1 /*
2 * Copyright (c) 2022-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 */
15
16 #include "user_auth_callback_v9.h"
17
18 #include <optional>
19 #include <uv.h>
20
21 #include "napi/native_node_api.h"
22
23 #include "iam_logger.h"
24 #include "iam_ptr.h"
25
26 #define LOG_TAG "USER_AUTH_NAPI"
27
28 namespace OHOS {
29 namespace UserIam {
30 namespace UserAuth {
31 namespace {
32 struct ResultCallbackV9Holder {
33 std::shared_ptr<UserAuthCallbackV9> callback {nullptr};
34 int32_t result {0};
35 std::vector<uint8_t> token {};
36 std::optional<int32_t> remainTimes {std::nullopt};
37 std::optional<int32_t> freezingTime {std::nullopt};
38 napi_env env;
39 };
40
41 struct AcquireCallbackV9Holder {
42 std::shared_ptr<UserAuthCallbackV9> callback {nullptr};
43 int32_t module {0};
44 uint32_t acquireInfo {0};
45 napi_env env;
46 };
47 }
48
UserAuthCallbackV9(napi_env env)49 UserAuthCallbackV9::UserAuthCallbackV9(napi_env env) : env_(env)
50 {
51 if (env_ == nullptr) {
52 IAM_LOGE("UserAuthCallbackV9 get null env");
53 }
54 }
55
~UserAuthCallbackV9()56 UserAuthCallbackV9::~UserAuthCallbackV9()
57 {
58 }
59
SetResultCallback(const std::shared_ptr<JsRefHolder> & resultCallback)60 void UserAuthCallbackV9::SetResultCallback(const std::shared_ptr<JsRefHolder> &resultCallback)
61 {
62 std::lock_guard<std::mutex> guard(mutex_);
63 resultCallback_ = resultCallback;
64 }
65
ClearResultCallback()66 void UserAuthCallbackV9::ClearResultCallback()
67 {
68 std::lock_guard<std::mutex> guard(mutex_);
69 resultCallback_ = nullptr;
70 }
71
SetAcquireCallback(const std::shared_ptr<JsRefHolder> & acquireCallback)72 void UserAuthCallbackV9::SetAcquireCallback(const std::shared_ptr<JsRefHolder> &acquireCallback)
73 {
74 std::lock_guard<std::mutex> guard(mutex_);
75 acquireCallback_ = acquireCallback;
76 }
77
ClearAcquireCallback()78 void UserAuthCallbackV9::ClearAcquireCallback()
79 {
80 std::lock_guard<std::mutex> guard(mutex_);
81 acquireCallback_ = nullptr;
82 }
83
GetResultCallback()84 std::shared_ptr<JsRefHolder> UserAuthCallbackV9::GetResultCallback()
85 {
86 std::lock_guard<std::mutex> guard(mutex_);
87 return resultCallback_;
88 }
89
GetAcquireCallback()90 std::shared_ptr<JsRefHolder> UserAuthCallbackV9::GetAcquireCallback()
91 {
92 std::lock_guard<std::mutex> guard(mutex_);
93 return acquireCallback_;
94 }
95
DoResultCallback(int32_t result,const std::vector<uint8_t> & token,std::optional<int32_t> & remainTimes,std::optional<int32_t> & freezingTime)96 napi_status UserAuthCallbackV9::DoResultCallback(int32_t result, const std::vector<uint8_t> &token,
97 std::optional<int32_t> &remainTimes, std::optional<int32_t> &freezingTime)
98 {
99 auto resultCallback = GetResultCallback();
100 if (resultCallback == nullptr) {
101 return napi_ok;
102 }
103 IAM_LOGI("start");
104 napi_value eventInfo;
105 napi_status ret = napi_create_object(env_, &eventInfo);
106 if (ret != napi_ok) {
107 IAM_LOGE("napi_create_object failed %{public}d", ret);
108 return ret;
109 }
110 ret = UserAuthNapiHelper::SetInt32Property(env_, eventInfo, "result", result);
111 if (ret != napi_ok) {
112 IAM_LOGE("napi_create_int32 failed %{public}d", ret);
113 return ret;
114 }
115 ret = UserAuthNapiHelper::SetUint8ArrayProperty(env_, eventInfo, "token", token);
116 if (ret != napi_ok) {
117 IAM_LOGE("SetUint8ArrayProperty failed %{public}d", ret);
118 return ret;
119 }
120
121 if (remainTimes.has_value()) {
122 ret = UserAuthNapiHelper::SetInt32Property(env_, eventInfo, "remainAttempts", remainTimes.value());
123 if (ret != napi_ok) {
124 IAM_LOGE("SetInt32Property failed %{public}d", ret);
125 return ret;
126 }
127 }
128
129 if (freezingTime.has_value()) {
130 ret = UserAuthNapiHelper::SetInt32Property(env_, eventInfo, "lockoutDuration", freezingTime.value());
131 if (ret != napi_ok) {
132 IAM_LOGE("SetInt32Property failed %{public}d", ret);
133 return ret;
134 }
135 }
136
137 return UserAuthNapiHelper::CallVoidNapiFunc(env_, resultCallback->Get(), ARGS_ONE, &eventInfo);
138 }
139
DoAcquireCallback(int32_t module,uint32_t acquireInfo)140 napi_status UserAuthCallbackV9::DoAcquireCallback(int32_t module, uint32_t acquireInfo)
141 {
142 auto acquireCallback = GetAcquireCallback();
143 if (acquireCallback == nullptr) {
144 return napi_ok;
145 }
146 IAM_LOGI("start");
147 napi_value eventInfo;
148 napi_status ret = napi_create_object(env_, &eventInfo);
149 if (ret != napi_ok) {
150 IAM_LOGE("napi_create_object failed %{public}d", ret);
151 return ret;
152 }
153 ret = UserAuthNapiHelper::SetInt32Property(env_, eventInfo, "module", module);
154 if (ret != napi_ok) {
155 IAM_LOGE("napi_create_int32 failed %{public}d", ret);
156 return ret;
157 }
158 ret = UserAuthNapiHelper::SetUint32Property(env_, eventInfo, "tip", acquireInfo);
159 if (ret != napi_ok) {
160 IAM_LOGE("SetUint32Property failed %{public}d", ret);
161 return ret;
162 }
163 return UserAuthNapiHelper::CallVoidNapiFunc(env_, acquireCallback->Get(), ARGS_ONE, &eventInfo);
164 }
165
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const UserIam::UserAuth::Attributes & extraInfo)166 void UserAuthCallbackV9::OnAcquireInfo(int32_t module, uint32_t acquireInfo,
167 const UserIam::UserAuth::Attributes &extraInfo)
168 {
169 IAM_LOGI("start module:%{public}d acquireInfo:%{public}u", module, acquireInfo);
170 uv_loop_s *loop = nullptr;
171 napi_status napiStatus = napi_get_uv_event_loop(env_, &loop);
172 if (napiStatus != napi_ok || loop == nullptr) {
173 IAM_LOGE("napi_get_uv_event_loop fail");
174 return;
175 }
176 std::shared_ptr<AcquireCallbackV9Holder> acquireHolder = Common::MakeShared<AcquireCallbackV9Holder>();
177 if (acquireHolder == nullptr) {
178 IAM_LOGE("acquireHolder is null");
179 return;
180 }
181 acquireHolder->callback = shared_from_this();
182 acquireHolder->module = module;
183 acquireHolder->acquireInfo = acquireInfo;
184 acquireHolder->env = env_;
185 auto task = [acquireHolder] () {
186 IAM_LOGI("start");
187 if (acquireHolder == nullptr || acquireHolder->callback == nullptr) {
188 IAM_LOGE("acquireHolder is invalid");
189 return;
190 }
191 napi_handle_scope scope = nullptr;
192 napi_open_handle_scope(acquireHolder->env, &scope);
193 if (scope == nullptr) {
194 IAM_LOGE("scope is invalid");
195 return;
196 }
197 napi_status ret = acquireHolder->callback->DoAcquireCallback(acquireHolder->module, acquireHolder->acquireInfo);
198 if (ret != napi_ok) {
199 IAM_LOGE("DoAcquireCallback fail %{public}d", ret);
200 napi_close_handle_scope(acquireHolder->env, scope);
201 return;
202 }
203 napi_close_handle_scope(acquireHolder->env, scope);
204 };
205 if (napi_status::napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
206 IAM_LOGE("napi_send_event: Failed to SendEvent");
207 }
208 }
209
OnResultV9Work(std::shared_ptr<ResultCallbackV9Holder> resultHolder)210 void OnResultV9Work(std::shared_ptr<ResultCallbackV9Holder> resultHolder)
211 {
212 IAM_LOGI("start");
213 if (resultHolder == nullptr || resultHolder->callback == nullptr) {
214 IAM_LOGE("resultHolder is invalid");
215 return;
216 }
217 napi_handle_scope scope = nullptr;
218 napi_open_handle_scope(resultHolder->env, &scope);
219 if (scope == nullptr) {
220 IAM_LOGE("scope is invalid");
221 return;
222 }
223 napi_status ret = resultHolder->callback->DoResultCallback(resultHolder->result, resultHolder->token,
224 resultHolder->remainTimes, resultHolder->freezingTime);
225 if (ret != napi_ok) {
226 IAM_LOGE("DoResultCallback fail %{public}d", ret);
227 napi_close_handle_scope(resultHolder->env, scope);
228 return;
229 }
230 napi_close_handle_scope(resultHolder->env, scope);
231 }
232
OnResult(int32_t result,const Attributes & extraInfo)233 void UserAuthCallbackV9::OnResult(int32_t result, const Attributes &extraInfo)
234 {
235 IAM_LOGI("start, result:%{public}d", result);
236 uv_loop_s *loop = nullptr;
237 napi_status napiStatus = napi_get_uv_event_loop(env_, &loop);
238 if (napiStatus != napi_ok || loop == nullptr) {
239 IAM_LOGE("napi_get_uv_event_loop fail");
240 return;
241 }
242 std::shared_ptr<ResultCallbackV9Holder> resultHolder = Common::MakeShared<ResultCallbackV9Holder>();
243 if (resultHolder == nullptr) {
244 IAM_LOGE("resultHolder is null");
245 return;
246 }
247 resultHolder->callback = shared_from_this();
248 resultHolder->result = UserAuthNapiHelper::GetResultCodeV9(result);
249 resultHolder->env = env_;
250 if (!extraInfo.GetUint8ArrayValue(Attributes::ATTR_SIGNATURE, resultHolder->token)) {
251 IAM_LOGE("ATTR_SIGNATURE is null");
252 }
253
254 int32_t remainTimes = 0;
255 if (extraInfo.GetInt32Value(Attributes::ATTR_REMAIN_TIMES, remainTimes)) {
256 resultHolder->remainTimes = remainTimes;
257 } else {
258 IAM_LOGE("ATTR_REMAIN_TIMES is null");
259 }
260
261 int32_t freezingTime = INT32_MAX;
262 if (extraInfo.GetInt32Value(Attributes::ATTR_FREEZING_TIME, freezingTime)) {
263 resultHolder->freezingTime = freezingTime;
264 } else {
265 IAM_LOGE("ATTR_FREEZING_TIME is null");
266 }
267 auto task = [resultHolder] () {
268 OnResultV9Work(resultHolder);
269 };
270 if (napi_status::napi_ok != napi_send_event(env_, task, napi_eprio_immediate)) {
271 IAM_LOGE("napi_send_event: Failed to SendEvent");
272 }
273 }
274 } // namespace UserAuth
275 } // namespace UserIam
276 } // namespace OHOS
277