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