• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import ability from '@ohos.ability.ability';
17import dlpPermission from '@ohos.dlpPermission'
18import hiSysEvent from '@ohos.hiSysEvent';
19import router from '@ohos.router';
20import picker from '@ohos.file.picker';
21import hiTraceMeter from '@ohos.hiTraceMeter';
22import fileio from '@ohos.fileio';
23import fileUri from '@ohos.file.fileuri';
24import fs from '@ohos.file.fs';
25import osAccount from '@ohos.account.osAccount';
26import { BusinessError } from '@ohos.base'
27import { EncryptingPanel } from '../common/encryptionComponents/encrypting';
28import { DlpAlertDialog } from '../common/components/dlp_alert_dialog';
29import {
30  PermissionType,
31  getAlertMessage,
32  getOsAccountInfo,
33  checkAccountLogin,
34  getUserId,
35  removeDuplicate,
36  directionStatus,
37  AuthAccount
38} from '../common/utils';
39import Constants from '../common/constant';
40import permissionTypeSelect from '../common/encryptionComponents/permission_type_select';
41import AddStaff from '../common/encryptionComponents/AddStaff';
42import GlobalContext from '../common/GlobalContext'
43import common from '@ohos.app.ability.common';
44
45
46const TAG = "[DLPManager_Encrypt]"
47
48let abilityResult: ability.AbilityResult = {
49  "resultCode": 0,
50  "want": {}
51};
52
53let defaultDlpProperty: dlpPermission.DLPProperty = {
54  ownerAccount: '',
55  ownerAccountType: (GlobalContext.load('domainAccount') as boolean) ? dlpPermission.AccountType.DOMAIN_ACCOUNT : dlpPermission.AccountType.CLOUD_ACCOUNT,
56  authUserList: [],
57  contactAccount: '',
58  offlineAccess: true,
59  ownerAccountID: '',
60  everyoneAccessList: []
61};
62
63let defaultDlpFile: dlpPermission.DLPFile = {
64  dlpProperty: defaultDlpProperty,
65  recoverDLPFile: async () => {},
66  closeDLPFile: async () => {},
67  addDLPLinkFile: async () => {},
68  stopFuseLink: async () => {},
69  resumeFuseLink: async () => {},
70  replaceDLPLinkFile: async () => {},
71  deleteDLPLinkFile: async () => {}
72};
73
74@Component
75struct DlpDialog {
76  srcFd: number = -1;
77  srcFileName: string = '';
78  isDlpFile: boolean = false;
79  linkFileName: string = '';
80  dlpAlertDialog?: CustomDialogController;
81  @State directionStatus: number = 0;
82  @State authPerm: number = 2;
83  @State dlpFile: dlpPermission.DLPFile = defaultDlpFile;
84  @State handlePopupReadOnly: boolean = false;
85  @State handlePopupEdit: boolean = false;
86  @State processing: boolean = false;
87  @State prepareData: boolean = false;
88  @State domainOrCloudAccount: number = (GlobalContext.load('domainAccount') as boolean) ? dlpPermission.AccountType.DOMAIN_ACCOUNT : dlpPermission.AccountType.CLOUD_ACCOUNT
89  @State permissionDict: PermissionType[] = [
90    {
91      value: $r('app.string.PERMISSION_TYPE_SELECT_TARGET'), data: 'target', index: 0
92    } as PermissionType,
93    {
94      value: $r('app.string.PERMISSION_TYPE_SELECT_ALL'), data: 'all', index: 1
95    } as PermissionType,
96    {
97      value: $r('app.string.PERMISSION_TYPE_SELECT_SELF'), data: 'self', index: 2
98    } as PermissionType
99  ];
100
101  @State staffDataArrayReadOnly: AuthAccount[] = [];
102  @State staffDataArrayEdit: AuthAccount[] = [];
103  @State selectedPermissionTypeReadOnly: PermissionType = { data: '', value: { id: 0, type: 0, params: [], bundleName: '', moduleName: '' }, index: -1 };
104  @State selectedPermissionTypeEdit: PermissionType = { data: '', value: { id: 0, type: 0, params: [], bundleName: '', moduleName: '' }, index: -1 };
105
106  @Builder popupBuilderReadOnly() {
107    Row() {
108      Text($r('app.string.header_title_readonly_tips'))
109        .fontFamily('HarmonyHeiTi')
110        .fontSize($r('sys.float.ohos_id_text_size_body2'))
111        .fontColor($r('sys.color.ohos_id_color_primary_dark'))
112    }
113    .width(Constants.HEADER_COLUMN_MESSAGE_TIPS)
114    .padding({
115      left: Constants.ROW_FONT_SIZE,
116      right: Constants.ROW_FONT_SIZE,
117      top: Constants.DA_MARGIN_TOP,
118      bottom: Constants.DA_MARGIN_TOP
119    })
120  }
121
122  @Builder popupBuilderEdit() {
123    Row() {
124      Text($r('app.string.header_title_edit_tips'))
125        .fontSize($r('sys.float.ohos_id_text_size_body2'))
126        .fontColor($r('sys.color.ohos_id_color_primary_dark'))
127    }
128    .width(Constants.HEADER_COLUMN_MESSAGE_TIPS)
129    .padding({
130      left: Constants.ROW_FONT_SIZE,
131      right: Constants.ROW_FONT_SIZE,
132      top: Constants.DA_MARGIN_TOP,
133      bottom: Constants.DA_MARGIN_TOP
134    })
135  }
136
137  showErrorDialog(title: Resource, message: Resource) {
138    this.dlpAlertDialog = new CustomDialogController({
139      builder: DlpAlertDialog({
140        title: title,
141        message: message,
142        action: () => {
143        }
144      }),
145      autoCancel: false,
146      customStyle: true,
147    })
148    this.dlpAlertDialog.open();
149  }
150
151  showErrorDialogAndExit(title: Resource, message: Resource) {
152    this.dlpAlertDialog = new CustomDialogController({
153      builder: DlpAlertDialog({
154        title: title,
155        message: message
156      }),
157      autoCancel: false,
158      customStyle: true
159    })
160    this.dlpAlertDialog.open();
161  }
162
163
164  async sendDlpFileCreateFault(code: number, reason?: string) {
165    let event: hiSysEvent.SysEventInfo = {
166      domain: 'DLP',
167      name: 'DLP_FILE_CREATE',
168      eventType: hiSysEvent.EventType.FAULT,
169      params: {
170        'CODE': code,
171        'REASON': reason
172      } as Record<string, number | string>
173    };
174
175    try {
176      let userId = await getUserId();
177      event.params['USER_ID'] = userId;
178      await hiSysEvent.write(event);
179    } catch (err) {
180      console.error(TAG, 'sendDlpFileOpenEvent failed, err: ', JSON.stringify(err));
181    }
182  }
183
184  async sendDlpFileCreateEvent(code: number) {
185    let event: hiSysEvent.SysEventInfo = {
186      domain: 'DLP',
187      name: 'DLP_FILE_CREATE_EVENT',
188      eventType: hiSysEvent.EventType.BEHAVIOR,
189      params: {
190        'CODE': code,
191      } as Record<string, number>
192    };
193    try {
194      let userId = await getUserId();
195      event.params['USER_ID'] = userId;
196      await hiSysEvent.write(event);
197    } catch (err) {
198      console.error(TAG, 'sendDlpFileOpenEvent, err: ', JSON.stringify(err));
199    }
200  }
201
202  async catchProcess() {
203    this.processing = false;
204    if (GlobalContext.load('requestIsFromSandBox') as boolean) {
205      try {
206        console.info(TAG, 'resumeFuseLink', this.srcFileName);
207        await this.dlpFile.resumeFuseLink();
208      } catch (err) {
209        console.error(TAG, 'resumeFuseLink failed', (err as BusinessError).code, (err as BusinessError).message);
210      }
211    }
212  }
213
214  async changeEncrypt() {
215    console.info(TAG, 'Change encryption for', this.srcFd);
216    this.processing = true;
217    if (GlobalContext.load('requestIsFromSandBox') as boolean) {
218      try {
219        console.info(TAG, 'stopFuseLink', this.srcFileName);
220        await this.dlpFile.stopFuseLink();
221      } catch (err) {
222        console.error(TAG, 'stopFuseLink failed', (err as BusinessError).code, (err as BusinessError).message);
223        this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_INSIDE_ERROR'));
224        this.processing = false;
225        return;
226      }
227    }
228    let filePath = (GlobalContext.load('context') as common.UIAbilityContext).filesDir + '/' + (new Date().getTime());
229    let tempFd: number = 0;
230    try {
231      tempFd = fileio.openSync(filePath, 0o102, 0o660);
232      console.info(TAG, 'open temp file, fd', tempFd)
233    } catch (err) {
234      console.error(TAG, 'open temp failed', JSON.stringify(err));
235      this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_INSIDE_ERROR'));
236      await this.catchProcess();
237      return;
238    }
239
240    try {
241      console.info(TAG, 'recoverDLPFile', this.srcFileName, this.srcFd);
242      await this.dlpFile.recoverDLPFile(tempFd);
243    } catch (err) {
244      console.error(TAG, 'recoverDLPFile', this.srcFileName, 'failed', (err as BusinessError).code, (err as BusinessError).message);
245      fileio.closeSync(tempFd);
246      fileio.unlinkSync(filePath);
247      let errorInfo = getAlertMessage(err, $r('app.string.TITLE_SERVICE_ERROR'), $r('app.string.MESSAGE_RECOVER_DLP_ERROR'));
248      this.showErrorDialog(errorInfo.title, errorInfo.msg);
249      await this.catchProcess();
250      return;
251    }
252    let accountInfo: osAccount.OsAccountInfo;
253    try {
254      accountInfo = await getOsAccountInfo();
255    } catch (err) {
256      console.error(TAG, 'getOsAccountInfo failed', (err as BusinessError).code, (err as BusinessError).message);
257      fileio.closeSync(tempFd);
258      fileio.unlinkSync(filePath);
259      this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_GET_ACCOUNT_ERROR'));
260      await this.catchProcess();
261      return;
262    }
263    if (!checkAccountLogin(accountInfo)) {
264      fileio.closeSync(tempFd);
265      fileio.unlinkSync(filePath);
266      this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_NO_ACCOUNT_ERROR'));
267      await this.catchProcess();
268      return;
269    }
270    let property: dlpPermission.DLPProperty = this.dlpFile.dlpProperty;
271    try {
272      console.info(TAG, 'closeDLPFile', this.srcFileName, this.srcFd);
273      await this.dlpFile.closeDLPFile();
274    } catch (err) {
275      console.error(TAG, 'closeDLPFile', this.srcFileName, 'failed', (err as BusinessError).code, (err as BusinessError).message);
276    }
277
278    this.staffDataArrayReadOnly = removeDuplicate(this.staffDataArrayReadOnly, 'authAccount');
279    this.staffDataArrayEdit = removeDuplicate(this.staffDataArrayEdit, 'authAccount');
280    this.staffDataArrayReadOnly = this.staffDataArrayReadOnly.filter((item) =>!this.staffDataArrayEdit.some((ele) => ele.authAccount === item.authAccount))
281    if (GlobalContext.load('domainAccount') as boolean) {
282      property.ownerAccount = accountInfo.domainInfo.accountName;
283      property.ownerAccountID = accountInfo.domainInfo.accountId ?? '';
284    } else {
285      property.ownerAccount = accountInfo.distributedInfo.name;
286      property.ownerAccountID = accountInfo.distributedInfo.id;
287    }
288    property.authUserList = []
289    property.everyoneAccessList = [];
290    if (this.selectedPermissionTypeEdit.data === 'all') {
291      property.everyoneAccessList = [ dlpPermission.DLPFileAccess.CONTENT_EDIT ];
292      this.staffDataArrayReadOnly = [];
293      this.staffDataArrayEdit = [];
294    } else {
295      let isReadyOnlyAll = this.selectedPermissionTypeReadOnly.data === 'all';
296      if (isReadyOnlyAll) {
297        property.everyoneAccessList = [ dlpPermission.DLPFileAccess.READ_ONLY ];
298      }
299      if (this.selectedPermissionTypeReadOnly.data === 'all') {
300        this.staffDataArrayReadOnly = []
301      }
302      if (['all', 'self'].includes(this.selectedPermissionTypeEdit.data ?? '')) {
303        this.staffDataArrayEdit = [];
304      }
305      // foreach
306      this.staffDataArrayReadOnly && this.staffDataArrayReadOnly.forEach(item => {
307        property.authUserList?.push({
308          authAccount: item.authAccount,
309          dlpFileAccess: dlpPermission.DLPFileAccess.READ_ONLY,
310          permExpiryTime: Date.UTC(9999, 1, 1),
311          authAccountType: this.domainOrCloudAccount,
312        })
313      })
314      this.staffDataArrayEdit && this.staffDataArrayEdit.forEach(item => {
315        property.authUserList?.push({
316          authAccount: item.authAccount,
317          dlpFileAccess: dlpPermission.DLPFileAccess.CONTENT_EDIT,
318          permExpiryTime: Date.UTC(9999, 1, 1),
319          authAccountType: this.domainOrCloudAccount,
320        })
321      })
322    }
323
324    let newDlpFile: dlpPermission.DLPFile;
325    try {
326      console.info(TAG, 'generateDLPFile', this.srcFd);
327      newDlpFile = await dlpPermission.generateDLPFile(tempFd, this.srcFd, property);
328    } catch (err) {
329      console.error(TAG, 'generateDLPFile', this.srcFd, 'failed', (err as BusinessError).code, (err as BusinessError).message);
330      fileio.closeSync(tempFd);
331      fileio.unlinkSync(filePath);
332      let errorInfo = getAlertMessage(err, $r('app.string.TITLE_SERVICE_ERROR'), $r('app.string.MESSAGE_GENERATE_DLP_ERROR'));
333      this.showErrorDialog(errorInfo.title, errorInfo.msg);
334      await this.catchProcess();
335      return;
336    }
337    if (GlobalContext.load('requestIsFromSandBox') as boolean) {
338      let sandbox2linkFile: Map<string, (number | string | dlpPermission.DLPFile)[][]> = GlobalContext.load('sandbox2linkFile') as Map<string, (number | string | dlpPermission.DLPFile)[][]>;
339      for (let key of Array.from<(number | string | dlpPermission.DLPFile)[][]>(sandbox2linkFile.values())) {
340        for (let j of key) {
341          if (j[1] === this.linkFileName) {
342            j[0] = newDlpFile;
343          }
344        }
345      }
346      try {
347        await newDlpFile.replaceDLPLinkFile(this.linkFileName);
348      } catch (err) {
349        console.error(TAG, 'replaceDLPLinkFile failed', (err as BusinessError).code, (err as BusinessError).message);
350      }
351    }
352    fileio.closeSync(tempFd);
353    fileio.unlinkSync(filePath);
354    this.dlpFile = newDlpFile;
355    await this.catchProcess();
356    this.processing = false;
357    // update global dlp resource
358    GlobalContext.store('dlpFileName', this.srcFileName);
359    GlobalContext.store('dlpFile', this.dlpFile);
360    GlobalContext.store('dlpFd', this.srcFd);
361    router.replaceUrl({
362      url: 'pages/encryptionSuccess',
363      params: {
364        staffDataArrayReadOnly: this.staffDataArrayReadOnly,
365        staffDataArrayEdit: this.staffDataArrayEdit,
366        selectedPermissionTypeReadOnly: this.selectedPermissionTypeReadOnly,
367        selectedPermissionTypeEdit: this.selectedPermissionTypeEdit,
368      }
369    })
370    return;
371  }
372
373  async beginEncrypt() {
374    this.processing = true;
375    console.info(TAG, 'begin encryption for', this.srcFileName, this.srcFd);
376    let uri: string = '';
377    let displayName: string = this.srcFileName;
378    try {
379      let DocumentSaveOptions = new picker.DocumentSaveOptions();
380      displayName = displayName + '.dlp';
381      DocumentSaveOptions.newFileNames = [displayName];
382      let documentPicker = new picker.DocumentViewPicker();
383      documentPicker.save(DocumentSaveOptions).then(async (saveRes) => {
384        if (saveRes === undefined || saveRes.length === 0) {
385          console.error(TAG, 'fail to get uri');
386          this.processing = false;
387          return;
388        }
389        console.info(TAG, 'get uri', saveRes)
390        uri = saveRes[0];
391        let dstFd: number = -1;
392        let uriInfo: fileUri.FileUri = new fileUri.FileUri('');
393        let file: fs.File;
394        try {
395          uriInfo = new fileUri.FileUri(uri);
396        } catch (err) {
397          console.log(TAG, 'fileUri fail', (err as BusinessError).code, (err as BusinessError).message);
398        }
399        try {
400          file = await fs.open(uri, fs.OpenMode.READ_WRITE);
401          dstFd = file.fd;
402        } catch (error) {
403          console.error(TAG, 'open', uri, 'failed', (error as BusinessError).code, (error as BusinessError).message);
404          try {
405            await fs.unlink(uriInfo.path);
406          } catch (err) {
407            console.log(TAG, 'unlink fail', (err as BusinessError).code, (err as BusinessError).message);
408          }
409          this.showErrorDialog($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_INSIDE_ERROR'));
410          this.processing = false;
411          return;
412        };
413        this.staffDataArrayReadOnly = removeDuplicate(this.staffDataArrayReadOnly, 'authAccount');
414        this.staffDataArrayEdit = removeDuplicate(this.staffDataArrayEdit, 'authAccount');
415        this.staffDataArrayReadOnly = this.staffDataArrayReadOnly.filter((item) =>!this.staffDataArrayEdit.some((ele) => ele.authAccount === item.authAccount))
416        if (this.selectedPermissionTypeEdit.data === 'all') {
417          this.dlpFile.dlpProperty.everyoneAccessList = [ dlpPermission.DLPFileAccess.CONTENT_EDIT ];
418          this.staffDataArrayReadOnly = []
419        } else {
420          let isReadyOnlyAll = this.selectedPermissionTypeReadOnly.data === 'all'
421          if (isReadyOnlyAll) {
422            this.dlpFile.dlpProperty.everyoneAccessList = [ dlpPermission.DLPFileAccess.READ_ONLY ];
423          }
424          // foreach
425          if (this.selectedPermissionTypeReadOnly.data === 'all') {
426            this.staffDataArrayReadOnly = []
427          }
428          if (['all', 'self'].includes(this.selectedPermissionTypeEdit.data)) {
429            this.staffDataArrayEdit = [];
430          }
431          this.dlpFile.dlpProperty.authUserList = []
432          this.staffDataArrayReadOnly && this.staffDataArrayReadOnly.forEach(item => {
433            this.dlpFile.dlpProperty.authUserList?.push({
434              authAccount: item.authAccount,
435              dlpFileAccess: dlpPermission.DLPFileAccess.READ_ONLY,
436              permExpiryTime: Date.UTC(9999, 1, 1),
437              authAccountType: this.domainOrCloudAccount,
438            })
439          })
440          this.staffDataArrayEdit && this.staffDataArrayEdit.forEach(item => {
441            this.dlpFile.dlpProperty.authUserList?.push({
442              authAccount: item.authAccount,
443              dlpFileAccess: dlpPermission.DLPFileAccess.CONTENT_EDIT,
444              permExpiryTime: Date.UTC(9999, 1, 1),
445              authAccountType: this.domainOrCloudAccount,
446            })
447          })
448        }
449        hiTraceMeter.startTrace("DlpGenerateDlpFileJs", this.srcFd);
450        try {
451          console.info(TAG, 'generateDLPFile', dstFd);
452          this.dlpFile = await dlpPermission.generateDLPFile(this.srcFd, dstFd, this.dlpFile.dlpProperty);
453        } catch (err) {
454          await this.sendDlpFileCreateFault(102, (err as BusinessError<string>).data); // 102: DLP_FILE_CREATE_ERORR
455          hiTraceMeter.finishTrace("DlpGenerateDlpFileJs", this.srcFd);
456          console.info(TAG, 'generateDLPFile failed', err.code, err.message);
457          try {
458            await fs.close(file);
459          } catch (err) {
460            console.log(TAG, 'close fail', (err as BusinessError).code, (err as BusinessError).message);
461          }
462          try {
463            await fs.unlink(uriInfo.path);
464          } catch (err) {
465            console.log(TAG, 'unlink fail', (err as BusinessError).code, (err as BusinessError).message);
466          }
467          let errorInfo = getAlertMessage(err, $r('app.string.TITLE_SERVICE_ERROR'), $r('app.string.MESSAGE_GENERATE_DLP_ERROR'));
468          this.showErrorDialog(errorInfo.title, errorInfo.msg);
469          this.processing = false;
470          return;
471        }
472        await this.sendDlpFileCreateEvent(201); // 201: DLP_FILE_CREATE_SUCCESS
473        hiTraceMeter.finishTrace("DlpGenerateDlpFileJs", this.srcFd);
474        this.processing = false;
475
476        // update global dlp resource
477        GlobalContext.store('dlpFileName', uriInfo.name);
478
479        GlobalContext.store('dlpFile', this.dlpFile);
480        GlobalContext.store('dlpFd', dstFd);
481        router.replaceUrl({
482          url: 'pages/encryptionSuccess',
483          params: {
484            staffDataArrayReadOnly: this.staffDataArrayReadOnly,
485            staffDataArrayEdit: this.staffDataArrayEdit,
486            selectedPermissionTypeReadOnly: this.selectedPermissionTypeReadOnly,
487            selectedPermissionTypeEdit: this.selectedPermissionTypeEdit,
488          }
489        })
490      }).catch((err: BusinessError) => {
491        console.error('DocumentViewPicker save failed', err.code, err.message);
492        let errorInfo = getAlertMessage(err, $r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_INSIDE_ERROR'));
493        this.showErrorDialog(errorInfo.title, errorInfo.msg);
494        this.processing = false;
495        return;
496      });
497    } catch (err) {
498      console.error('DocumentViewPicker failed', (err as BusinessError).code, (err as BusinessError).message);
499      this.processing = false;
500      return;
501    }
502  }
503
504  async prepareDlpProperty() {
505    if (GlobalContext.load('domainAccount') as boolean) {
506      let accountInfo: osAccount.OsAccountInfo = GlobalContext.load('accountInfo') as osAccount.OsAccountInfo;
507      this.dlpFile.dlpProperty.ownerAccount = accountInfo.domainInfo.accountName;
508      this.dlpFile.dlpProperty.contactAccount = accountInfo.domainInfo.accountName;
509      this.dlpFile.dlpProperty.ownerAccountID = accountInfo.domainInfo.accountId ?? '';
510    } else {
511      let accountInfo: osAccount.OsAccountInfo = GlobalContext.load('accountInfo') as osAccount.OsAccountInfo;
512      this.dlpFile.dlpProperty.ownerAccount = accountInfo.distributedInfo.name;
513      this.dlpFile.dlpProperty.contactAccount = accountInfo.distributedInfo.name;
514      this.dlpFile.dlpProperty.ownerAccountID = accountInfo.distributedInfo.id;
515    }
516    let ownerAccount: dlpPermission.AuthUser = {
517      authAccount: this.dlpFile.dlpProperty.ownerAccount,
518      dlpFileAccess: dlpPermission.DLPFileAccess.FULL_CONTROL,
519      permExpiryTime: Date.UTC(9999, 1, 1),
520      authAccountType: this.domainOrCloudAccount,
521    }
522    this.dlpFile.dlpProperty.authUserList?.push(ownerAccount)
523    return
524  }
525
526  async showData(defaultDlpProperty: dlpPermission.DLPProperty) {
527    this.permissionDict.forEach(async (item, index) => {
528      this.permissionDict[index].value = $r(await (GlobalContext.load('context') as common.UIAbilityContext).resourceManager.getString(item.value.id))
529    })
530    let readOnlyData: dlpPermission.AuthUser[] = defaultDlpProperty.authUserList?.filter((item: dlpPermission.AuthUser) => {
531      return item.dlpFileAccess === 1;
532      }) ?? []
533    let editData: dlpPermission.AuthUser[] = defaultDlpProperty.authUserList?.filter((item: dlpPermission.AuthUser) => {
534      return item.dlpFileAccess === 2;
535    }) ?? []
536    const filterEditFilter = () => {
537      if (editData.length === 0) {
538        this.selectedPermissionTypeEdit = this.permissionDict[2];
539      } else {
540        this.staffDataArrayEdit = editData;
541      }
542    }
543    if ((defaultDlpProperty.everyoneAccessList !== undefined) && (defaultDlpProperty.everyoneAccessList.length > 0)) {
544      let perm = Math.max(...defaultDlpProperty.everyoneAccessList);
545      if (perm === dlpPermission.DLPFileAccess.CONTENT_EDIT) {
546        this.selectedPermissionTypeEdit = this.permissionDict[1];
547        this.staffDataArrayReadOnly = readOnlyData;
548      } else if (perm === dlpPermission.DLPFileAccess.READ_ONLY) {
549        this.selectedPermissionTypeReadOnly = this.permissionDict[1];
550        this.staffDataArrayReadOnly = [];
551        filterEditFilter()
552      }
553    } else {
554      this.staffDataArrayReadOnly = readOnlyData;
555      filterEditFilter()
556    }
557  }
558
559  async checkAccount() {
560    try {
561      GlobalContext.store('accountInfo', await getOsAccountInfo());
562    } catch (err) {
563      console.error(TAG, 'getOsAccountInfo failed:', JSON.stringify(err));
564      this.showErrorDialogAndExit($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_GET_ACCOUNT_ERROR'))
565      return;
566    }
567    if (!checkAccountLogin(GlobalContext.load('accountInfo') as osAccount.OsAccountInfo)) {
568      this.showErrorDialogAndExit($r('app.string.TITLE_APP_ERROR'), $r('app.string.MESSAGE_APP_NO_ACCOUNT_ERROR'));
569      return;
570    }
571  }
572
573  async aboutToAppear() {
574    this.prepareData = true;
575    await this.checkAccount();
576    if (GlobalContext.load('requestIsFromSandBox') as boolean) {
577      console.info(TAG, 'encryption request from sandbox');
578      this.linkFileName = GlobalContext.load('linkFileName') as string;
579      this.srcFileName = GlobalContext.load('dlpFileName') as string;
580      this.dlpFile = GlobalContext.load('dlpFile') as dlpPermission.DLPFile;
581      this.srcFd = GlobalContext.load('dlpFd') as number;
582      setTimeout(() => {
583        this.showData(this.dlpFile.dlpProperty);
584      }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
585      this.isDlpFile = true;
586      setTimeout(() => {
587        this.prepareData = false;
588      }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
589      return
590    } else {
591      let routerParams = router.getParams();
592      if (routerParams !== undefined) { // is a dlp file
593        console.info(TAG, 'encryption request from router');
594        this.srcFileName = GlobalContext.load('dlpFileName') as string;
595        this.srcFd = GlobalContext.load('dlpFd') as number;
596      } else { // not a dlp file
597        console.info(TAG, 'encryption request from ability');
598        this.srcFileName = GlobalContext.load('originFileName') as string;
599        this.srcFd = GlobalContext.load('originFd') as number;
600      }
601    }
602
603    let isDlpSuffix: boolean = this.srcFileName.endsWith(".dlp");
604    if (!isDlpSuffix) {
605      await this.prepareDlpProperty();
606      this.isDlpFile = false;
607    } else {
608      this.dlpFile = GlobalContext.load('dlpFile') as dlpPermission.DLPFile;
609      setTimeout(() => {
610        this.showData(this.dlpFile.dlpProperty);
611      }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
612      this.isDlpFile = true;
613    }
614    setTimeout(() => {
615      this.prepareData = false;
616    }, Constants.ENCRYPTION_SET_TIMEOUT_TIME)
617
618    this.directionStatus = (GlobalContext.load('context') as common.UIAbilityContext).config.direction ?? -1;
619    directionStatus((counter) => {
620      this.directionStatus = counter;
621    })
622  }
623
624  build() {
625    Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
626      EncryptingPanel({ processing: $processing })
627      if (!this.processing) {
628        Column() {
629          Row() {
630            Text($r('app.string.header_title'))
631              .fontWeight(FontWeight.Medium)
632              .fontFamily($r('app.string.typeface'))
633              .fontColor($r('sys.color.ohos_id_color_text_primary'))
634              .fontSize(Constants.HEADER_TEXT_FRONT_SIZE)
635              .lineHeight(Constants.HEADER_TEXT_LINE_HEIGHT)
636              .width(Constants.HEADER_TEXT_WIDTH)
637              .align(Alignment.Start)
638          }
639          .width(Constants.HEADER_COLUMN_WIDTH)
640          .height(Constants.HEADER_COLUMN_HEIGHT)
641          .padding({
642            left: Constants.HEADER_COLUMN_PADDING_LEFT,
643            right: Constants.HEADER_COLUMN_PADDING_RIGHT
644          })
645
646          Scroll() {
647            Column() {
648              Row() {
649                Text($r('app.string.header_title_list'))
650                  .fontWeight(FontWeight.Regular)
651                  .fontColor($r('sys.color.ohos_id_color_text_secondary'))
652                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
653                  .width(Constants.HEADER_TEXT_WIDTH)
654                  .align(Alignment.Start)
655              }
656              .width(Constants.HEADER_COLUMN_WIDTH)
657
658              Row() {
659                Text($r('app.string.header_title_readonly'))
660                  .fontWeight(FontWeight.Medium)
661                  .fontColor($r('sys.color.ohos_id_color_text_primary'))
662                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
663                Image($r('app.media.details'))
664                  .width(Constants.FOOTER_ROW_PAD_RIGHT)
665                  .height(Constants.FOOTER_ROW_PAD_RIGHT)
666                  .margin({ left: Constants.AP_TEXT_PAD_RIGHT })
667                  .fillColor($r('sys.color.ohos_id_color_text_secondary'))
668                  .onClick(() => {
669                    this.handlePopupReadOnly = !this.handlePopupReadOnly
670                  })
671                  .draggable(false)
672                  .bindPopup(this.handlePopupReadOnly, {
673                    builder: this.popupBuilderReadOnly,
674                    placement: Placement.Bottom,
675                    popupColor: ($r('sys.color.ohos_id_color_tooltip_background_dark')),
676                    enableArrow: true,
677                    showInSubWindow: false,
678                    onStateChange: (e) => {
679                      if (!e.isVisible) {
680                        this.handlePopupReadOnly = false
681                      }
682                    }
683                  })
684                Blank()
685                permissionTypeSelect({
686                  selectedItem: $selectedPermissionTypeReadOnly,
687                  staffArray: $staffDataArrayReadOnly,
688                  isDisable: this.selectedPermissionTypeEdit?.data === 'all',
689                  isReadType: true
690                })
691              }
692              .width(Constants.FOOTER_ROW_WIDTH)
693              .height(Constants.HEADER_COLUMN_HEIGHT_READONLY)
694              .margin({ top: Constants.FOOTER_ROW_MARGIN })
695
696              Row() {
697                if (!['all', 'self'].includes(this.selectedPermissionTypeReadOnly?.data ?? '')) {
698                  AddStaff({
699                    staffArray: $staffDataArrayReadOnly,
700                    isDisable: this.selectedPermissionTypeEdit?.data === 'all',
701                  })
702                }
703              }
704              .margin({ bottom: Constants.ENCRYPTION_STAFF_ITEM_MARGIN_BOTTOM })
705
706              Row() {
707                Text($r('app.string.header_title_edit'))
708                  .fontWeight(FontWeight.Medium)
709                  .fontColor($r('sys.color.ohos_id_color_text_primary'))
710                  .fontSize($r('sys.float.ohos_id_text_size_body1'))
711                Image($r('app.media.details'))
712                  .width(Constants.FOOTER_ROW_PAD_RIGHT)
713                  .height(Constants.FOOTER_ROW_PAD_RIGHT)
714                  .margin({ left: Constants.AP_TEXT_PAD_RIGHT })
715                  .fillColor($r('sys.color.ohos_id_color_text_secondary'))
716                  .onClick(() => {
717                    this.handlePopupEdit = !this.handlePopupEdit
718                  })
719                  .draggable(false)
720                  .bindPopup(this.handlePopupEdit, {
721                    builder: this.popupBuilderEdit,
722                    placement: Placement.Bottom,
723                    popupColor: ($r('sys.color.ohos_id_color_tooltip_background_dark')),
724                    enableArrow: true,
725                    showInSubWindow: false,
726                    onStateChange: (e) => {
727                      if (!e.isVisible) {
728                        this.handlePopupEdit = false
729                      }
730                    }
731                  })
732                Blank()
733                permissionTypeSelect({
734                  selectedItem: $selectedPermissionTypeEdit,
735                  staffArray: $staffDataArrayEdit,
736                  isDisable: false,
737                  isReadType: false
738                })
739              }
740              .width(Constants.FOOTER_ROW_WIDTH)
741              .height(Constants.HEADER_COLUMN_HEIGHT_READONLY)
742
743              Row() {
744                if (!['all', 'self'].includes(this.selectedPermissionTypeEdit?.data ?? '')) {
745                  AddStaff({
746                    staffArray: $staffDataArrayEdit,
747                    isDisable: false
748                  })
749                }
750              }
751              .margin({ bottom: Constants.ENCRYPTION_STAFF_ITEM_MARGIN_BOTTOM })
752            }
753          }.constraintSize({
754            maxHeight: this.directionStatus === 0 ? Constants.CHANGE_MAX_HEIGHT : Constants.ENCRYPTION_SUCCESS_MAX_HEIGHT
755          })
756          .padding({
757            left: Constants.HEADER_COLUMN_PADDING_LEFT,
758            right: Constants.HEADER_COLUMN_PADDING_RIGHT
759          })
760
761          Flex({ direction: FlexDirection.Row }) {
762            Button($r('app.string.ban'), { type: ButtonType.Capsule, stateEffect: true })
763              .backgroundColor($r('app.color.base_button_color'))
764              .width(Constants.HEADER_TEXT_WIDTH)
765              .focusable(false)
766              .fontColor($r('app.color.encryption_cancel'))
767              .height(Constants.FOOTER_HEIGHT)
768              .onClick(async (event) => {
769                if (this.isDlpFile && !(GlobalContext.load('requestIsFromSandBox') as boolean)) {
770                  try {
771                    console.info(TAG, 'closeDLPFile', this.srcFileName, this.srcFd);
772                    await this.dlpFile.closeDLPFile();
773                  } catch (err) {
774                    console.error(TAG, 'closeDLPFile', this.srcFileName, 'failed', (err as BusinessError).code, (err as BusinessError).message);
775                  }
776                  try {
777                    console.info(TAG, 'refresh dlp file', GlobalContext.load('dlpFileName') as string, GlobalContext.load('dlpFd') as number);
778                    await fs.close(GlobalContext.load('dlpFd') as number); // refresh file info
779                  } catch (err) {
780                    console.error(TAG, 'refresh dlp file failed', (err as BusinessError).code, (err as BusinessError).message);
781                  }
782                }
783                if (GlobalContext.load('fileOpenHistoryFromMain')) {
784                  (GlobalContext.load('fileOpenHistoryFromMain') as Map<string, Object>).delete(GlobalContext.load('uri') as string)
785                }
786                abilityResult.resultCode = 0;
787                (GlobalContext.load('context') as common.UIAbilityContext).terminateSelfWithResult(abilityResult);
788              })
789              .margin({ right: Constants.ENCRYPTION_PROTECTION_BUTTON_MARGIN })
790            Button($r('app.string.sure'), {
791              type: ButtonType.Capsule, stateEffect: true
792            })
793              .backgroundColor($r('app.color.base_button_color'))
794              .width(Constants.HEADER_TEXT_WIDTH)
795              .focusable(false)
796              .fontColor($r('app.color.encryption_cancel'))
797              .enabled((this.staffDataArrayReadOnly.length > 0 || this.staffDataArrayEdit.length > 0 || ['all', 'self'].includes(this.selectedPermissionTypeReadOnly.data ?? '') || ['all', 'self'].includes(this.selectedPermissionTypeEdit.data ?? '')))
798              .opacity((this.staffDataArrayReadOnly.length > 0 || this.staffDataArrayEdit.length > 0 || ['all', 'self'].includes(this.selectedPermissionTypeReadOnly.data ?? '') || ['all', 'self'].includes(this.selectedPermissionTypeEdit.data ?? '')) ?
799              Constants.FOOTER_OPACITY_ONE : Constants.FOOTER_OPACITY_SEPC)
800              .height(Constants.FOOTER_BUTTON_HEIGHT)
801              .onClick(async (event) => {
802                if (this.isDlpFile) {
803                  await this.changeEncrypt();
804                } else {
805                  await this.beginEncrypt();
806                }
807              })
808              .margin({ left: Constants.ENCRYPTION_PROTECTION_BUTTON_MARGIN })
809          }
810          .margin({
811            left: Constants.ENCRYPTION_BUTTON_TO_BUTTON_WIDTH,
812            right: Constants.ENCRYPTION_BUTTON_TO_BUTTON_WIDTH,
813            bottom: Constants.ENCRYPTION_BUTTON_MARGIN_BOTTOM,
814            top: Constants.ENCRYPTION_BUTTON_TO_BUTTON_WIDTH
815          })
816        }
817        .visibility(this.processing ? Visibility.Hidden : Visibility.Visible)
818        .width(Constants.FOOTER_ROW_WIDTH)
819        .backgroundColor($r('app.color.da_button_color'))
820        .borderRadius(Constants.INDEX_BORDER_RADIUS)
821      }
822    }
823  }
824}
825
826@Entry
827@Component
828struct encryptionProtection {
829  aboutToAppear() {
830  }
831
832  build() {
833    GridRow({
834      columns: {
835        xs: Constants.XS_COLUMNS,
836        sm: Constants.SM_COLUMNS,
837        md: Constants.MD_COLUMNS,
838        lg: Constants.LG_COLUMNS
839      },
840      gutter: Constants.DIALOG_GUTTER
841    }) {
842      GridCol({
843        span: {
844          xs: Constants.XS_SPAN,
845          sm: Constants.SM_SPAN,
846          md: Constants.DIALOG_MD_SPAN,
847          lg: Constants.DIALOG_LG_SPAN
848        },
849        offset: {
850          xs: Constants.XS_OFFSET,
851          sm: Constants.SM_OFFSET,
852          md: Constants.DIALOG_MD_OFFSET,
853          lg: Constants.DIALOG_LG_OFFSET
854        }
855      }) {
856        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center,
857          direction: FlexDirection.Column }) {
858          DlpDialog()
859        }
860      }
861    }
862  }
863}
864