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 */ 15import ability from '@ohos.ability.ability'; 16import account_osAccount from '@ohos.account.osAccount'; 17import emitter from '@ohos.events.emitter'; 18import dlpPermission from '@ohos.dlpPermission'; 19import bundleManager from '@ohos.bundle.bundleManager' 20import fs from '@ohos.file.fs'; 21import fileuri from "@ohos.file.fileuri"; 22import { BusinessError, Callback } from '@ohos.base' 23import deviceInfo from '@ohos.deviceInfo'; 24import Constants from '../common/constant'; 25import Want from '@ohos.app.ability.Want'; 26import GlobalContext from './GlobalContext' 27import common from '@ohos.app.ability.common'; 28 29let TAG = "[DLPManager_Utils]"; 30 31interface AuthAccount { 32 authAccount: string; 33} 34 35interface PermissionType { 36 value: Resource; 37 data: string; 38 index: number; 39} 40 41function getFileUriByPath(filePath: string): string { 42 try { 43 let uri = fileuri.getUriFromPath(filePath); 44 return uri; 45 } catch (err) { 46 console.info(TAG, 'getUriFromPath error:', JSON.stringify(err)); 47 return ""; 48 } 49} 50 51function getFileFd(uri: string): number { 52 try { 53 let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); 54 console.info(TAG, 'open', uri, 'as', file.fd); 55 return file.fd; 56 } catch (err) { 57 console.info(TAG, 'openSync error:', JSON.stringify(err)); 58 return -1; 59 } 60} 61 62async function getOsAccountInfo(): Promise<account_osAccount.OsAccountInfo> { 63 let accountMgr = account_osAccount.getAccountManager(); 64 return await accountMgr.getCurrentOsAccount(); 65} 66 67function checkAccountLogin(accountInfo: account_osAccount.OsAccountInfo): boolean { 68 if (GlobalContext.load('domainAccount') as boolean) { 69 if (accountInfo.domainInfo.accountName === '' && 70 accountInfo.domainInfo.accountId === '') { 71 return false; 72 } 73 } else { 74 if (accountInfo.distributedInfo.name === 'ohosAnonymousName' && 75 accountInfo.distributedInfo.id === 'ohosAnonymousUid') { 76 return false; 77 } 78 } 79 return true; 80} 81 82async function getUserId(): Promise<number> { 83 let accountMgr = account_osAccount.getAccountManager(); 84 return await accountMgr.getOsAccountLocalIdFromProcess(); 85} 86 87function getAuthPerm(accountName: string, dlpProperty: dlpPermission.DLPProperty): dlpPermission.DLPFileAccess { 88 let perm: dlpPermission.DLPFileAccess = dlpPermission.DLPFileAccess.NO_PERMISSION; 89 if (accountName === dlpProperty.ownerAccount) { 90 return dlpPermission.DLPFileAccess.FULL_CONTROL; 91 } 92 if ((dlpProperty.everyoneAccessList !== undefined) && (dlpProperty.everyoneAccessList.length > 0)) { 93 perm = Math.max(...dlpProperty.everyoneAccessList); 94 } 95 let authUserList = dlpProperty.authUserList ?? []; 96 for (let i = 0; i < authUserList.length; ++i) { 97 let authUser = authUserList[i]; 98 if (authUser.authAccount === accountName) { 99 return authUser.dlpFileAccess; 100 } 101 } 102 return perm; 103} 104 105function terminateSelfWithResult(resultCode: number, result: string): void { 106 let abilityResult: ability.AbilityResult = { 107 resultCode: resultCode, 108 want: { 109 parameters: { 110 result: result 111 } 112 } 113 }; 114 (GlobalContext.load('context') as common.UIAbilityContext).terminateSelfWithResult(abilityResult); 115} 116 117function getAlertMessage(err: BusinessError, defaultTitle?: Resource, defaultMessage?: Resource) { 118 switch (err.code) { 119 case Constants.ERR_JS_USER_NO_PERMISSION: 120 return { 121 'title': $r('app.string.TITLE_APP_VISIT_FILE_ERROR'), 122 'msg': $r('app.string.MESSAGE_APP_NOT_HAVE_PERM_VISIT', err.message.split(", contact:")?.[1]) 123 } as Record<string, Resource>; 124 case Constants.ERR_JS_APP_INSIDE_ERROR: 125 return { 'title': $r('app.string.TITLE_APP_ERROR'), 'msg': $r('app.string.MESSAGE_APP_INSIDE_ERROR') } as Record<string, Resource>; 126 case Constants.ERR_JS_GET_ACCOUNT_ERROR: 127 return { 'title': $r('app.string.TITLE_APP_ERROR'), 'msg': $r('app.string.MESSAGE_APP_GET_ACCOUNT_ERROR') } as Record<string, Resource>; 128 case Constants.ERR_JS_APP_NO_ACCOUNT_ERROR: 129 case Constants.ERR_JS_ACCOUNT_NOT_LOGIN: 130 return { 'title': $r('app.string.TITLE_APP_ERROR'), 'msg': $r('app.string.MESSAGE_APP_NO_ACCOUNT_ERROR') } as Record<string, Resource>; 131 case Constants.ERR_JS_APP_PARAM_ERROR: 132 return { 'title': $r('app.string.TITLE_APP_ERROR'), 'msg': $r('app.string.MESSAGE_APP_PARAM_ERROR') } as Record<string, Resource>; 133 case Constants.ERR_JS_APP_GET_FILE_ASSET_ERROR: 134 return { 'title': $r('app.string.TITLE_APP_ERROR'), 'msg': $r('app.string.MESSAGE_APP_GET_FILE_ASSET_ERROR') } as Record<string, Resource>; 135 case Constants.ERR_JS_APP_OPEN_REJECTED: 136 return { 'msg': $r('app.string.MESSAGE_DLP_OPEN_REJECT') } as Record<string, Resource>; 137 case Constants.ERR_JS_APP_ENCRYPTION_REJECTED: 138 return { 'msg': $r('app.string.MESSAGE_DLP_ENCRYPTION_REJECTED') } as Record<string, Resource>; 139 case Constants.ERR_JS_SYSTEM_NEED_TO_BE_UPGRADED: 140 return { 'msg': $r('app.string.MESSAGE_DLP_SYSTEM_NEED_TO_BE_UPGRADED')} as Record<string, Resource>; 141 case Constants.ERR_JS_CREDENTIAL_SERVICE_ERROR: 142 return { 'title': $r('app.string.TITLE_SERVICE_ERROR'), 'msg': $r('app.string.MESSAGE_SERVICE_INSIDE_ERROR') } as Record<string, Resource>; 143 case Constants.ERR_JS_CREDENTIAL_SERVER_ERROR: 144 return { 'title': $r('app.string.TITLE_SERVICE_ERROR'), 'msg': $r('app.string.MESSAGE_DLP_CREDENTIAL_SERVER_ERROR') } as Record<string, Resource>; 145 case Constants.ERR_JS_NOT_DLP_FILE: 146 return { 'title': $r('app.string.TITLE_APP_DLP_ERROR'), 'msg': $r('app.string.MESSAGE_APP_FILE_PARAM_ERROR') } as Record<string, Resource>; 147 case Constants.ERR_JS_CREDENTIAL_TIMEOUT: 148 return { 'title': $r('app.string.TITLE_SERVICE_ERROR'), 'msg': $r('app.string.MESSAGE_DLP_CREDENTIAL_TIMEOUT_ERROR') } as Record<string, Resource>; 149 case Constants.ERR_JS_DLP_FILE_READ_ONLY: 150 return { 'title': $r('app.string.TITLE_OPERATE_DENY'), 'msg': $r('app.string.MESSAGE_DLP_READ_ONLY') } as Record<string, Resource>; 151 case Constants.ERR_JS_FILENAME_TOO_LONG: 152 return { 'title': $r('app.string.TITLE_CANT_ENCRYPT'), 'msg': $r('app.string.MESSAGE_DLP_FILENAME_TOO_LONG')} as Record<string, Resource>; 153 default: 154 if (defaultTitle !== undefined && defaultMessage != undefined) { 155 return { 'title': defaultTitle, 'msg': defaultMessage } as Record<string, Resource>; 156 } else { 157 return { 'title': $r('app.string.TITLE_APP_ERROR'), 'msg': $r('app.string.MESSAGE_APP_INSIDE_ERROR') } as Record<string, Resource>; 158 } 159 } 160} 161 162async function startAlertAbility(context: common.UIAbilityContext | common.ServiceExtensionContext, error: BusinessError) { 163 context.startAbility({ 164 bundleName: 'com.ohos.dlpmanager', 165 abilityName: 'AlertAbility', 166 parameters: { 167 error: error, 168 } 169 }, async (err: BusinessError) => { 170 if (err.code !== 0) { 171 console.error(TAG, 'start AlertAbility failed', err.code, err.message); 172 } 173 context.terminateSelf() 174 }) 175} 176 177function judgeIsSandBox() { 178 return new Promise<boolean>(async resolve => { 179 let abilityWant: Want = GlobalContext.load('abilityWant') as Want; 180 let callerToken: number = abilityWant.parameters?.['ohos.aafwk.param.callerToken'] as number; 181 let callerBundleName: string = abilityWant.parameters?.['ohos.aafwk.param.callerBundleName'] as string; 182 GlobalContext.store('applicationInfo', await bundleManager.getApplicationInfo( 183 callerBundleName, bundleManager.ApplicationFlag.GET_APPLICATION_INFO_DEFAULT)); 184 if (callerToken === (GlobalContext.load('applicationInfo') as bundleManager.ApplicationInfo).accessTokenId) { 185 resolve(false); 186 } 187 resolve(true); 188 }) 189} 190 191let removeDuplicate = (arr: AuthAccount[], arg: string) => { 192 let map: Map<string, AuthAccount> = new Map(); 193 for (let item of arr) { 194 if (!map.has(item.authAccount)) { 195 map.set(item.authAccount, item); 196 } 197 } 198 return Array.from<AuthAccount>(map.values()); 199} 200 201 202let calculate = (newValue: Area, allNames: AuthAccount[]) => { 203 let editLength = allNames.length; 204 let screenWidth = Number(newValue['width']) - Constants.HEADER_COLUMN_PADDING_LEFT; 205 let rowNamesLen = Math.floor(screenWidth / (Constants.ENCRYPTION_STAFF_WIDTH + Constants.ENCRYPTION_ADD_STAFF_MARGIN_RIGHT)); 206 let showNamesArr = editLength > Constants.ENCRYPTION_DOUBLED_NUMBER * rowNamesLen 207 ? allNames.slice(0, 2 * rowNamesLen - 1) 208 : allNames.slice(0, 2 * rowNamesLen); 209 let hideNamesNum = editLength - showNamesArr.length > 0 210 ? String(editLength - showNamesArr.length) 211 : '0'; 212 return { 213 'rowNamesLen': rowNamesLen, 214 'showNamesArr': showNamesArr, 215 'hideNamesNum': hideNamesNum 216 } as Record<string, number | AuthAccount[] | string> 217} 218 219let toggleShow = (allNames: AuthAccount[], showNamesArr: AuthAccount[], editFlag: boolean, rowNamesLen: number) => { 220 if (showNamesArr.length < allNames.length) { 221 let showFlag = !editFlag; 222 let showNamesArr = allNames; 223 return { 224 'showNamesArr': showNamesArr, 225 'showFlag': showFlag 226 } as Record<string, AuthAccount[] | boolean>; 227 } else { 228 let showFlag = !editFlag; 229 let showNamesArr = allNames.length > Constants.ENCRYPTION_DOUBLED_NUMBER * rowNamesLen 230 ? allNames.slice(0, Constants.ENCRYPTION_DOUBLED_NUMBER * rowNamesLen - 1) 231 : allNames.slice(0, Constants.ENCRYPTION_DOUBLED_NUMBER * rowNamesLen); 232 return { 233 'showNamesArr': showNamesArr, 234 'showFlag': showFlag 235 } as Record<string, AuthAccount[] | boolean>; 236 } 237} 238 239 240function directionStatus(func: Callback<number>) { 241 let innerEvent: emitter.InnerEvent = { 242 eventId: Constants.ENCRYPTION_EMIT_DIRECTION_STATUS 243 }; 244 emitter.on(innerEvent, (eventData: emitter.EventData) => { 245 func(eventData.data?.direction); 246 }); 247} 248 249function isPC(): boolean { 250 let deviceTypeName = deviceInfo.deviceType; 251 let productModel = deviceInfo.productModel; 252 253 return (deviceTypeName === 'tablet' || deviceTypeName === '2in1') && productModel?.startsWith('HYM') === true 254} 255 256function isValidPath(path: string): Boolean { 257 if (path.indexOf('/./') !== -1 || path.indexOf('/../') !== -1) { 258 return false; 259 } 260 return true; 261} 262 263 264export { 265 AuthAccount, 266 PermissionType, 267 getOsAccountInfo, 268 checkAccountLogin, 269 getUserId, 270 getAuthPerm, 271 terminateSelfWithResult, 272 startAlertAbility, 273 getAlertMessage, 274 judgeIsSandBox, 275 getFileFd, 276 getFileUriByPath, 277 removeDuplicate, 278 calculate, 279 toggleShow, 280 directionStatus, 281 isPC, 282 isValidPath 283}; 284