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_time.h"
24 #include "nlohmann/json.hpp"
25 #include "widget_callback_interface.h"
26 #include "hisysevent_adapter.h"
27
28 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace UserAuth {
33
34 const std::string PIN_SUB_TYPE_SIX = "PIN_SIX";
35 const std::string PIN_SUB_TYPE_NUMBER = "PIN_NUMBER";
36 const std::string PIN_SUB_TYPE_MIXED = "PIN_MIXED";
37 const std::string PIN_SUB_TYPE_MAX = "PIN_MAX";
38
Instance()39 WidgetClient &WidgetClient::Instance()
40 {
41 static WidgetClient widgetClient;
42 return widgetClient;
43 }
44
SetWidgetSchedule(const std::shared_ptr<WidgetScheduleNode> & schedule)45 void WidgetClient::SetWidgetSchedule(const std::shared_ptr<WidgetScheduleNode> &schedule)
46 {
47 IF_FALSE_LOGE_AND_RETURN(schedule != nullptr);
48 schedule_ = schedule;
49 }
50
OnNotice(NoticeType type,const std::string & eventData)51 ResultCode WidgetClient::OnNotice(NoticeType type, const std::string &eventData)
52 {
53 // handle notice from widget
54 if (type != WIDGET_NOTICE) {
55 IAM_LOGE("Invalid notice type");
56 return ResultCode::INVALID_PARAMETERS;
57 }
58 if (eventData.empty()) {
59 IAM_LOGE("Invalid notice event data");
60 return ResultCode::INVALID_PARAMETERS;
61 }
62 IAM_LOGI("recv notice eventData: %{public}s", eventData.c_str());
63 auto root = nlohmann::json::parse(eventData.c_str(), nullptr, false);
64 if (root.is_null() || root.is_discarded()) {
65 IAM_LOGE("OnNotice eventData is not json format");
66 return ResultCode::INVALID_PARAMETERS;
67 }
68 WidgetNotice notice = root.get<WidgetNotice>();
69 if (notice.widgetContextId == 0) {
70 IAM_LOGE("Invalid widget context id");
71 return ResultCode::INVALID_PARAMETERS;
72 }
73 if (!IsValidNoticeType(notice)) {
74 IAM_LOGE("Not support notice event");
75 return ResultCode::INVALID_PARAMETERS;
76 }
77 if (schedule_ == nullptr) {
78 IAM_LOGE("Invalid schedule node, report auth false");
79 return ResultCode::GENERAL_ERROR;
80 }
81 std::vector<AuthType> authTypeList = {};
82 if (!GetAuthTypeList(notice, authTypeList)) {
83 IAM_LOGE("Invalid auth type list");
84 return ResultCode::INVALID_PARAMETERS;
85 }
86 if (notice.event == NOTICE_EVENT_AUTH_READY) {
87 schedule_->StartAuthList(authTypeList);
88 } else if (notice.event == NOTICE_EVENT_CANCEL_AUTH) {
89 if (authTypeList.size() == 1 && authTypeList[0] == AuthType::ALL) {
90 schedule_->StopSchedule();
91 } else {
92 schedule_->StopAuthList(authTypeList);
93 }
94 } else if (notice.event == NOTICE_EVENT_USER_NAVIGATION) {
95 schedule_->NaviPinAuth();
96 }
97 return ResultCode::SUCCESS;
98 }
99
SendCommand(const WidgetCommand & command)100 void WidgetClient::SendCommand(const WidgetCommand &command)
101 {
102 if (widgetCallback_ == nullptr) {
103 IAM_LOGE("SendCommand widget callback is null");
104 return;
105 }
106 nlohmann::json root = command;
107 std::string cmdData = root.dump();
108 IAM_LOGI("SendCommand cmdData: %{public}s", cmdData.c_str());
109 widgetCallback_->SendCommand(cmdData);
110 }
111
ReportWidgetResult(int32_t result,AuthType authType,int32_t lockoutDuration,int32_t remainAttempts)112 void WidgetClient::ReportWidgetResult(int32_t result, AuthType authType,
113 int32_t lockoutDuration, int32_t remainAttempts)
114 {
115 // sendCommand of CMD_NOTIFY_AUTH_RESULT
116 WidgetCommand::Cmd cmd {
117 .event = "CMD_NOTIFY_AUTH_RESULT",
118 .version = NOTICE_VERSION_STR,
119 .type = AuthType2Str(authType),
120 .result = result,
121 .lockoutDuration = lockoutDuration,
122 .remainAttempts = remainAttempts
123 };
124 if (authType == AuthType::FINGERPRINT && !sensorInfo_.empty()) {
125 cmd.sensorInfo = sensorInfo_;
126 }
127 WidgetCommand widgetCmd {
128 .widgetContextId = widgetContextId_,
129 .title = widgetParam_.title,
130 .windowModeType = WinModeType2Str(widgetParam_.windowMode),
131 .navigationButtonText = widgetParam_.navigationButtonText,
132 .cmdList = { cmd }
133 };
134 for (auto &type : authTypeList_) {
135 widgetCmd.typeList.emplace_back(AuthType2Str(type));
136 }
137 if (!pinSubType_.empty()) {
138 widgetCmd.pinSubType = pinSubType_;
139 }
140 SendCommand(widgetCmd);
141 }
142
SetWidgetContextId(uint64_t contextId)143 void WidgetClient::SetWidgetContextId(uint64_t contextId)
144 {
145 widgetContextId_ = contextId;
146 }
147
SetWidgetParam(const WidgetParam & param)148 void WidgetClient::SetWidgetParam(const WidgetParam ¶m)
149 {
150 widgetParam_ = param;
151 }
152
SetAuthTypeList(const std::vector<AuthType> & authTypeList)153 void WidgetClient::SetAuthTypeList(const std::vector<AuthType> &authTypeList)
154 {
155 authTypeList_ = authTypeList;
156 }
157
SetWidgetCallback(const sptr<WidgetCallbackInterface> & callback)158 void WidgetClient::SetWidgetCallback(const sptr<WidgetCallbackInterface> &callback)
159 {
160 widgetCallback_ = callback;
161 }
162
SetAuthTokenId(uint32_t tokenId)163 void WidgetClient::SetAuthTokenId(uint32_t tokenId)
164 {
165 authTokenId_ = tokenId;
166 IAM_LOGI("WidgetClient SetAuthTokenId authTokenId: %{public}u", authTokenId_);
167 }
168
GetAuthTokenId() const169 uint32_t WidgetClient::GetAuthTokenId() const
170 {
171 return authTokenId_;
172 }
173
Reset()174 void WidgetClient::Reset()
175 {
176 IAM_LOGI("WidgetClient Reset");
177 widgetParam_.title.clear();
178 widgetParam_.navigationButtonText.clear();
179 widgetParam_.windowMode = WindowModeType::DIALOG_BOX;
180 widgetContextId_ = 0;
181 authTokenId_ = 0;
182 schedule_ = nullptr;
183 widgetCallback_ = nullptr;
184 pinSubType_.clear();
185 sensorInfo_.clear();
186 }
187
ForceStopAuth()188 void WidgetClient::ForceStopAuth()
189 {
190 IAM_LOGE("Stop Auth process forcely by disconnect");
191 if (widgetContextId_ != 0) {
192 IAM_LOGE("widget context id hasn't been reset");
193 UserIam::UserAuth::ReportSystemFault(Common::GetNowTimeString(), "AuthWidget");
194 }
195 if (schedule_ != nullptr) {
196 schedule_->StopSchedule();
197 }
198 }
199
SetPinSubType(const PinSubType & subType)200 void WidgetClient::SetPinSubType(const PinSubType &subType)
201 {
202 pinSubType_ = PIN_SUB_TYPE_SIX;
203 switch (subType) {
204 case PinSubType::PIN_NUMBER:
205 pinSubType_ = PIN_SUB_TYPE_NUMBER;
206 break;
207 case PinSubType::PIN_MIXED:
208 pinSubType_ = PIN_SUB_TYPE_MIXED;
209 break;
210 case PinSubType::PIN_MAX:
211 pinSubType_ = PIN_SUB_TYPE_MAX;
212 break;
213 default:
214 break;
215 }
216 }
217
SetSensorInfo(const std::string & info)218 void WidgetClient::SetSensorInfo(const std::string &info)
219 {
220 sensorInfo_ = info;
221 }
222
GetAuthTypeList(const WidgetNotice & notice,std::vector<AuthType> & authTypeList)223 bool WidgetClient::GetAuthTypeList(const WidgetNotice ¬ice, std::vector<AuthType> &authTypeList)
224 {
225 if (authTypeList_.empty()) {
226 IAM_LOGE("inner auth type list is empty");
227 return false;
228 }
229 std::vector<AuthType> tempList = notice.AuthTypeList();
230 if (tempList.empty()) {
231 IAM_LOGE("auth type list is empty");
232 return false;
233 }
234 if (tempList.size() == 1 && tempList[0] == AuthType::ALL) {
235 if (notice.event != NOTICE_EVENT_CANCEL_AUTH) {
236 IAM_LOGE("invalid type all case event type: %{public}s", notice.event.c_str());
237 return false;
238 }
239 authTypeList.emplace_back(AuthType::ALL);
240 return true;
241 }
242 for (auto &type : tempList) {
243 if (std::find(authTypeList_.begin(), authTypeList_.end(), type) == authTypeList_.end()) {
244 IAM_LOGE("invalid auth type: %{public}d", type);
245 return false;
246 }
247 authTypeList.emplace_back(type);
248 }
249 if (authTypeList.size() == authTypeList_.size() && notice.event == NOTICE_EVENT_CANCEL_AUTH) {
250 authTypeList.clear();
251 authTypeList.emplace_back(AuthType::ALL);
252 }
253 return true;
254 }
255
IsValidNoticeType(const WidgetNotice & notice)256 bool WidgetClient::IsValidNoticeType(const WidgetNotice ¬ice)
257 {
258 if (notice.event != NOTICE_EVENT_AUTH_READY &&
259 notice.event != NOTICE_EVENT_CANCEL_AUTH &&
260 notice.event != NOTICE_EVENT_USER_NAVIGATION) {
261 return false;
262 }
263 return true;
264 }
265 } // namespace UserAuth
266 } // namespace UserIam
267 } // namespace OHOS