1 /*
2  * Copyright (c) 2022-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 
16 #include "account_iam_client.h"
17 
18 #include "accesstoken_kit.h"
19 #include "account_error_no.h"
20 #include "account_iam_callback_service.h"
21 #include "account_log_wrapper.h"
22 #include "account_proxy.h"
23 #include "account_permission_manager.h"
24 #include "ipc_skeleton.h"
25 #include "ohos_account_kits_impl.h"
26 #include "os_account_manager.h"
27 #ifdef HAS_PIN_AUTH_PART
28 #include "pinauth_register.h"
29 #endif
30 
31 namespace OHOS {
32 namespace AccountSA {
33 namespace {
34 const std::string PERMISSION_ACCESS_PIN_AUTH = "ohos.permission.ACCESS_PIN_AUTH";
35 const std::string PERMISSION_MANAGE_USER_IDM = "ohos.permission.MANAGE_USER_IDM";
36 const std::string PERMISSION_ACCESS_USER_AUTH_INTERNAL = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
37 }
38 
GetInstance()39 AccountIAMClient &AccountIAMClient::GetInstance()
40 {
41     static AccountIAMClient *instance = new (std::nothrow) AccountIAMClient();
42     return *instance;
43 }
44 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)45 int32_t AccountIAMClient::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
46 {
47     auto proxy = GetAccountIAMProxy();
48     if (proxy == nullptr) {
49         return ERR_ACCOUNT_COMMON_GET_PROXY;
50     }
51     return proxy->OpenSession(userId, challenge);
52 }
53 
CloseSession(int32_t userId)54 int32_t AccountIAMClient::CloseSession(int32_t userId)
55 {
56     auto proxy = GetAccountIAMProxy();
57     if (proxy == nullptr) {
58         return ERR_ACCOUNT_COMMON_GET_PROXY;
59     }
60     return proxy->CloseSession(userId);
61 }
62 
AddCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)63 void AccountIAMClient::AddCredential(
64     int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
65 {
66     if (callback == nullptr) {
67         ACCOUNT_LOGE("the callback for adding credential is nullptr");
68         return;
69     }
70     Attributes emptyResult;
71     auto proxy = GetAccountIAMProxy();
72     if (proxy == nullptr) {
73         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
74         return;
75     }
76     if ((userId == -1) && (!GetCurrentUserId(userId))) {
77         ACCOUNT_LOGE("fail to add credential for invalid userId");
78         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
79         return;
80     }
81     if (credInfo.authType == AuthType::PIN) {
82         SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
83     }
84     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
85     proxy->AddCredential(userId, credInfo, wrapper);
86 }
87 
UpdateCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)88 void AccountIAMClient::UpdateCredential(
89     int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
90 {
91     if (callback == nullptr) {
92         ACCOUNT_LOGE("the callback for updating credential is nullptr");
93         return;
94     }
95     Attributes emptyResult;
96     auto proxy = GetAccountIAMProxy();
97     if (proxy == nullptr) {
98         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
99         return;
100     }
101     if ((userId == -1) && (!GetCurrentUserId(userId))) {
102         ACCOUNT_LOGE("fail to update credential for invalid userId");
103         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
104         return;
105     }
106     if (credInfo.authType == AuthType::PIN) {
107         SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
108     }
109     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
110     proxy->UpdateCredential(userId, credInfo, wrapper);
111 }
112 
DelCred(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)113 void AccountIAMClient::DelCred(int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken,
114     const std::shared_ptr<IDMCallback>& callback)
115 {
116     if (callback == nullptr) {
117         ACCOUNT_LOGE("the callback for deleting credential is nullptr");
118         return;
119     }
120     Attributes emptyResult;
121     auto proxy = GetAccountIAMProxy();
122     if (proxy == nullptr) {
123         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
124         return;
125     }
126     if ((userId == -1) && (!GetCurrentUserId(userId))) {
127         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
128         return;
129     }
130     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
131     proxy->DelCred(userId, credentialId, authToken, wrapper);
132 }
133 
DelUser(int32_t userId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)134 void AccountIAMClient::DelUser(
135     int32_t userId, const std::vector<uint8_t> &authToken, const std::shared_ptr<IDMCallback> &callback)
136 {
137     if (callback == nullptr) {
138         ACCOUNT_LOGE("the callback for deleting user is nullptr");
139         return;
140     }
141     Attributes emptyResult;
142     auto proxy = GetAccountIAMProxy();
143     if (proxy == nullptr) {
144         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
145         return;
146     }
147     if ((userId == -1) && (!GetCurrentUserId(userId))) {
148         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
149         return;
150     }
151     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
152     proxy->DelUser(userId, authToken, wrapper);
153 }
154 
GetCredentialInfo(int32_t userId,AuthType authType,const std::shared_ptr<GetCredInfoCallback> & callback)155 int32_t AccountIAMClient::GetCredentialInfo(
156     int32_t userId, AuthType authType, const std::shared_ptr<GetCredInfoCallback> &callback)
157 {
158     auto proxy = GetAccountIAMProxy();
159     if (proxy == nullptr) {
160         return ERR_ACCOUNT_COMMON_GET_PROXY;
161     }
162     sptr<IGetCredInfoCallback> wrapper = new (std::nothrow) GetCredInfoCallbackService(callback);
163     ErrCode result = proxy->GetCredentialInfo(userId, authType, wrapper);
164     if ((result != ERR_OK) && (callback != nullptr)) {
165         std::vector<CredentialInfo> infoList;
166         callback->OnCredentialInfo(result, infoList);
167     }
168     return result;
169 }
170 
Cancel(int32_t userId)171 int32_t AccountIAMClient::Cancel(int32_t userId)
172 {
173     auto proxy = GetAccountIAMProxy();
174     if (proxy == nullptr) {
175         return ERR_ACCOUNT_COMMON_GET_PROXY;
176     }
177     return proxy->Cancel(userId);
178 }
179 
180 #ifdef HAS_PIN_AUTH_PART
StartDomainAuth(int32_t userId,const std::shared_ptr<IDMCallback> & callback)181 uint64_t AccountIAMClient::StartDomainAuth(int32_t userId, const std::shared_ptr<IDMCallback> &callback)
182 {
183     std::lock_guard<std::mutex> lock(domainMutex_);
184     Attributes emptyResult;
185     if (domainInputer_ == nullptr) {
186         ACCOUNT_LOGE("the registered inputer is not found or invalid");
187         callback->OnResult(ERR_ACCOUNT_IAM_KIT_INPUTER_NOT_REGISTERED, emptyResult);
188         return 0;
189     }
190     domainInputer_->OnGetData(IAMAuthType::DOMAIN, std::vector<uint8_t>(),
191         std::make_shared<DomainCredentialRecipient>(userId, callback));
192     return 0;
193 }
194 #endif
195 
PrepareRemoteAuth(const std::string & remoteNetworkId,const std::shared_ptr<PreRemoteAuthCallback> & callback)196 int32_t AccountIAMClient::PrepareRemoteAuth(
197     const std::string &remoteNetworkId, const std::shared_ptr<PreRemoteAuthCallback> &callback)
198 {
199     if (callback == nullptr) {
200         ACCOUNT_LOGE("Callback for PrepareRemoteAuth is nullptr.");
201         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
202     }
203     auto proxy = GetAccountIAMProxy();
204     if (proxy == nullptr) {
205         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY);
206         return ERR_ACCOUNT_COMMON_GET_PROXY;
207     }
208     sptr<IPreRemoteAuthCallback> wrapper = new (std::nothrow) PreRemoteAuthCallbackService(callback);
209     return proxy->PrepareRemoteAuth(remoteNetworkId, wrapper);
210 }
211 
Auth(AuthOptions & authOptions,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)212 uint64_t AccountIAMClient::Auth(AuthOptions& authOptions, const std::vector<uint8_t> &challenge,
213     AuthType authType, AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
214 {
215     return AuthUser(authOptions, challenge, authType, authTrustLevel, callback);
216 }
217 
AuthUser(AuthOptions & authOptions,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)218 uint64_t AccountIAMClient::AuthUser(
219     AuthOptions &authOptions, const std::vector<uint8_t> &challenge, AuthType authType,
220     AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
221 {
222     uint64_t contextId = 0;
223     if (callback == nullptr) {
224         ACCOUNT_LOGE("callback is nullptr");
225         return contextId;
226     }
227     auto proxy = GetAccountIAMProxy();
228     if (proxy == nullptr) {
229         return contextId;
230     }
231     if ((!authOptions.hasRemoteAuthOptions) && (authOptions.accountId == -1) &&
232         (!GetCurrentUserId(authOptions.accountId))) {
233         return contextId;
234     }
235 #ifdef HAS_PIN_AUTH_PART
236     if (static_cast<int32_t>(authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
237         return StartDomainAuth(authOptions.accountId, callback);
238     }
239 #endif
240     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(authOptions.accountId, callback);
241     AuthParam authParam;
242     authParam.challenge = challenge;
243     authParam.authType = authType;
244     authParam.authTrustLevel = authTrustLevel;
245     authParam.userId = authOptions.accountId;
246     authParam.authIntent = authOptions.authIntent;
247     if (authOptions.hasRemoteAuthOptions) {
248         authParam.remoteAuthParam = RemoteAuthParam();
249         if (authOptions.remoteAuthOptions.hasVerifierNetworkId) {
250             authParam.remoteAuthParam.value().verifierNetworkId = authOptions.remoteAuthOptions.verifierNetworkId;
251         }
252         if (authOptions.remoteAuthOptions.hasCollectorNetworkId) {
253             authParam.remoteAuthParam.value().collectorNetworkId = authOptions.remoteAuthOptions.collectorNetworkId;
254         }
255         if (authOptions.remoteAuthOptions.hasCollectorTokenId) {
256             authParam.remoteAuthParam.value().collectorTokenId = authOptions.remoteAuthOptions.collectorTokenId;
257         }
258     }
259     ErrCode result = proxy->AuthUser(authParam, wrapper, contextId);
260     if (result != ERR_OK) {
261         Attributes emptyResult;
262         callback->OnResult(result, emptyResult);
263     }
264     return contextId;
265 }
266 
CancelAuth(uint64_t contextId)267 int32_t AccountIAMClient::CancelAuth(uint64_t contextId)
268 {
269     auto proxy = GetAccountIAMProxy();
270     if (proxy == nullptr) {
271         return ERR_ACCOUNT_COMMON_GET_PROXY;
272     }
273     return proxy->CancelAuth(contextId);
274 }
275 
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel,int32_t & status)276 int32_t AccountIAMClient::GetAvailableStatus(AuthType authType, AuthTrustLevel authTrustLevel, int32_t &status)
277 {
278     auto proxy = GetAccountIAMProxy();
279     if (proxy == nullptr) {
280         return ERR_ACCOUNT_COMMON_GET_PROXY;
281     }
282     if (authTrustLevel < UserIam::UserAuth::ATL1 || authTrustLevel > UserIam::UserAuth::ATL4) {
283         ACCOUNT_LOGE("authTrustLevel is not in correct range");
284         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
285     }
286     if (authType < UserIam::UserAuth::ALL) {
287         ACCOUNT_LOGE("authType is not in correct range");
288         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
289     }
290     return proxy->GetAvailableStatus(authType, authTrustLevel, status);
291 }
292 
GetProperty(int32_t userId,const GetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)293 void AccountIAMClient::GetProperty(
294     int32_t userId, const GetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
295 {
296     if (callback == nullptr) {
297         ACCOUNT_LOGE("the callback for getting property is nullptr");
298         return;
299     }
300     Attributes emptyResult;
301     auto proxy = GetAccountIAMProxy();
302     if (proxy == nullptr) {
303         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
304         return;
305     }
306     sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
307     proxy->GetProperty(userId, request, wrapper);
308 }
309 
GetPropertyByCredentialId(uint64_t credentialId,std::vector<Attributes::AttributeKey> & keys,const std::shared_ptr<GetSetPropCallback> & callback)310 void AccountIAMClient::GetPropertyByCredentialId(uint64_t credentialId,
311     std::vector<Attributes::AttributeKey> &keys, const std::shared_ptr<GetSetPropCallback> &callback)
312 {
313     if (callback == nullptr) {
314         ACCOUNT_LOGE("The callback for getting property is nullptr");
315         return;
316     }
317     Attributes emptyResult;
318     auto proxy = GetAccountIAMProxy();
319     if (proxy == nullptr) {
320         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
321         return;
322     }
323     sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
324     proxy->GetPropertyByCredentialId(credentialId, keys, wrapper);
325 }
326 
SetProperty(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)327 void AccountIAMClient::SetProperty(
328     int32_t userId, const SetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
329 {
330     if (callback == nullptr) {
331         ACCOUNT_LOGE("the callback for setting property is nullptr");
332         return;
333     }
334     Attributes emptyResult;
335     auto proxy = GetAccountIAMProxy();
336     if (proxy == nullptr) {
337         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
338         return;
339     }
340     sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
341     proxy->SetProperty(userId, request, wrapper);
342 }
343 
GetEnrolledId(int32_t accountId,AuthType authType,const std::shared_ptr<GetEnrolledIdCallback> & callback)344 void AccountIAMClient::GetEnrolledId(
345     int32_t accountId, AuthType authType, const std::shared_ptr<GetEnrolledIdCallback> &callback)
346 {
347     if (callback == nullptr) {
348         ACCOUNT_LOGE("The callback for get enrolled id is nullptr");
349         return;
350     }
351     uint64_t emptyResult = 0;
352     auto proxy = GetAccountIAMProxy();
353     if (proxy == nullptr) {
354         callback->OnEnrolledId(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
355         return;
356     }
357     sptr<IGetEnrolledIdCallback> wrapper = new (std::nothrow) GetEnrolledIdCallbackService(callback);
358     if (wrapper == nullptr) {
359         callback->OnEnrolledId(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
360         return;
361     }
362     proxy->GetEnrolledId(accountId, authType, wrapper);
363 }
364 
CheckSelfPermission(const std::string & permissionName)365 bool AccountIAMClient::CheckSelfPermission(const std::string &permissionName)
366 {
367     Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetSelfTokenID();
368     ErrCode result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
369     return result == Security::AccessToken::TypePermissionState::PERMISSION_GRANTED;
370 }
371 
372 #ifdef HAS_PIN_AUTH_PART
RegisterPINInputer(const std::shared_ptr<IInputer> & inputer)373 ErrCode AccountIAMClient::RegisterPINInputer(const std::shared_ptr<IInputer> &inputer)
374 {
375     std::lock_guard<std::mutex> lock(pinMutex_);
376     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
377     if (result != ERR_OK) {
378         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
379         return result;
380     }
381     if (pinInputer_ != nullptr) {
382         ACCOUNT_LOGE("inputer is already registered");
383         return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
384     }
385     int32_t userId = -1;
386     if (!GetCurrentUserId(userId)) {
387         return ERR_ACCOUNT_IAM_KIT_GET_USERID_FAIL;
388     }
389     auto iamInputer = std::make_shared<IAMInputer>(userId, inputer);
390     if (UserIam::PinAuth::PinAuthRegister::GetInstance().RegisterInputer(iamInputer)) {
391         pinInputer_ = inputer;
392         return ERR_OK;
393     }
394     return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
395 }
396 
RegisterDomainInputer(const std::shared_ptr<IInputer> & inputer)397 ErrCode AccountIAMClient::RegisterDomainInputer(const std::shared_ptr<IInputer> &inputer)
398 {
399     std::lock_guard<std::mutex> lock(domainMutex_);
400     if (domainInputer_ != nullptr) {
401         ACCOUNT_LOGE("inputer is already registered");
402         return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
403     }
404     domainInputer_ = inputer;
405     return ERR_OK;
406 }
407 
RegisterInputer(int32_t authType,const std::shared_ptr<IInputer> & inputer)408 ErrCode AccountIAMClient::RegisterInputer(int32_t authType, const std::shared_ptr<IInputer> &inputer)
409 {
410     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
411     if (result != ERR_OK) {
412         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
413         return result;
414     }
415     if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
416         (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
417         ACCOUNT_LOGE("failed to check permission");
418         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
419     }
420     if (inputer == nullptr) {
421         ACCOUNT_LOGE("inputer is nullptr");
422         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
423     }
424     switch (authType) {
425         case IAMAuthType::DOMAIN:
426             return RegisterDomainInputer(inputer);
427         default:
428             return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
429     }
430 }
431 
UnregisterInputer(int32_t authType)432 ErrCode AccountIAMClient::UnregisterInputer(int32_t authType)
433 {
434     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
435     if (result != ERR_OK) {
436         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
437         return result;
438     }
439     if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
440         (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
441         ACCOUNT_LOGE("failed to check permission");
442         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
443     }
444     switch (authType) {
445         case IAMAuthType::DOMAIN:
446             return UnregisterDomainInputer();
447         default:
448             return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
449     }
450     return ERR_OK;
451 }
452 
UnregisterPINInputer()453 ErrCode AccountIAMClient::UnregisterPINInputer()
454 {
455     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
456     if (result != ERR_OK) {
457         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
458         return result;
459     }
460     if (!CheckSelfPermission(PERMISSION_ACCESS_PIN_AUTH)) {
461         ACCOUNT_LOGE("failed to check permission");
462         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
463     }
464     UserIam::PinAuth::PinAuthRegister::GetInstance().UnRegisterInputer();
465     std::lock_guard<std::mutex> lock(pinMutex_);
466     pinInputer_ = nullptr;
467     return ERR_OK;
468 }
469 
UnregisterDomainInputer()470 ErrCode AccountIAMClient::UnregisterDomainInputer()
471 {
472     std::lock_guard<std::mutex> lock(domainMutex_);
473     domainInputer_ = nullptr;
474     return ERR_OK;
475 }
476 #endif
477 
GetAccountState(int32_t userId)478 IAMState AccountIAMClient::GetAccountState(int32_t userId)
479 {
480     auto proxy = GetAccountIAMProxy();
481     if (proxy == nullptr) {
482         return IDLE;
483     }
484     return proxy->GetAccountState(userId);
485 }
486 
SetAuthSubType(int32_t userId,int32_t authSubType)487 void AccountIAMClient::SetAuthSubType(int32_t userId, int32_t authSubType)
488 {
489     std::lock_guard<std::mutex> lock(mutex_);
490     auto it = credentialMap_.find(userId);
491     if (it != credentialMap_.end()) {
492         return;
493     }
494     credentialMap_[userId] = {
495         .type = authSubType
496     };
497 }
498 
GetAuthSubType(int32_t userId)499 int32_t AccountIAMClient::GetAuthSubType(int32_t userId)
500 {
501     std::lock_guard<std::mutex> lock(mutex_);
502     auto it = credentialMap_.find(userId);
503     if (it != credentialMap_.end()) {
504         return it->second.type;
505     }
506     return 0;
507 }
508 
GetCurrentUserId(int32_t & userId)509 bool AccountIAMClient::GetCurrentUserId(int32_t &userId)
510 {
511     std::vector<int32_t> userIds;
512     if ((OsAccountManager::QueryActiveOsAccountIds(userIds) != ERR_OK) || userIds.empty()) {
513         ACCOUNT_LOGE("fail to get activated os account ids");
514         return false;
515     }
516     userId = userIds[0];
517     return true;
518 }
519 
ResetAccountIAMProxy(const wptr<IRemoteObject> & remote)520 void AccountIAMClient::ResetAccountIAMProxy(const wptr<IRemoteObject>& remote)
521 {
522     std::lock_guard<std::mutex> lock(mutex_);
523     if (proxy_ == nullptr) {
524         ACCOUNT_LOGE("proxy is nullptr");
525         return;
526     }
527     auto serviceRemote = proxy_->AsObject();
528     if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
529         serviceRemote->RemoveDeathRecipient(deathRecipient_);
530         proxy_ = nullptr;
531     }
532 }
533 
OnRemoteDied(const wptr<IRemoteObject> & remote)534 void AccountIAMClient::AccountIAMDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
535 {
536     if (remote == nullptr) {
537         ACCOUNT_LOGE("remote is nullptr");
538         return;
539     }
540     AccountIAMClient::GetInstance().ResetAccountIAMProxy(remote);
541 }
542 
GetAccountIAMProxy()543 sptr<IAccountIAM> AccountIAMClient::GetAccountIAMProxy()
544 {
545     std::lock_guard<std::mutex> lock(mutex_);
546     if (proxy_ != nullptr) {
547         return proxy_;
548     }
549     sptr<IRemoteObject> object = OhosAccountKitsImpl::GetInstance().GetAccountIAMService();
550     if (object == nullptr) {
551         ACCOUNT_LOGE("failed to get account iam service");
552         return nullptr;
553     }
554     deathRecipient_ = new (std::nothrow) AccountIAMDeathRecipient();
555     if (deathRecipient_ == nullptr) {
556         ACCOUNT_LOGE("failed to create account iam death recipient");
557         return nullptr;
558     }
559     if (!object->AddDeathRecipient(deathRecipient_)) {
560         ACCOUNT_LOGE("failed to add account iam death recipient");
561         deathRecipient_ = nullptr;
562         return nullptr;
563     }
564     proxy_ = iface_cast<IAccountIAM>(object);
565     if (proxy_ == nullptr) {
566         ACCOUNT_LOGE("failed to get account iam proxy");
567     }
568     return proxy_;
569 }
570 }  // namespace AccountSA
571 }  // namespace OHOS
572