1/* 2 * Copyright (c) 2021 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 account_appAccount from '@ohos.account.appAccount'; 17import rpc from '@ohos.rpc'; 18 19var TAG = "[AccountTest]" 20class MyParameter { 21 constructor(params, size) { 22 this.params = params 23 this.size = size 24 } 25 26 marshalling(parcel) { 27 parcel.writeInt(this.size) 28 console.log(TAG + "size: " + this.size) 29 for (var key in this.params) { 30 parcel.writeString(key) 31 console.log(TAG + "writeBoolean key: " + key) 32 var value = this.params[key] 33 switch (typeof value) { 34 case 'string': 35 console.log(TAG + "writeString value: " + value) 36 parcel.writeInt(9) 37 parcel.writeString(value) 38 break 39 case 'boolean': 40 console.log(TAG + "writeBoolean value: " + value) 41 parcel.writeInt(1) 42 parcel.writeBoolean(value) 43 break 44 } 45 } 46 return true 47 } 48 49 unmarshalling(parcel) { 50 this.size = parcel.readInt() 51 console.log(TAG + "size: " + this.size) 52 for (var i = 0; i < this.size; ++i) { 53 var key = parcel.readString() 54 console.log(TAG + "key: " + key) 55 var type = parcel.readInt() 56 console.log(TAG + "type: " + type) 57 var value = null 58 switch (type) { 59 case 9: 60 value = parcel.readString() 61 break 62 case 1: 63 value = parcel.readBool() 64 break 65 } 66 console.log(TAG + "value: " + value) 67 this[key] = value 68 } 69 } 70} 71 72class MyWant { 73 constructor(bundleName, abilityName, parameters) { 74 this.bundleName = bundleName 75 this.abilityName = abilityName 76 this.paramSize = 0 77 for (var key in parameters) { 78 this.paramSize ++ 79 } 80 this.parameters = new MyParameter(parameters, this.paramSize) 81 } 82 marshalling(parcel) { 83 // action 84 parcel.writeString("") 85 // uri 86 parcel.writeInt(-1) 87 // entities 88 parcel.writeInt(-1) 89 // flag 90 parcel.writeInt(0) 91 if (this.bundleName == "" && this.abilityName == "") { 92 // element 93 parcel.writeInt(-1) 94 } else { 95 parcel.writeInt(1) 96 } 97 // parameters 98 if (this.paramSize > 0) { 99 parcel.writeInt(1) 100 parcel.writeSequenceable(this.parameters) 101 } else { 102 parcel.writeInt(-1) 103 } 104 // bundleName 105 parcel.writeString(this.bundleName) 106 // picker 107 parcel.writeInt(-1) 108 return true 109 } 110 111 unmarshalling(parcel) { 112 // action 113 console.log(TAG + "action: " + parcel.readString()); 114 // uri 115 console.log(TAG + "uri: " + parcel.readInt()); 116 // entities 117 console.log(TAG + "entities: " + parcel.readInt()); 118 // flag 119 console.log(TAG + "flag: " + parcel.readInt()) 120 // element 121 console.log(TAG + "element: " + parcel.readInt()) 122 // parameters 123 var hasParam = parcel.readInt() 124 console.log(TAG + "hasParam: " + hasParam) 125 if (hasParam == 1) { 126 parcel.readSequenceable(this.parameters) 127 } 128 // bundleName 129 parcel.readString() 130 // picker 131 parcel.readInt() 132 return true; 133 } 134} 135 136class VerifyCredentialOptions { 137 constructor(credentialType, credential, parameters) { 138 this.credential = credential 139 this.credentialType = credentialType 140 this.parameters = new MyParameter(parameters, 0) 141 } 142 143 unmarshalling(parcel) { 144 this.credentialType = readString8(parcel) 145 this.credential = readString8(parcel) 146 parcel.readSequenceable(this.parameters) 147 return true 148 } 149} 150 151class SetPropertiesOptions { 152 constructor(properties, parameters) { 153 this.properties = new MyParameter(properties, 0) 154 this.parameters = new MyParameter(parameters, 0) 155 } 156 157 unmarshalling(parcel) { 158 parcel.readSequenceable(this.properties) 159 parcel.readSequenceable(this.parameters) 160 return true 161 } 162} 163 164function readString8(data) { 165 var size = data.readInt() 166 var padSize = (((size + 4) & (~3)) - size - 1) 167 console.log(TAG + "padSize: " + padSize) 168 var str = "" 169 var count = 0 170 for (var i = 0; i < (size + 1 + padSize) / 4; ++i) { 171 var result = data.readInt() 172 if (count != size) { 173 str += String.fromCharCode((result & 0x000000FF)) 174 count++ 175 } 176 if (count != size) { 177 str += String.fromCharCode((result & 0x0000FF00) >>> 8) 178 count++ 179 } 180 if (count != size) { 181 str += String.fromCharCode((result & 0x00FF0000) >>> 16) 182 count++ 183 } 184 if (count != size) { 185 str += String.fromCharCode((result & 0xFF000000) >>> 24) 186 count++ 187 } 188 } 189 return str 190} 191 192function readStringArray(data) { 193 var size = data.readInt() 194 console.log(TAG + "label size: " + size) 195 var result = [] 196 for (var i = 0; i < size; ++i) { 197 result.push(readString8(data)) 198 } 199 return result 200} 201 202class MyAuthenticatorCallback { 203 204 constructor(callback) { 205 this.callback = callback 206 this.newData = new rpc.MessageParcel() 207 this.newReply = new rpc.MessageParcel() 208 this.newOptions = new rpc.MessageOption() 209 this.newData.writeInterfaceToken("ohos.accountfwk.IAppAccountAuthenticatorCallback") 210 } 211 212 onResult(resultCode, result) { 213 this.newData.writeInt(resultCode) 214 var want = new MyWant("", "", result) 215 this.newData.writeSequenceable(want) 216 this.callback.sendRequest(0, this.newData, this.newReply, this.newOptions) 217 } 218 219 onRequestRedirected(request) { 220 this.newData.writeSequenceable(request) 221 this.callback.sendRequest(1, this.newData, this.newReply, this.newOptions) 222 } 223 224 onRequestContinued() { 225 this.callback.sendRequest(2, this.newData, this.newReply, this.newOptions) 226 } 227} 228 229class MyAuthenticator extends rpc.RemoteObject { 230 authenticatorImpl = new MyAuthenticatorImpl() 231 constructor() { 232 super("authenticator") 233 } 234 235 onRemoteRequest(code, data, reply, options) { 236 console.log(TAG + "code: " + code) 237 data.readInterfaceToken() 238 var name = null 239 var callback = null 240 switch (code) { 241 case 2 : 242 name = readString8(data) 243 var verifyOptions = new VerifyCredentialOptions("", "", {}) 244 data.readSequenceable(verifyOptions) 245 callback = new MyAuthenticatorCallback(data.readRemoteObject()) 246 this.authenticatorImpl.verifyCredential(name, verifyOptions, callback) 247 break 248 case 3 : 249 name = readString8(data) 250 var labels = readStringArray(data) 251 callback = new MyAuthenticatorCallback(data.readRemoteObject()) 252 console.log(TAG + "callback: " + callback) 253 this.authenticatorImpl.checkAccountLabels(name, labels, callback) 254 break 255 case 4 : 256 var setOptions = new SetPropertiesOptions({}, {}) 257 data.readSequenceable(setOptions) 258 callback = new MyAuthenticatorCallback(data.readRemoteObject()) 259 this.authenticatorImpl.setProperties(setOptions, callback) 260 break 261 case 5 : 262 name = readString8(data) 263 callback = new MyAuthenticatorCallback(data.readRemoteObject()) 264 this.authenticatorImpl.checkAccountRemovable(name, callback) 265 break 266 } 267 return true 268 } 269 270 getRemoteObject() { 271 return this 272 } 273} 274 275class MyAuthenticatorImpl { 276 accountLables = { 277 "zhangsan": ["male", "30-40", "level4"], 278 "lisi": ["female"] 279 } 280 281 accountCredentials = { 282 "zhangsan": { 283 "PIN": "123456", 284 "NUMBER": "12356789" 285 }, 286 "lisi": { 287 "FACE": "X00001" 288 } 289 } 290 291 accountRemovability = { 292 "zhangsan": false, 293 "lisi": true 294 } 295 296 properties = {} 297 298 verifyCredential(name, options, callback) { 299 console.log(TAG + "name: " + name + ", options: " + JSON.stringify(options)) 300 if (name == "xiaoming") { 301 callback.onRequestContinued() 302 return 303 } 304 var credentialInfo = this.accountCredentials[name] 305 if (credentialInfo == undefined) { 306 callback.onResult(0, {"booleanResult": false}) 307 return 308 } 309 if (options.credentialType == undefined || options.credential == undefined) { 310 var want = new MyWant("com.ohos.accountauthenticator", "VerifyAbility", 311 {"credentialType": options.credentialType, "credential": options.credential}) 312 callback.onRequestRedirected(want) 313 return 314 } 315 var credential = credentialInfo[options.credentialType.toUpperCase()] 316 if (credential == undefined || credential != options.credential) { 317 callback.onResult(0, {"booleanResult": false}) 318 return 319 } 320 callback.onResult(0, {"booleanResult": true}) 321 } 322 323 checkAccountLabels(name, labels, callback) { 324 console.log(TAG + "name: " + name + ", labels: " + JSON.stringify(labels)) 325 if (labels.length == 0) { 326 callback.onResult(0, {"booleanResult": true}) 327 return 328 } 329 var allLabels = this.accountLables[name] 330 if (allLabels == undefined || allLabels.length == 0) { 331 callback.onResult(0, {"booleanResult": false}) 332 return 333 } 334 for (var i = 0; i < labels.length; ++i) { 335 if (allLabels.indexOf(labels[i]) == -1) { 336 callback.onResult(0, {"booleanResult": false}) 337 return 338 } 339 } 340 callback.onResult(0, {"booleanResult": true}) 341 } 342 343 setProperties(options, callback) { 344 console.log(TAG + "options: " + JSON.stringify(options)) 345 callback.onResult(10016, {}) 346 } 347 348 checkAccountRemovable(name, callback) { 349 console.log(TAG + "name: " + name) 350 var isRemovable = this.accountRemovability[name] 351 if (isRemovable == undefined || isRemovable == false) { 352 callback.onResult(0, {"booleanResult": false}) 353 return 354 } 355 callback.onResult(0, {"booleanResult": true}) 356 } 357} 358 359export {MyAuthenticator}