• 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 "widget_client.h"
17 
18 #include "system_ability_definition.h"
19 
20 #include "auth_common.h"
21 #include "iam_check.h"
22 #include "iam_logger.h"
23 #include "iam_para2str.h"
24 #include "iam_time.h"
25 #include "nlohmann/json.hpp"
26 #include "widget_callback_interface.h"
27 #include "hisysevent_adapter.h"
28 
29 #define LOG_TAG "USER_AUTH_SA"
30 
31 namespace OHOS {
32 namespace UserIam {
33 namespace UserAuth {
34 
35 const std::string PIN_SUB_TYPE_SIX = "PIN_SIX";
36 const std::string PIN_SUB_TYPE_NUMBER = "PIN_NUMBER";
37 const std::string PIN_SUB_TYPE_MIXED = "PIN_MIXED";
38 const std::string PIN_SUB_TYPE_FOUR = "PIN_FOUR";
39 const std::string PIN_SUB_TYPE_PATTERN = "PIN_PATTERN";
40 const std::string PIN_SUB_TYPE_MAX = "PIN_MAX";
41 
Instance()42 WidgetClient &WidgetClient::Instance()
43 {
44     static WidgetClient widgetClient;
45     return widgetClient;
46 }
47 
SetWidgetSchedule(const std::shared_ptr<WidgetScheduleNode> & schedule)48 void WidgetClient::SetWidgetSchedule(const std::shared_ptr<WidgetScheduleNode> &schedule)
49 {
50     IF_FALSE_LOGE_AND_RETURN(schedule != nullptr);
51     schedule_ = schedule;
52 }
53 
OnNotice(NoticeType type,const std::string & eventData)54 ResultCode WidgetClient::OnNotice(NoticeType type, const std::string &eventData)
55 {
56     // handle notice from widget
57     if (type != WIDGET_NOTICE) {
58         IAM_LOGE("Invalid notice type");
59         return ResultCode::INVALID_PARAMETERS;
60     }
61     if (eventData.empty()) {
62         IAM_LOGE("Invalid notice event data");
63         return ResultCode::INVALID_PARAMETERS;
64     }
65     IAM_LOGI("recv notice eventData: %{public}s", eventData.c_str());
66     auto root = nlohmann::json::parse(eventData.c_str(), nullptr, false);
67     if (root.is_null() || root.is_discarded()) {
68         IAM_LOGE("OnNotice eventData is not json format");
69         return ResultCode::INVALID_PARAMETERS;
70     }
71     WidgetNotice notice = root.get<WidgetNotice>();
72     if (notice.widgetContextId == 0) {
73         IAM_LOGE("Invalid widget context id");
74         return ResultCode::INVALID_PARAMETERS;
75     }
76     if (!IsValidNoticeType(notice)) {
77         IAM_LOGE("Not support notice event");
78         return ResultCode::INVALID_PARAMETERS;
79     }
80     if (schedule_ == nullptr) {
81         IAM_LOGE("Invalid schedule node, report auth false");
82         return ResultCode::GENERAL_ERROR;
83     }
84     std::vector<AuthType> authTypeList = {};
85     if (!GetAuthTypeList(notice, authTypeList)) {
86         IAM_LOGE("Invalid auth type list");
87         return ResultCode::INVALID_PARAMETERS;
88     }
89     ProcessNotice(notice, authTypeList);
90     return ResultCode::SUCCESS;
91 }
92 
ProcessNotice(const WidgetNotice & notice,std::vector<AuthType> & authTypeList)93 void WidgetClient::ProcessNotice(const WidgetNotice &notice, std::vector<AuthType> &authTypeList)
94 {
95     if (notice.event == NOTICE_EVENT_AUTH_READY) {
96         schedule_->StartAuthList(authTypeList, notice.endAfterFirstFail, notice.authIntent);
97     } else if (notice.event == NOTICE_EVENT_CANCEL_AUTH) {
98         if (notice.widgetContextId != widgetContextId_) {
99             IAM_LOGE("Invalid widgetContextId ****%{public}hx", static_cast<uint16_t>(widgetContextId_));
100             return;
101         }
102         if (authTypeList.size() == 1 && authTypeList[0] == AuthType::ALL) {
103             schedule_->StopSchedule();
104         } else {
105             schedule_->StopAuthList(authTypeList);
106         }
107     } else if (notice.event == NOTICE_EVENT_USER_NAVIGATION) {
108         schedule_->NaviPinAuth();
109     } else if (notice.event == NOTICE_EVENT_WIDGET_PARA_INVALID) {
110         schedule_->WidgetParaInvalid();
111     } else if (notice.event == NOTICE_EVENT_END) {
112         schedule_->StopAuthList(authTypeList);
113     } else if (notice.event == NOTICE_EVENT_RELOAD) {
114         if ((authTypeList.size() == 1 && authTypeList[0] == AuthType::ALL) || authTypeList.size() != 1) {
115             schedule_->WidgetParaInvalid();
116         } else {
117             schedule_->WidgetReload(notice.orientation, notice.needRotate, notice.alreadyLoad, authTypeList[0]);
118         }
119     }
120 }
121 
SendCommand(const WidgetCommand & command)122 void WidgetClient::SendCommand(const WidgetCommand &command)
123 {
124     if (widgetCallback_ == nullptr) {
125         IAM_LOGE("SendCommand widget callback is null");
126         return;
127     }
128     nlohmann::json root = command;
129     std::string cmdData = root.dump();
130     IAM_LOGI("SendCommand cmdData");
131     widgetCallback_->SendCommand(cmdData);
132 }
133 
ReportWidgetResult(int32_t result,AuthType authType,int32_t lockoutDuration,int32_t remainAttempts)134 void WidgetClient::ReportWidgetResult(int32_t result, AuthType authType,
135     int32_t lockoutDuration, int32_t remainAttempts)
136 {
137     WidgetCommand::ExtraInfo extraInfo {
138         .callingBundleName = callingBundleName_,
139         .challenge = challenge_
140     };
141     // sendCommand of CMD_NOTIFY_AUTH_RESULT
142     WidgetCommand::Cmd cmd {
143         .event = CMD_NOTIFY_AUTH_RESULT,
144         .version = NOTICE_VERSION_STR,
145         .type = AuthType2Str(authType),
146         .result = result,
147         .lockoutDuration = lockoutDuration,
148         .remainAttempts = remainAttempts,
149         .extraInfo = extraInfo
150     };
151     if (authType == AuthType::FINGERPRINT && !sensorInfo_.empty()) {
152         cmd.sensorInfo = sensorInfo_;
153     }
154     WidgetCommand widgetCmd {
155         .widgetContextId = widgetContextId_,
156         .title = widgetParam_.title,
157         .windowModeType = WinModeType2Str(widgetParam_.windowMode),
158         .navigationButtonText = widgetParam_.navigationButtonText,
159         .cmdList = { cmd }
160     };
161     for (auto &type : authTypeList_) {
162         widgetCmd.typeList.emplace_back(AuthType2Str(type));
163     }
164     if (!pinSubType_.empty()) {
165         widgetCmd.pinSubType = pinSubType_;
166     }
167     SendCommand(widgetCmd);
168 }
169 
ReportWidgetTip(int32_t tipType,AuthType authType,std::vector<uint8_t> tipInfo)170 void WidgetClient::ReportWidgetTip(int32_t tipType, AuthType authType, std::vector<uint8_t> tipInfo)
171 {
172     // sendCommand of CMD_NOTIFY_AUTH_TIP
173     WidgetCommand::Cmd cmd {
174         .event = CMD_NOTIFY_AUTH_TIP,
175         .version = NOTICE_VERSION_STR,
176         .type = AuthType2Str(authType),
177         .tipType = tipType,
178         .tipInfo = tipInfo
179     };
180     WidgetCommand widgetCmd {
181         .widgetContextId = widgetContextId_,
182         .cmdList = { cmd }
183     };
184     SendCommand(widgetCmd);
185 }
186 
SetWidgetContextId(uint64_t contextId)187 void WidgetClient::SetWidgetContextId(uint64_t contextId)
188 {
189     widgetContextId_ = contextId;
190 }
191 
SetWidgetParam(const WidgetParamInner & param)192 void WidgetClient::SetWidgetParam(const WidgetParamInner &param)
193 {
194     widgetParam_ = param;
195 }
196 
SetAuthTypeList(const std::vector<AuthType> & authTypeList)197 void WidgetClient::SetAuthTypeList(const std::vector<AuthType> &authTypeList)
198 {
199     authTypeList_ = authTypeList;
200 }
201 
SetWidgetCallback(const sptr<WidgetCallbackInterface> & callback)202 void WidgetClient::SetWidgetCallback(const sptr<WidgetCallbackInterface> &callback)
203 {
204     widgetCallback_ = callback;
205 }
206 
SetAuthTokenId(uint32_t tokenId)207 void WidgetClient::SetAuthTokenId(uint32_t tokenId)
208 {
209     authTokenId_ = tokenId;
210     IAM_LOGI("WidgetClient SetAuthTokenId authTokenId: %{public}s", GET_MASKED_STRING(authTokenId_).c_str());
211 }
212 
GetAuthTokenId() const213 uint32_t WidgetClient::GetAuthTokenId() const
214 {
215     return authTokenId_;
216 }
217 
Reset()218 void WidgetClient::Reset()
219 {
220     IAM_LOGI("WidgetClient Reset");
221     widgetParam_.title.clear();
222     widgetParam_.navigationButtonText.clear();
223     widgetParam_.windowMode = WindowModeType::DIALOG_BOX;
224     widgetContextId_ = 0;
225     authTokenId_ = 0;
226     schedule_ = nullptr;
227     widgetCallback_ = nullptr;
228     pinSubType_.clear();
229     sensorInfo_.clear();
230     modalCallback_ = nullptr;
231 }
232 
ForceStopAuth()233 void WidgetClient::ForceStopAuth()
234 {
235     IAM_LOGE("stop auth process forcely by disconnect");
236     if (widgetContextId_ != 0) {
237         IAM_LOGE("widget context id hasn't been reset");
238         UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), "AuthWidget");
239     }
240     if (schedule_ != nullptr) {
241         schedule_->StopSchedule();
242     }
243 }
244 
CancelAuth()245 void WidgetClient::CancelAuth()
246 {
247     IAM_LOGE("cancel auth process forcely");
248     if (schedule_ != nullptr) {
249         schedule_->StopSchedule();
250     }
251 }
252 
SetPinSubType(const PinSubType & subType)253 void WidgetClient::SetPinSubType(const PinSubType &subType)
254 {
255     pinSubType_ = PIN_SUB_TYPE_SIX;
256     switch (subType) {
257         case PinSubType::PIN_NUMBER:
258             pinSubType_ = PIN_SUB_TYPE_NUMBER;
259             break;
260         case PinSubType::PIN_MIXED:
261             pinSubType_ = PIN_SUB_TYPE_MIXED;
262             break;
263         case PinSubType::PIN_MAX:
264             pinSubType_ = PIN_SUB_TYPE_MAX;
265             break;
266         case PinSubType::PIN_FOUR:
267             pinSubType_ = PIN_SUB_TYPE_FOUR;
268             break;
269         case PinSubType::PIN_PATTERN:
270             pinSubType_ = PIN_SUB_TYPE_PATTERN;
271             break;
272         default:
273             break;
274     }
275 }
276 
SetSensorInfo(const std::string & info)277 void WidgetClient::SetSensorInfo(const std::string &info)
278 {
279     sensorInfo_ = info;
280 }
281 
GetAuthTypeList(const WidgetNotice & notice,std::vector<AuthType> & authTypeList)282 bool WidgetClient::GetAuthTypeList(const WidgetNotice &notice, std::vector<AuthType> &authTypeList)
283 {
284     if (authTypeList_.empty()) {
285         IAM_LOGE("inner auth type list is empty");
286         return false;
287     }
288     std::vector<AuthType> tempList = notice.AuthTypeList();
289     if (tempList.empty()) {
290         IAM_LOGE("auth type list is empty");
291         return false;
292     }
293     if (tempList.size() == 1 && tempList[0] == AuthType::ALL) {
294         if (notice.event != NOTICE_EVENT_CANCEL_AUTH) {
295             IAM_LOGE("invalid type all case event type: %{public}s", notice.event.c_str());
296             return false;
297         }
298         authTypeList.emplace_back(AuthType::ALL);
299         return true;
300     }
301     for (auto &type : tempList) {
302         if (std::find(authTypeList_.begin(), authTypeList_.end(), type) == authTypeList_.end()) {
303             IAM_LOGE("invalid auth type: %{public}d", type);
304             return false;
305         }
306         authTypeList.emplace_back(type);
307     }
308     if (authTypeList.size() == authTypeList_.size() && notice.event == NOTICE_EVENT_CANCEL_AUTH) {
309         authTypeList.clear();
310         authTypeList.emplace_back(AuthType::ALL);
311     }
312     return true;
313 }
314 
IsValidNoticeType(const WidgetNotice & notice)315 bool WidgetClient::IsValidNoticeType(const WidgetNotice &notice)
316 {
317     if (notice.event != NOTICE_EVENT_AUTH_READY &&
318         notice.event != NOTICE_EVENT_CANCEL_AUTH &&
319         notice.event != NOTICE_EVENT_USER_NAVIGATION &&
320         notice.event != NOTICE_EVENT_WIDGET_PARA_INVALID &&
321         notice.event != NOTICE_EVENT_RELOAD &&
322         notice.event != NOTICE_EVENT_END) {
323         return false;
324     }
325     return true;
326 }
327 
SetChallenge(const std::vector<uint8_t> & challenge)328 void WidgetClient::SetChallenge(const std::vector<uint8_t> &challenge)
329 {
330     challenge_ = challenge;
331 }
332 
SetCallingBundleName(const std::string & callingBundleName)333 void WidgetClient::SetCallingBundleName(const std::string &callingBundleName)
334 {
335     callingBundleName_ = callingBundleName;
336 }
337 
SetModalCallback(const sptr<ModalCallbackInterface> & callback)338 void WidgetClient::SetModalCallback(const sptr<ModalCallbackInterface> &callback)
339 {
340     IAM_LOGI("set modal callback");
341     modalCallback_ = callback;
342 }
343 
LaunchModal(const std::string & commandData)344 void WidgetClient::LaunchModal(const std::string &commandData)
345 {
346     IAM_LOGI("launch modal command: %{public}s", commandData.c_str());
347     if (modalCallback_ != nullptr) {
348         modalCallback_->SendCommand(widgetContextId_, commandData);
349     }
350 }
351 
ReleaseModal()352 void WidgetClient::ReleaseModal()
353 {
354     IAM_LOGI("release modal");
355     if (modalCallback_ != nullptr) {
356         std::string cmdData = "";
357         modalCallback_->SendCommand(widgetContextId_, cmdData);
358     }
359 }
360 } // namespace UserAuth
361 } // namespace UserIam
362 } // namespace OHOS