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