1 /*
2 * Copyright (c) 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 "user_auth_napi_client_impl.h"
17
18 #include "system_ability_definition.h"
19
20 #include "callback_manager.h"
21 #include "iam_logger.h"
22 #include "iam_ptr.h"
23 #include "ipc_client_utils.h"
24 #include "load_mode_client_util.h"
25 #include "modal_callback_service.h"
26 #include "user_auth_callback_service.h"
27 #include "user_auth_common_defines.h"
28
29 #define LOG_TAG "USER_AUTH_SDK"
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
GetProxy()33 sptr<IUserAuth> UserAuthNapiClientImpl::GetProxy()
34 {
35 std::lock_guard<std::mutex> lock(mutex_);
36 if (proxy_ != nullptr) {
37 return proxy_;
38 }
39 sptr<IRemoteObject> obj = IpcClientUtils::GetRemoteObject(SUBSYS_USERIAM_SYS_ABILITY_USERAUTH);
40 if (obj == nullptr) {
41 IAM_LOGE("remote object is null");
42 return proxy_;
43 }
44 sptr<IRemoteObject::DeathRecipient> dr(new (std::nothrow) UserAuthImplDeathRecipient());
45 if ((dr == nullptr) || (obj->IsProxyObject() && !obj->AddDeathRecipient(dr))) {
46 IAM_LOGE("add death recipient fail");
47 return proxy_;
48 }
49
50 proxy_ = iface_cast<IUserAuth>(obj);
51 deathRecipient_ = dr;
52 return proxy_;
53 }
54
ResetProxy(const wptr<IRemoteObject> & remote)55 void UserAuthNapiClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
56 {
57 IAM_LOGI("start");
58 std::lock_guard<std::mutex> lock(mutex_);
59 if (proxy_ == nullptr) {
60 IAM_LOGE("proxy_ is null");
61 return;
62 }
63 auto serviceRemote = proxy_->AsObject();
64 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
65 IAM_LOGI("need reset");
66 serviceRemote->RemoveDeathRecipient(deathRecipient_);
67 proxy_ = nullptr;
68 deathRecipient_ = nullptr;
69 }
70 IAM_LOGI("end reset proxy");
71 }
72
OnRemoteDied(const wptr<IRemoteObject> & remote)73 void UserAuthNapiClientImpl::UserAuthImplDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
74 {
75 IAM_LOGI("start");
76 if (remote == nullptr) {
77 IAM_LOGE("remote is nullptr");
78 return;
79 }
80 CallbackManager::GetInstance().OnServiceDeath();
81 UserAuthNapiClientImpl::Instance().ResetProxy(remote);
82 }
83
Instance()84 UserAuthNapiClientImpl &UserAuthNapiClientImpl::Instance()
85 {
86 static UserAuthNapiClientImpl impl;
87 return impl;
88 }
89
BeginWidgetAuth(int32_t apiVersion,const AuthParamInner & authParam,const WidgetParamNapi & widgetParam,const std::shared_ptr<AuthenticationCallback> & callback,const std::shared_ptr<UserAuthModalClientCallback> & modalCallback)90 uint64_t UserAuthNapiClientImpl::BeginWidgetAuth(int32_t apiVersion, const AuthParamInner &authParam,
91 const WidgetParamNapi &widgetParam, const std::shared_ptr<AuthenticationCallback> &callback,
92 const std::shared_ptr<UserAuthModalClientCallback> &modalCallback)
93 {
94 IAM_LOGI("start, apiVersion: %{public}d authTypeSize: %{public}zu authTrustLevel: %{public}u userId:%{public}d",
95 apiVersion, authParam.authTypes.size(), authParam.authTrustLevel, authParam.userId);
96
97 AuthParamInner authParamInner = {
98 .userId = authParam.userId,
99 .isUserIdSpecified = authParam.userId == INVALID_USER_ID ? false : true,
100 .challenge = authParam.challenge,
101 .authTypes = authParam.authTypes,
102 .authTrustLevel = authParam.authTrustLevel,
103 .reuseUnlockResult = authParam.reuseUnlockResult,
104 .skipLockedBiometricAuth = authParam.skipLockedBiometricAuth,
105 };
106 WidgetParamInner widgetParamInner = {
107 .title = widgetParam.title,
108 .navigationButtonText = widgetParam.navigationButtonText,
109 .windowMode = widgetParam.windowMode,
110 .hasContext = widgetParam.hasContext,
111 };
112 IAM_LOGI("has context: %{public}d", widgetParamInner.hasContext);
113 return BeginWidgetAuthInner(apiVersion, authParamInner, widgetParamInner, callback, modalCallback);
114 }
115
BeginWidgetAuthInner(int32_t apiVersion,const AuthParamInner & authParam,const WidgetParamInner & widgetParam,const std::shared_ptr<AuthenticationCallback> & callback,const std::shared_ptr<UserAuthModalClientCallback> & modalCallback)116 uint64_t UserAuthNapiClientImpl::BeginWidgetAuthInner(int32_t apiVersion, const AuthParamInner &authParam,
117 const WidgetParamInner &widgetParam, const std::shared_ptr<AuthenticationCallback> &callback,
118 const std::shared_ptr<UserAuthModalClientCallback> &modalCallback)
119 {
120 if (!callback || !modalCallback) {
121 IAM_LOGE("auth callback is nullptr");
122 return BAD_CONTEXT_ID;
123 }
124 auto proxy = GetProxy();
125 if (!proxy) {
126 IAM_LOGE("proxy is nullptr");
127 Attributes extraInfo;
128 int32_t result = LoadModeUtil::GetProxyNullResultCode(__func__, std::vector<std::string>({
129 ACCESS_BIOMETRIC_PERMISSION
130 }));
131 callback->OnResult(result, extraInfo);
132 return BAD_CONTEXT_ID;
133 }
134
135 sptr<IIamCallback> wrapper(new (std::nothrow) UserAuthCallbackService(callback, modalCallback));
136 if (wrapper == nullptr) {
137 IAM_LOGE("failed to create wrapper");
138 Attributes extraInfo;
139 callback->OnResult(static_cast<int32_t>(ResultCode::GENERAL_ERROR), extraInfo);
140 return BAD_CONTEXT_ID;
141 }
142
143 // modal
144 sptr<IModalCallback> wrapperModal(new (std::nothrow) ModalCallbackService(modalCallback));
145 if (wrapperModal == nullptr) {
146 IAM_LOGE("failed to create wrapper for modal");
147 Attributes extraInfo;
148 callback->OnResult(static_cast<int32_t>(ResultCode::GENERAL_ERROR), extraInfo);
149 return BAD_CONTEXT_ID;
150 }
151 uint64_t contextId = BAD_CONTEXT_ID;
152 IpcAuthParamInner ipcAuthParam = {};
153 IpcWidgetParamInner ipcWidgetParam = {};
154 InitIpcAuthParam(authParam, ipcAuthParam);
155 InitIpcWidgetParam(widgetParam, ipcWidgetParam);
156 auto ret = proxy->AuthWidget(apiVersion, ipcAuthParam, ipcWidgetParam, wrapper, wrapperModal, contextId);
157 if (ret != SUCCESS) {
158 IAM_LOGE("AuthWidget fail, ret:%{public}d", ret);
159 return BAD_CONTEXT_ID;
160 }
161 return contextId;
162 }
163
CancelAuthentication(uint64_t contextId,int32_t cancelReason)164 int32_t UserAuthNapiClientImpl::CancelAuthentication(uint64_t contextId, int32_t cancelReason)
165 {
166 IAM_LOGI("start");
167 auto proxy = GetProxy();
168 if (!proxy) {
169 IAM_LOGE("proxy is nullptr");
170 return GENERAL_ERROR;
171 }
172
173 return proxy->CancelAuthOrIdentify(contextId, cancelReason);
174 }
175
InitIpcAuthParam(const AuthParamInner & authParam,IpcAuthParamInner & ipcAuthParamInner)176 void UserAuthNapiClientImpl::InitIpcAuthParam(const AuthParamInner &authParam,
177 IpcAuthParamInner &ipcAuthParamInner)
178 {
179 ipcAuthParamInner.userId = authParam.userId;
180 ipcAuthParamInner.isUserIdSpecified = authParam.isUserIdSpecified;
181 ipcAuthParamInner.challenge = authParam.challenge;
182 ipcAuthParamInner.authType = static_cast<int32_t>(authParam.authType);
183 ipcAuthParamInner.authTypes.resize(authParam.authTypes.size());
184 std::transform(authParam.authTypes.begin(), authParam.authTypes.end(),
185 ipcAuthParamInner.authTypes.begin(), [](AuthType authType) {
186 return static_cast<int32_t>(authType);
187 });
188 ipcAuthParamInner.authTrustLevel = static_cast<int32_t>(authParam.authTrustLevel);
189 ipcAuthParamInner.authIntent = static_cast<int32_t>(authParam.authIntent);
190 ipcAuthParamInner.skipLockedBiometricAuth = authParam.skipLockedBiometricAuth;
191 ipcAuthParamInner.reuseUnlockResult.isReuse = authParam.reuseUnlockResult.isReuse;
192 ipcAuthParamInner.reuseUnlockResult.reuseMode = authParam.reuseUnlockResult.reuseMode;
193 ipcAuthParamInner.reuseUnlockResult.reuseDuration = authParam.reuseUnlockResult.reuseDuration;
194 }
195
InitIpcWidgetParam(const WidgetParamInner & widgetParam,IpcWidgetParamInner & ipcWidgetParamInner)196 void UserAuthNapiClientImpl::InitIpcWidgetParam(const WidgetParamInner &widgetParam,
197 IpcWidgetParamInner &ipcWidgetParamInner)
198 {
199 ipcWidgetParamInner.title = widgetParam.title;
200 ipcWidgetParamInner.navigationButtonText = widgetParam.navigationButtonText;
201 ipcWidgetParamInner.windowMode = static_cast<int32_t>(widgetParam.windowMode);
202 ipcWidgetParamInner.hasContext = widgetParam.hasContext;
203 }
204 } // namespace UserAuth
205 } // namespace UserIam
206 } // namespace OHOS
207