1/** 2 * Copyright (c) 2024-2024 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 { CustomContentDialog, AlertDialog } from '@ohos.arkui.advanced.Dialog'; 17import { CMModelErrorCode, CMModelOptType } from '../model/CertMangerModel'; 18import checkUserAuthModel from '../model/CheckUserAuthModel'; 19import { BusinessError } from '@ohos.base'; 20import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; 21import certManagerModel from '../model/CertMangerModel'; 22import util from '@ohos.util'; 23 24/* instrument ignore file */ 25 26const TAG = 'CertificateInstallPage'; 27let storage = LocalStorage.getShared(); 28 29@Entry(storage) 30@Component 31struct CertificateInstallPage { 32 @State installFailedDialogMessage: ResourceStr = ''; 33 @State callerName: string = ''; 34 @State resultCode: number = CMModelErrorCode.CM_MODEL_ERROR_FAILED; 35 @State successUri: string = ''; 36 ; 37 private session: UIExtensionContentSession = 38 storage?.get<UIExtensionContentSession>('session') as UIExtensionContentSession; 39 private want: Want = storage?.get<Want>('want') as Want; 40 41 private context: Context = getContext(this); 42 43 installFailedDialog: CustomDialogController = new CustomDialogController({ 44 alignment: DialogAlignment.Center, 45 showInSubWindow: true, 46 cancel: () => { 47 this.session?.terminateSelfWithResult({ 48 resultCode: this.resultCode 49 }); 50 }, 51 builder: AlertDialog({ 52 primaryTitle: $r('app.string.cert_install_failed'), 53 content: this.installFailedDialogMessage, 54 primaryButton: { 55 value: $r('app.string.OK'), 56 action: () => { 57 this.session?.terminateSelfWithResult({ 58 resultCode: this.resultCode 59 }); 60 } 61 } 62 }) 63 }); 64 65 installSuccessDialog: CustomDialogController = new CustomDialogController({ 66 alignment: DialogAlignment.Center, 67 showInSubWindow: true, 68 cancel: () => { 69 this.session?.sendData({'uri': this.successUri}); 70 }, 71 builder: AlertDialog({ 72 primaryTitle: $r('app.string.cert_install_success'), 73 content: $r('app.string.cert_install_success_tip'), 74 primaryButton: { 75 value: $r('app.string.OK'), 76 action: () => { 77 this.session?.sendData({'uri': this.successUri}); 78 } 79 } 80 }) 81 }); 82 83 rootCertificateDialog: CustomDialogController = new CustomDialogController({ 84 alignment: DialogAlignment.Center, 85 showInSubWindow: false, 86 cancel: () => { 87 this.session?.terminateSelf(); 88 }, 89 builder: AlertDialog({ 90 primaryTitle: $r('app.string.cert_install_tip', this.callerName), 91 content: $r('app.string.cert_install_warning'), 92 primaryButton: { 93 value: $r('app.string.root_certificate_cancel'), 94 action: () => { 95 console.info(TAG, 'USER_CA_STATUS_CONFIRM cancel'); 96 this.session?.terminateSelf(); 97 } 98 }, 99 secondaryButton: { 100 value: $r('app.string.root_certificate_continue'), 101 action: () => { 102 console.info(TAG, 'USER_CA_STATUS_CONFIRM confirm'); 103 this.checkUserAuth(); 104 } 105 } 106 }), 107 }) 108 109 aboutToAppear(): void { 110 let isGranted = this.getCallerName(); 111 if (!isGranted) { 112 this.session?.terminateSelf(); 113 return; 114 } 115 this.rootCertificateDialog.open(); 116 } 117 118 build() { 119 } 120 121 private getCallerName(): boolean { 122 if (this.want === undefined || this.want === null) { 123 console.error(TAG, 'initData, want is undefined'); 124 return false; 125 } 126 let parameters = this.want.parameters; 127 if (parameters === undefined || parameters === null) { 128 console.error(TAG, 'initData, parameters is undefined'); 129 return false; 130 } 131 let callerName = parameters['bundleName']; 132 if (callerName === undefined || callerName === null) { 133 console.error(TAG, 'getCallerName, callerName is undefined'); 134 return false; 135 } 136 this.callerName = 'callerName as string'; 137 return true; 138 } 139 140 private handleInstallResult(resultCode: CMModelErrorCode, uri: string) { 141 if (resultCode === CMModelErrorCode.CM_MODEL_ERROR_SUCCESS) { 142 this.successUri = uri; 143 this.installSuccessDialog.open(); 144 } else if (resultCode === CMModelErrorCode.CM_MODEL_ERROR_INCORRECT_FORMAT) { 145 this.resultCode = CMModelErrorCode.CM_MODEL_ERROR_INCORRECT_FORMAT; 146 this.installFailedDialogMessage = $r('app.string.Install_ERROR_INCORRECT_FORMAT'); 147 this.installFailedDialog.open(); 148 } else if (resultCode === CMModelErrorCode.CM_MODEL_ERROR_MAX_QUANTITY_REACHED) { 149 this.resultCode = CMModelErrorCode.CM_MODEL_ERROR_MAX_QUANTITY_REACHED; 150 this.installFailedDialogMessage = $r('app.string.Install_Error_MAX_QUANTITY_REACHED'); 151 this.installFailedDialog.open(); 152 } else { 153 console.debug(TAG, `result code ${resultCode}, need not show result`); 154 this.session?.terminateSelfWithResult({ 155 resultCode: resultCode 156 }); 157 } 158 } 159 160 checkUserAuth() { 161 let titleStr = this.context?.resourceManager.getStringSync($r('app.string.Identity_Authentication')); 162 checkUserAuthModel.auth(titleStr, (authResult: boolean) => { 163 if (!authResult) { 164 console.warn(TAG, 'userAuth cancel!'); 165 this.session?.terminateSelf(); 166 return; 167 } 168 console.info(TAG, 'userAuth success!'); 169 this.installCaCertificate(); 170 }) 171 } 172 173 private async getCertificateData(parameters: Record<string, Object>): Promise<Uint8Array | undefined> { 174 return new Promise<Uint8Array | undefined>(resolve => { 175 let certificateDataObj = parameters['cert']; 176 if (certificateDataObj === undefined || certificateDataObj === null) { 177 console.error(TAG, 'getCertificateData, certificate data is undefined'); 178 return resolve(undefined); 179 } 180 new util.Base64Helper().decode(certificateDataObj as string).then((value) => { 181 return resolve(value); 182 }).catch((error: BusinessError) => { 183 console.error(TAG, `decode certificate data err: ${error?.code}, msg: ${error?.message}`); 184 return resolve(undefined); 185 }); 186 }); 187 } 188 189 private installCaCertificate(): void { 190 if (this.want === undefined || this.want === null) { 191 console.error(TAG, 'initData, want is undefined'); 192 return; 193 } 194 let parameters = this.want.parameters; 195 if (parameters === undefined || parameters === null) { 196 console.error(TAG, 'initData, parameters is undefined'); 197 return; 198 } 199 this.getCertificateData(parameters).then(data => { 200 if (data === undefined) { 201 console.error(TAG, 'installCaCertificate, certificate data is undefined'); 202 this.session?.terminateSelf(); 203 return; 204 } 205 certManagerModel.installCertOrCred(CMModelOptType.CM_MODEL_OPT_USER_CA, '', data, 206 '', (resultCode: CMModelErrorCode, uri: string) => { 207 console.info(TAG, `installCertOrCred result: ${resultCode}`); 208 this.handleInstallResult(resultCode, uri); 209 }); 210 }) 211 } 212}