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 ¬ice, 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 ¶m)
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 ¬ice, 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 ¬ice)
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