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 <map>
17 #include "iam_common_defines.h"
18 #include "iam_logger.h"
19 #include "user_auth_common_defines.h"
20 #include "widget_json.h"
21 
22 #define LOG_TAG "USER_AUTH_SA"
23 
24 namespace OHOS {
25 namespace UserIam {
26 namespace UserAuth {
27 
28 const std::string AUTH_TYPE_PIN = "pin";
29 const std::string AUTH_TYPE_FACE = "face";
30 const std::string AUTH_TYPE_FINGER_PRINT = "fingerprint";
31 const std::string AUTH_TYPE_ALL = "all";
32 
33 const std::string WINDOW_MODE_DIALOG = "DIALOG_BOX";
34 const std::string WINDOW_MODE_FULLSCREEN = "FULLSCREEN";
35 
36 const std::string PIN_SUB_TYPE_SIX = "PIN_SIX";
37 const std::string PIN_SUB_TYPE_NUM = "PIN_NUMBER";
38 const std::string PIN_SUB_TYPE_MIX = "PIN_MIXED";
39 const std::string PIN_SUB_TYPE_FOUR = "PIN_FOUR";
40 const std::string PIN_SUB_TYPE_PATTERN = "PIN_PATTERN";
41 const std::string PIN_SUB_TYPE_MAX = "PIN_MAX";
42 
43 const std::string JSON_AUTH_TYPE = "type";
44 const std::string JSON_WIDGET_CTX_ID = "widgetContextId";
45 const std::string JSON_AUTH_EVENT = "event";
46 const std::string JSON_AUTH_VERSION = "version";
47 const std::string JSON_AUTH_PAYLOAD = "payload";
48 const std::string JSON_AUTH_END_AFTER_FIRST_FAIL = "endAfterFirstFail";
49 const std::string JSON_AUTH_INTENT = "authIntent";
50 const std::string JSON_ORIENTATION = "orientation";
51 const std::string JSON_NEED_ROTATE = "needRotate";
52 const std::string JSON_ALREADY_LOAD = "alreadyLoad";
53 const std::string JSON_LOCKOUT_DURATION = "lockoutDuration";
54 const std::string JSON_REMAIN_ATTEMPTS = "remainAttempts";
55 const std::string JSON_AUTH_RESULT = "result";
56 const std::string JSON_SENSOR_INFO = "sensorInfo";
57 const std::string JSON_AUTH_TIP_TYPE = "tipType";
58 const std::string JSON_AUTH_TIP_INFO = "tipInfo";
59 const std::string JSON_AUTH_TITLE = "title";
60 const std::string JSON_AUTH_CMD = "cmd";
61 const std::string JSON_AUTH_PIN_SUB_TYPE = "pinSubType";
62 const std::string JSON_AUTH_WINDOW_MODE = "windowModeType";
63 const std::string JSON_AUTH_NAVI_BTN_TEXT = "navigationButtonText";
64 const std::string JSON_WIDGET_IS_RELOAD = "isReload";
65 const std::string JSON_WIDGET_ROTATE_AUTH_TYPE = "rotateAuthType";
66 const std::string JSON_WIDGET_CALLING_APP_ID = "callingAppID";
67 
68 const std::string JSON_UI_EXTENSION_TYPE = "ability.want.params.uiExtensionType";
69 const std::string JSON_UI_EXT_NODE_ANGLE = "ability.want.params.uiExtNodeAngle";
70 const std::string JSON_USER_IAM_CMD_DATA = "useriamCmdData";
71 const std::string JSON_SYS_DIALOG_ZORDER = "sysDialogZOrder";
72 
73 const std::string JSON_CHALLENGE = "challenge";
74 const std::string JSON_CALLER_BUNDLE_NAME = "callingBundleName";
75 const std::string JSON_CMD_EXTRA_INFO = "extraInfo";
76 
77 namespace {
GetJsonPayload(nlohmann::json &jsonPayload, const WidgetCommand::Cmd &cmd)78 void GetJsonPayload(nlohmann::json &jsonPayload, const WidgetCommand::Cmd &cmd)
79 {
80     jsonPayload[JSON_AUTH_TYPE] = cmd.type;
81     if (cmd.lockoutDuration != -1) {
82         jsonPayload[JSON_LOCKOUT_DURATION] = cmd.lockoutDuration;
83     }
84     if (cmd.remainAttempts != -1) {
85         jsonPayload[JSON_REMAIN_ATTEMPTS] = cmd.remainAttempts;
86     }
87     if (cmd.event == CMD_NOTIFY_AUTH_RESULT || cmd.result == PIN_EXPIRED) {
88         jsonPayload[JSON_AUTH_RESULT] = cmd.result;
89     }
90     if (cmd.event == CMD_NOTIFY_AUTH_TIP) {
91         jsonPayload[JSON_AUTH_TIP_TYPE] = cmd.tipType;
92         jsonPayload[JSON_AUTH_TIP_INFO] = cmd.tipInfo;
93     }
94     if (!cmd.sensorInfo.empty()) {
95         jsonPayload[JSON_SENSOR_INFO] = cmd.sensorInfo;
96     }
97     auto jsonCmdExtraInfo = nlohmann::json({{JSON_CHALLENGE, cmd.extraInfo.challenge},
98         {JSON_CALLER_BUNDLE_NAME, cmd.extraInfo.callingBundleName}});
99     jsonPayload[JSON_CMD_EXTRA_INFO] = jsonCmdExtraInfo;
100 }
101 
GetJsonCmd(nlohmann::json &jsonCommand, const WidgetCommand &command)102 void GetJsonCmd(nlohmann::json &jsonCommand, const WidgetCommand &command)
103 {
104     std::vector<nlohmann::json> jsonCmdList;
105     for (auto &cmd : command.cmdList) {
106         auto jsonCmd = nlohmann::json({{JSON_AUTH_EVENT, cmd.event},
107             {JSON_AUTH_VERSION, cmd.version}
108         });
109         nlohmann::json jsonPayload;
110         GetJsonPayload(jsonPayload, cmd);
111         jsonCmd[JSON_AUTH_PAYLOAD] = jsonPayload;
112         jsonCmdList.push_back(jsonCmd);
113     }
114 
115     jsonCommand = nlohmann::json({{JSON_WIDGET_CTX_ID, command.widgetContextId},
116         {JSON_AUTH_TYPE, command.typeList},
117         {JSON_AUTH_TITLE, command.title},
118         {JSON_AUTH_CMD, jsonCmdList}
119     });
120     if (command.pinSubType != "") {
121         jsonCommand[JSON_AUTH_PIN_SUB_TYPE] = command.pinSubType;
122     }
123     if (command.windowModeType != "") {
124         jsonCommand[JSON_AUTH_WINDOW_MODE] = command.windowModeType;
125     }
126     if (command.navigationButtonText != "") {
127         jsonCommand[JSON_AUTH_NAVI_BTN_TEXT] = command.navigationButtonText;
128     }
129     jsonCommand[JSON_WIDGET_IS_RELOAD] = command.isReload;
130     jsonCommand[JSON_WIDGET_ROTATE_AUTH_TYPE] = command.rotateAuthType;
131     jsonCommand[JSON_WIDGET_CALLING_APP_ID] = command.callingAppID;
132 }
133 }
134 
135 // utils
Str2AuthType(const std::string &strAuthType)136 AuthType Str2AuthType(const std::string &strAuthType)
137 {
138     AuthType authType = AuthType::ALL;
139     if (strAuthType.compare(AUTH_TYPE_ALL) == 0) {
140         authType = AuthType::ALL;
141     } else if (strAuthType.compare(AUTH_TYPE_PIN) == 0) {
142         authType = AuthType::PIN;
143     } else if (strAuthType.compare(AUTH_TYPE_FACE) == 0) {
144         authType = AuthType::FACE;
145     } else if (strAuthType.compare(AUTH_TYPE_FINGER_PRINT) == 0) {
146         authType = AuthType::FINGERPRINT;
147     } else {
148         IAM_LOGE("strAuthType: %{public}s", strAuthType.c_str());
149     }
150     return authType;
151 }
152 
AuthType2Str(const AuthType &authType)153 std::string AuthType2Str(const AuthType &authType)
154 {
155     std::string strAuthType = "";
156     switch (authType) {
157         case AuthType::ALL: {
158             strAuthType = AUTH_TYPE_ALL;
159             break;
160         }
161         case AuthType::PIN: {
162             strAuthType = AUTH_TYPE_PIN;
163             break;
164         }
165         case AuthType::FACE: {
166             strAuthType = AUTH_TYPE_FACE;
167             break;
168         }
169         case AuthType::FINGERPRINT: {
170             strAuthType = AUTH_TYPE_FINGER_PRINT;
171             break;
172         }
173         default: {
174             IAM_LOGE("authType: %{public}u", authType);
175         }
176     }
177     return strAuthType;
178 }
179 
WinModeType2Str(const WindowModeType &winModeType)180 std::string WinModeType2Str(const WindowModeType &winModeType)
181 {
182     std::string strWinModeType = "";
183     switch (winModeType) {
184         case WindowModeType::DIALOG_BOX: {
185             strWinModeType = WINDOW_MODE_DIALOG;
186             break;
187         }
188         case WindowModeType::FULLSCREEN: {
189             strWinModeType = WINDOW_MODE_FULLSCREEN;
190             break;
191         }
192         default: {
193             IAM_LOGE("winModeType: %{public}u", winModeType);
194         }
195     }
196     return strWinModeType;
197 }
198 
AuthTypeList() const199 std::vector<AuthType> WidgetNotice::AuthTypeList() const
200 {
201     std::vector<AuthType> authTypeList;
202     for (const auto &type : typeList) {
203         authTypeList.emplace_back(Str2AuthType(type));
204     }
205     return authTypeList;
206 }
207 
PinSubType2Str(const PinSubType &subType)208 std::string PinSubType2Str(const PinSubType &subType)
209 {
210     std::string strPinSubType = "";
211     switch (subType) {
212         case PinSubType::PIN_SIX: {
213             strPinSubType = PIN_SUB_TYPE_SIX;
214             break;
215         }
216         case PinSubType::PIN_NUMBER: {
217             strPinSubType = PIN_SUB_TYPE_NUM;
218             break;
219         }
220         case PinSubType::PIN_MIXED: {
221             strPinSubType = PIN_SUB_TYPE_MIX;
222             break;
223         }
224         case PinSubType::PIN_FOUR: {
225             strPinSubType = PIN_SUB_TYPE_FOUR;
226             break;
227         }
228         case PinSubType::PIN_PATTERN: {
229             strPinSubType = PIN_SUB_TYPE_PATTERN;
230             break;
231         }
232         case PinSubType::PIN_MAX: {
233             strPinSubType = PIN_SUB_TYPE_MAX;
234             break;
235         }
236         default: {
237             IAM_LOGE("subType: %{public}u", subType);
238         }
239     }
240     return strPinSubType;
241 }
242 
to_json(nlohmann::json &jsonNotice, const WidgetNotice &notice)243 void to_json(nlohmann::json &jsonNotice, const WidgetNotice &notice)
244 {
245     auto type = nlohmann::json({{JSON_AUTH_TYPE, notice.typeList},
246         {JSON_AUTH_END_AFTER_FIRST_FAIL, notice.endAfterFirstFail},
247         {JSON_AUTH_INTENT, notice.authIntent}});
248     jsonNotice = nlohmann::json({{JSON_WIDGET_CTX_ID, notice.widgetContextId},
249         {JSON_AUTH_EVENT, notice.event},
250         {JSON_ORIENTATION, notice.orientation},
251         {JSON_NEED_ROTATE, notice.needRotate},
252         {JSON_ALREADY_LOAD, notice.alreadyLoad},
253         {JSON_AUTH_VERSION, notice.version},
254         {JSON_AUTH_PAYLOAD, type}});
255 }
256 
isNumberItem(const nlohmann::json &jsonNotice, const std::string &item)257 bool isNumberItem(const nlohmann::json &jsonNotice, const std::string &item)
258 {
259     if (jsonNotice.find(item) != jsonNotice.end() && jsonNotice[item].is_number()) {
260         return true;
261     }
262     return false;
263 }
264 
from_json(const nlohmann::json &jsonNotice, WidgetNotice &notice)265 void from_json(const nlohmann::json &jsonNotice, WidgetNotice &notice)
266 {
267     if (isNumberItem(jsonNotice, JSON_WIDGET_CTX_ID)) {
268         jsonNotice.at(JSON_WIDGET_CTX_ID).get_to(notice.widgetContextId);
269     }
270     if (jsonNotice.find(JSON_AUTH_EVENT) != jsonNotice.end() && jsonNotice[JSON_AUTH_EVENT].is_string()) {
271         jsonNotice.at(JSON_AUTH_EVENT).get_to(notice.event);
272     }
273     if (isNumberItem(jsonNotice, JSON_ORIENTATION)) {
274         jsonNotice.at(JSON_ORIENTATION).get_to(notice.orientation);
275     }
276     if (isNumberItem(jsonNotice, JSON_NEED_ROTATE)) {
277         jsonNotice.at(JSON_NEED_ROTATE).get_to(notice.needRotate);
278     }
279     if (isNumberItem(jsonNotice, JSON_ALREADY_LOAD)) {
280         jsonNotice.at(JSON_ALREADY_LOAD).get_to(notice.alreadyLoad);
281     }
282     if (jsonNotice.find(JSON_AUTH_VERSION) != jsonNotice.end() && jsonNotice[JSON_AUTH_VERSION].is_string()) {
283         jsonNotice.at(JSON_AUTH_VERSION).get_to(notice.version);
284     }
285     if (jsonNotice.find(JSON_AUTH_PAYLOAD) == jsonNotice.end()) {
286         return;
287     }
288     if (jsonNotice[JSON_AUTH_PAYLOAD].find(JSON_AUTH_TYPE) != jsonNotice[JSON_AUTH_PAYLOAD].end() &&
289         jsonNotice[JSON_AUTH_PAYLOAD][JSON_AUTH_TYPE].is_array()) {
290         for (size_t index = 0; index < jsonNotice[JSON_AUTH_PAYLOAD][JSON_AUTH_TYPE].size(); index++) {
291             if (!jsonNotice[JSON_AUTH_PAYLOAD][JSON_AUTH_TYPE].at(index).is_string()) {
292                 notice.typeList.clear();
293                 break;
294             }
295             notice.typeList.emplace_back(jsonNotice[JSON_AUTH_PAYLOAD][JSON_AUTH_TYPE].at(index).get<std::string>());
296         }
297     }
298     if ((jsonNotice[JSON_AUTH_PAYLOAD].find(JSON_AUTH_END_AFTER_FIRST_FAIL) !=
299             jsonNotice[JSON_AUTH_PAYLOAD].end()) &&
300         jsonNotice[JSON_AUTH_PAYLOAD][JSON_AUTH_END_AFTER_FIRST_FAIL].is_boolean()) {
301         jsonNotice[JSON_AUTH_PAYLOAD].at(JSON_AUTH_END_AFTER_FIRST_FAIL).get_to(notice.endAfterFirstFail);
302     }
303     if (isNumberItem(jsonNotice[JSON_AUTH_PAYLOAD], JSON_AUTH_INTENT)) {
304         jsonNotice[JSON_AUTH_PAYLOAD].at(JSON_AUTH_INTENT).get_to(notice.authIntent);
305     }
306 }
307 
to_json(nlohmann::json &jsonCommand, const WidgetCommand &command)308 void to_json(nlohmann::json &jsonCommand, const WidgetCommand &command)
309 {
310     GetJsonCmd(jsonCommand, command);
311 }
312 
313 // WidgetCmdParameters
to_json(nlohmann::json &jsWidgetCmdParam, const WidgetCmdParameters &widgetCmdParameters)314 void to_json(nlohmann::json &jsWidgetCmdParam, const WidgetCmdParameters &widgetCmdParameters)
315 {
316     nlohmann::json jsonCommand;
317     GetJsonCmd(jsonCommand, widgetCmdParameters.useriamCmdData);
318 
319     jsWidgetCmdParam = nlohmann::json({{JSON_UI_EXTENSION_TYPE, widgetCmdParameters.uiExtensionType},
320         {JSON_SYS_DIALOG_ZORDER, widgetCmdParameters.sysDialogZOrder},
321         {JSON_UI_EXT_NODE_ANGLE, widgetCmdParameters.uiExtNodeAngle},
322         {JSON_USER_IAM_CMD_DATA, jsonCommand}
323     });
324 }
325 } // namespace UserAuth
326 } // namespace UserIam
327 } // namespace OHOS