• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_instance_v10.h"
17 
18 #include <algorithm>
19 #include <string>
20 
21 #include "iam_logger.h"
22 #include "iam_ptr.h"
23 
24 #include "user_auth_client_impl.h"
25 
26 #define LOG_LABEL Common::LABEL_USER_AUTH_NAPI
27 
28 namespace OHOS {
29 namespace UserIam {
30 namespace UserAuth {
31 const std::string AUTH_EVENT_RESULT = "result";
32 const std::string AUTH_PARAM_CHALLENGE = "challenge";
33 const std::string AUTH_PARAM_AUTHTYPE = "authType";
34 const std::string AUTH_PARAM_AUTHTRUSTLEVEL = "authTrustLevel";
35 const std::string WIDGET_PARAM_TITLE = "title";
36 const std::string WIDGET_PARAM_NAVIBTNTEXT = "navigationButtonText";
37 const std::string WIDGET_PARAM_WINDOWMODE = "windowMode";
38 const std::string NOTICETYPE = "noticeType";
39 
40 namespace WidgetType {
41     constexpr int32_t TITLE_MAX = 500;
42     constexpr int32_t BUTTON_MAX = 60;
43 }
44 
UserAuthInstanceV10(napi_env env)45 UserAuthInstanceV10::UserAuthInstanceV10(napi_env env) : callback_(Common::MakeShared<UserAuthCallbackV10>(env))
46 {
47     if (callback_ == nullptr) {
48         IAM_LOGE("get null callback");
49     }
50     authParam_.authTrustLevel = AuthTrustLevel::ATL1;
51     widgetParam_.navigationButtonText = "";
52     widgetParam_.title = "";
53     widgetParam_.windowMode = WindowModeType::UNKNOWN_WINDOW_MODE;
54 }
55 
InitChallenge(napi_env env,napi_value value)56 UserAuthResultCode UserAuthInstanceV10::InitChallenge(napi_env env, napi_value value)
57 {
58     authParam_.challenge.clear();
59     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
60     if (ret == napi_ok) {
61         IAM_LOGI("challenge is null");
62         return UserAuthResultCode::OHOS_INVALID_PARAM;
63     }
64     ret = UserAuthNapiHelper::GetUint8ArrayValue(env, value, MAX_CHALLENG_LEN, authParam_.challenge);
65     if (ret != napi_ok) {
66         IAM_LOGE("GetUint8ArrayValue fail:%{public}d", ret);
67         return UserAuthResultCode::OHOS_INVALID_PARAM;
68     }
69     IAM_LOGI("challenge size:%{public}zu", authParam_.challenge.size());
70     return UserAuthResultCode::SUCCESS;
71 }
72 
InitAuthType(napi_env env,napi_value value)73 UserAuthResultCode UserAuthInstanceV10::InitAuthType(napi_env env, napi_value value)
74 {
75     bool isArray = false;
76     napi_is_array(env, value, &isArray);
77     if (!isArray) {
78         IAM_LOGI("authType is not array");
79         return UserAuthResultCode::OHOS_INVALID_PARAM;
80     }
81     uint32_t length = 0;
82     napi_get_array_length(env, value, &length);
83     for (uint32_t i = 0; i < length; ++i) {
84         napi_value jsValue = nullptr;
85         napi_handle_scope scope = nullptr;
86         napi_open_handle_scope(env, &scope);
87         napi_get_element(env, value, i, &jsValue);
88         if (jsValue == nullptr) {
89             napi_close_handle_scope(env, scope);
90             continue;
91         }
92         int32_t value = 0;
93         napi_status ret = UserAuthNapiHelper::GetInt32Value(env, jsValue, value);
94         napi_close_handle_scope(env, scope);
95         if (ret != napi_ok) {
96             IAM_LOGE("napi authType GetUint32Value fail:%{public}d", ret);
97             return UserAuthResultCode::OHOS_INVALID_PARAM;
98         }
99         IAM_LOGI("napi get authType:%{public}d", value);
100         if (!UserAuthNapiHelper::CheckUserAuthType(value)) {
101             IAM_LOGE("authType is illegal, %{public}d", value);
102             return UserAuthResultCode::TYPE_NOT_SUPPORT;
103         }
104         auto iter = std::find(authParam_.authType.begin(), authParam_.authType.end(), static_cast<AuthType>(value));
105         if (iter != authParam_.authType.end()) {
106             IAM_LOGE("napi authType:%{public}d exist", value);
107             return UserAuthResultCode::OHOS_INVALID_PARAM;
108         }
109         authParam_.authType.push_back(static_cast<AuthType>(value));
110     }
111 
112     IAM_LOGI("authType size:%{public}zu", authParam_.authType.size());
113     return UserAuthResultCode::SUCCESS;
114 }
115 
InitAuthParam(napi_env env,napi_value value)116 UserAuthResultCode UserAuthInstanceV10::InitAuthParam(napi_env env, napi_value value)
117 {
118     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
119     if (ret == napi_ok) {
120         IAM_LOGI("authParam is null");
121         return UserAuthResultCode::OHOS_INVALID_PARAM;
122     }
123 
124     if (!UserAuthNapiHelper::HasNamedProperty(env, value, AUTH_PARAM_CHALLENGE)) {
125         IAM_LOGE("propertyName: %{public}s not exists.", AUTH_PARAM_CHALLENGE.c_str());
126         return UserAuthResultCode::OHOS_INVALID_PARAM;
127     }
128     napi_value napi_challenge = UserAuthNapiHelper::GetNamedProperty(env, value, AUTH_PARAM_CHALLENGE);
129     UserAuthResultCode errorCode = InitChallenge(env, napi_challenge);
130     if (errorCode != UserAuthResultCode::SUCCESS) {
131         IAM_LOGE("InitChallenge fail:%{public}d", errorCode);
132         return UserAuthResultCode::OHOS_INVALID_PARAM;
133     }
134 
135     if (!UserAuthNapiHelper::HasNamedProperty(env, value, AUTH_PARAM_AUTHTYPE)) {
136         IAM_LOGE("propertyName: %{public}s not exists.", AUTH_PARAM_AUTHTYPE.c_str());
137         return UserAuthResultCode::OHOS_INVALID_PARAM;
138     }
139     napi_value napi_authType = UserAuthNapiHelper::GetNamedProperty(env, value, AUTH_PARAM_AUTHTYPE);
140     errorCode = InitAuthType(env, napi_authType);
141     if (errorCode != UserAuthResultCode::SUCCESS) {
142         IAM_LOGE("InitAuthType fail:%{public}d", errorCode);
143         return errorCode;
144     }
145 
146     if (!UserAuthNapiHelper::HasNamedProperty(env, value, AUTH_PARAM_AUTHTRUSTLEVEL)) {
147         IAM_LOGE("propertyName: %{public}s not exists.", AUTH_PARAM_AUTHTRUSTLEVEL.c_str());
148         return UserAuthResultCode::OHOS_INVALID_PARAM;
149     }
150 
151     napi_value napi_authTrustLeval = UserAuthNapiHelper::GetNamedProperty(env, value, AUTH_PARAM_AUTHTRUSTLEVEL);
152     uint32_t authTrustLevel;
153     ret = UserAuthNapiHelper::GetUint32Value(env, napi_authTrustLeval, authTrustLevel);
154     if (ret != napi_ok) {
155         IAM_LOGE("GetUint32Value fail:%{public}d", ret);
156         return UserAuthResultCode::OHOS_INVALID_PARAM;
157     }
158     if (!UserAuthNapiHelper::CheckAuthTrustLevel(authTrustLevel)) {
159         IAM_LOGE("AuthTrustLeval fail:%{public}d", errorCode);
160         return UserAuthResultCode::TRUST_LEVEL_NOT_SUPPORT;
161     }
162     authParam_.authTrustLevel = AuthTrustLevel(authTrustLevel);
163 
164     return UserAuthResultCode::SUCCESS;
165 }
166 
InitWidgetParam(napi_env env,napi_value value)167 UserAuthResultCode UserAuthInstanceV10::InitWidgetParam(napi_env env, napi_value value)
168 {
169     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_null);
170     if (ret == napi_ok) {
171         IAM_LOGI("widgetParam is null");
172         return UserAuthResultCode::OHOS_INVALID_PARAM;
173     }
174 
175     if (!UserAuthNapiHelper::HasNamedProperty(env, value, WIDGET_PARAM_TITLE)) {
176         IAM_LOGE("propertyName: %{public}s not exists.", WIDGET_PARAM_TITLE.c_str());
177         return UserAuthResultCode::OHOS_INVALID_PARAM;
178     }
179     std::string title = UserAuthNapiHelper::GetStringPropertyUtf8(env, value, WIDGET_PARAM_TITLE);
180     if (title == "" || title.length() > WidgetType::TITLE_MAX) {
181         IAM_LOGE("title is invalid. size: %{public}zu", title.length());
182         return UserAuthResultCode::OHOS_INVALID_PARAM;
183     }
184     widgetParam_.title = title;
185 
186     if (UserAuthNapiHelper::HasNamedProperty(env, value, WIDGET_PARAM_NAVIBTNTEXT)) {
187         std::string naviBtnTxt = UserAuthNapiHelper::GetStringPropertyUtf8(env, value, WIDGET_PARAM_NAVIBTNTEXT);
188         if (naviBtnTxt == "" || naviBtnTxt.length() > WidgetType::BUTTON_MAX) {
189             IAM_LOGE("navigation button text is invalid, size: %{public}zu", naviBtnTxt.length());
190             return UserAuthResultCode::OHOS_INVALID_PARAM;
191         }
192         widgetParam_.navigationButtonText = naviBtnTxt;
193     }
194 
195     if (UserAuthNapiHelper::HasNamedProperty(env, value, WIDGET_PARAM_WINDOWMODE)) {
196         napi_value napi_windowModeType = UserAuthNapiHelper::GetNamedProperty(env, value, WIDGET_PARAM_WINDOWMODE);
197         uint32_t windowMode;
198         ret = UserAuthNapiHelper::GetUint32Value(env, napi_windowModeType, windowMode);
199         if (ret != napi_ok) {
200             IAM_LOGE("napi authType GetUint32Value fail:%{public}d", ret);
201             return UserAuthResultCode::OHOS_INVALID_PARAM;
202         }
203         switch (windowMode) {
204             case WindowModeType::DIALOG_BOX:
205             case WindowModeType::FULLSCREEN:
206                 widgetParam_.windowMode = static_cast<WindowModeType>(windowMode);
207                 break;
208             default:
209                 IAM_LOGE("windowMode type not support.");
210                 return UserAuthResultCode::OHOS_INVALID_PARAM;
211         }
212     }
213 
214     IAM_LOGI("widgetParam title:%{public}s, navBtnText:%{public}s, winMode:%{public}u",
215         widgetParam_.title.c_str(), widgetParam_.navigationButtonText.c_str(),
216         static_cast<uint32_t>(widgetParam_.windowMode));
217     return UserAuthResultCode::SUCCESS;
218 }
219 
Init(napi_env env,napi_callback_info info)220 UserAuthResultCode UserAuthInstanceV10::Init(napi_env env, napi_callback_info info)
221 {
222     if (callback_ == nullptr) {
223         IAM_LOGE("callback is null");
224         return UserAuthResultCode::GENERAL_ERROR;
225     }
226     napi_value argv[ARGS_TWO];
227     size_t argc = ARGS_TWO;
228     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
229     if (ret != napi_ok) {
230         IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
231         return UserAuthResultCode::GENERAL_ERROR;
232     }
233     if (argc != ARGS_TWO) {
234         IAM_LOGE("invalid param, argc:%{public}zu", argc);
235         return UserAuthResultCode::OHOS_INVALID_PARAM;
236     }
237 
238     UserAuthResultCode errCode = InitAuthParam(env, argv[PARAM0]);
239     if (errCode != UserAuthResultCode::SUCCESS) {
240         IAM_LOGE("AuthParam type error, errorCode: %{public}d", errCode);
241         return errCode;
242     }
243 
244     errCode = InitWidgetParam(env, argv[PARAM1]);
245     if (errCode != UserAuthResultCode::SUCCESS) {
246         IAM_LOGE("WidgetParam type error, errorCode: %{public}d", errCode);
247         return errCode;
248     }
249 
250     IAM_LOGE("Init SUCCESS");
251     return UserAuthResultCode::SUCCESS;
252 }
253 
GetCallback(napi_env env,napi_value value)254 std::shared_ptr<JsRefHolder> UserAuthInstanceV10::GetCallback(napi_env env, napi_value value)
255 {
256     napi_status ret = UserAuthNapiHelper::CheckNapiType(env, value, napi_object);
257     if (ret != napi_ok) {
258         IAM_LOGE("CheckNapiType fail:%{public}d", ret);
259         return nullptr;
260     }
261     napi_value callbackValue;
262     ret = napi_get_named_property(env, value, "onResult", &callbackValue);
263     if (ret != napi_ok) {
264         IAM_LOGE("napi_get_named_property fail:%{public}d", ret);
265         return nullptr;
266     }
267     return Common::MakeShared<JsRefHolder>(env, callbackValue);
268 }
269 
On(napi_env env,napi_callback_info info)270 UserAuthResultCode UserAuthInstanceV10::On(napi_env env, napi_callback_info info)
271 {
272     if (callback_ == nullptr) {
273         IAM_LOGE("getAuthInstance on callback is null");
274         return UserAuthResultCode::GENERAL_ERROR;
275     }
276     napi_value argv[ARGS_TWO];
277     size_t argc = ARGS_TWO;
278     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
279     if (ret != napi_ok) {
280         IAM_LOGE("getAuthInstance on napi_get_cb_info fail:%{public}d", ret);
281         return UserAuthResultCode::GENERAL_ERROR;
282     }
283     if (argc != ARGS_TWO) {
284         IAM_LOGE("getAuthInstance on invalid param, argc:%{public}zu", argc);
285         return UserAuthResultCode::OHOS_INVALID_PARAM;
286     }
287     static const size_t maxLen = 10;
288     char str[maxLen] = {0};
289     size_t len = maxLen;
290     ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
291     if (ret != napi_ok) {
292         IAM_LOGE("getAuthInstance on GetStrValue fail:%{public}d", ret);
293         return UserAuthResultCode::OHOS_INVALID_PARAM;
294     }
295     auto callbackRef = GetCallback(env, argv[PARAM1]);
296     if (callbackRef == nullptr || !callbackRef->IsValid()) {
297         IAM_LOGE("getAuthInstance on GetCallback fail");
298         return UserAuthResultCode::OHOS_INVALID_PARAM;
299     }
300     if (str == AUTH_EVENT_RESULT) {
301         IAM_LOGI("getAuthInstance on SetResultCallback");
302         if (callback_->HasResultCallback()) {
303             IAM_LOGE("callback has been registerred");
304             return UserAuthResultCode::GENERAL_ERROR;
305         }
306         callback_->SetResultCallback(callbackRef);
307         return UserAuthResultCode::SUCCESS;
308     } else {
309         IAM_LOGE("getAuthInstance on invalid event:%{public}s", str);
310         return UserAuthResultCode::OHOS_INVALID_PARAM;
311     }
312 }
313 
Off(napi_env env,napi_callback_info info)314 UserAuthResultCode UserAuthInstanceV10::Off(napi_env env, napi_callback_info info)
315 {
316     if (callback_ == nullptr) {
317         IAM_LOGE("userAuthInstance off callback is null");
318         return UserAuthResultCode::GENERAL_ERROR;
319     }
320     napi_value argv[ARGS_TWO];
321     size_t argc = ARGS_TWO;
322     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
323     if (ret != napi_ok) {
324         IAM_LOGE("userAuthInstance off napi_get_cb_info fail:%{public}d", ret);
325         return UserAuthResultCode::GENERAL_ERROR;
326     }
327     if (argc != ARGS_TWO && argc != ARGS_ONE) {
328         IAM_LOGE("userAuthInstance off invalid param, argc:%{public}zu", argc);
329         return UserAuthResultCode::OHOS_INVALID_PARAM;
330     }
331     static const size_t maxLen = 10;
332     char str[maxLen] = {0};
333     size_t len = maxLen;
334     ret = UserAuthNapiHelper::GetStrValue(env, argv[PARAM0], str, len);
335     if (ret != napi_ok) {
336         IAM_LOGE("UserAuthResultCode off GetStrValue fail:%{public}d", ret);
337         return UserAuthResultCode::OHOS_INVALID_PARAM;
338     }
339 
340     if (argc == ARGS_TWO) {
341         auto callbackRef = GetCallback(env, argv[PARAM1]);
342         if (callbackRef == nullptr || !callbackRef->IsValid()) {
343             IAM_LOGE("GetCallback fail");
344             return UserAuthResultCode::OHOS_INVALID_PARAM;
345         }
346     }
347 
348     if (str == AUTH_EVENT_RESULT) {
349         if (!callback_->HasResultCallback()) {
350             IAM_LOGE("no callback registerred yet");
351             return UserAuthResultCode::GENERAL_ERROR;
352         }
353         callback_->ClearResultCallback();
354         IAM_LOGI("UserAuthResultCode off clear result callback");
355         return UserAuthResultCode::SUCCESS;
356     } else {
357         IAM_LOGE("invalid event:%{public}s", str);
358         return UserAuthResultCode::OHOS_INVALID_PARAM;
359     }
360 }
361 
Start(napi_env env,napi_callback_info info)362 UserAuthResultCode UserAuthInstanceV10::Start(napi_env env, napi_callback_info info)
363 {
364     if (callback_ == nullptr) {
365         IAM_LOGE("callback is null");
366         return UserAuthResultCode::GENERAL_ERROR;
367     }
368     napi_value argv[ARGS_ONE];
369     size_t argc = ARGS_ONE;
370     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
371     if (ret != napi_ok) {
372         IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
373         return UserAuthResultCode::GENERAL_ERROR;
374     }
375     if (argc != ARGS_ZERO) {
376         IAM_LOGE("invalid param, argc:%{public}zu", argc);
377         return UserAuthResultCode::OHOS_INVALID_PARAM;
378     }
379     std::lock_guard<std::mutex> guard(mutex_);
380     if (isAuthStarted_) {
381         IAM_LOGE("auth already started");
382         return UserAuthResultCode::GENERAL_ERROR;
383     }
384     contextId_ = UserAuthClientImpl::Instance().BeginWidgetAuth(API_VERSION_10,
385         authParam_, widgetParam_, callback_);
386     isAuthStarted_ = true;
387     return UserAuthResultCode::SUCCESS;
388 }
389 
Cancel(napi_env env,napi_callback_info info)390 UserAuthResultCode UserAuthInstanceV10::Cancel(napi_env env, napi_callback_info info)
391 {
392     if (callback_ == nullptr) {
393         IAM_LOGE("callback is null");
394         return UserAuthResultCode::GENERAL_ERROR;
395     }
396     napi_value argv[ARGS_ONE];
397     size_t argc = ARGS_ONE;
398     napi_status ret = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
399     if (ret != napi_ok) {
400         IAM_LOGE("napi_get_cb_info fail:%{public}d", ret);
401         return UserAuthResultCode::GENERAL_ERROR;
402     }
403     if (argc != ARGS_ZERO) {
404         IAM_LOGE("invalid param, argc:%{public}zu", argc);
405         return UserAuthResultCode::OHOS_INVALID_PARAM;
406     }
407     std::lock_guard<std::mutex> guard(mutex_);
408     if (!isAuthStarted_) {
409         IAM_LOGE("auth not started");
410         return UserAuthResultCode::GENERAL_ERROR;
411     }
412     int32_t result = UserAuthClient::GetInstance().CancelAuthentication(contextId_);
413     if (result != ResultCode::SUCCESS) {
414         IAM_LOGE("CancelAuthentication fail:%{public}d", result);
415         return UserAuthResultCode(UserAuthNapiHelper::GetResultCodeV10(result));
416     }
417     isAuthStarted_ = false;
418     return UserAuthResultCode::SUCCESS;
419 }
420 } // namespace UserAuth
421 } // namespace UserIam
422 } // namespace OHOS
423