1 /*
2 * Copyright (c) 2021-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 "app_account_info.h"
17
18 #include "account_log_wrapper.h"
19 #ifdef HAS_ASSET_PART
20 #include <iomanip>
21 #include <sstream>
22 #include "mbedtls/sha256.h"
23 #endif
24 #include "nlohmann/json.hpp"
25
26 namespace OHOS {
27 namespace AccountSA {
28 namespace {
29 const std::string OWNER = "owner";
30 const std::string NAME = "name";
31 const std::string ALIAS = "alias";
32 const std::string EXTRA_INFO = "extraInfo";
33 const std::string SYNC_ENABLE = "syncEnable";
34 const std::string AUTHORIZED_APPS = "authorizedApps";
35 const std::string ASSOCIATED_DATA = "associatedData";
36 const std::string ACCOUNT_CREDENTIAL = "accountCredential";
37 const std::string OAUTH_TOKEN = "oauthToken";
38 const std::string OAUTH_TOKEN_INFOS = "tokenInfos";
39 const std::string OAUTH_TYPE = "authType";
40 const std::string OAUTH_TOKEN_STATUS = "status";
41 const std::string OAUTH_AUTH_LIST = "authList";
42 const std::string OAUTH_TOKEN_TO_TYPE = "tokenToType";
43 const std::string HYPHEN = "#";
44 constexpr uint32_t APP_INDEX = 0;
45 constexpr uint32_t MAX_TOKEN_NUMBER = 128;
46 constexpr uint32_t MAX_OAUTH_LIST_SIZE = 512;
47 constexpr uint32_t MAX_ASSOCIATED_DATA_NUMBER = 1024;
48 constexpr uint32_t MAX_APP_AUTH_LIST_SIZE = 1024;
49 #ifdef HAS_ASSET_PART
50 constexpr uint32_t HASH_LENGTH = 32;
51 constexpr uint32_t WIDTH_FOR_HEX = 2;
52 #endif
53 constexpr int32_t MAX_MAP_SZIE = 1024;
54 } // namespace
55
56 #ifdef HAS_ASSET_PART
ComputeHash(const std::string & input,std::string & output)57 static void ComputeHash(const std::string &input, std::string &output)
58 {
59 unsigned char hash[HASH_LENGTH] = {0};
60 mbedtls_sha256_context context;
61 mbedtls_sha256_init(&context);
62 mbedtls_sha256_starts(&context, 0);
63 mbedtls_sha256_update(&context, reinterpret_cast<const unsigned char *>(input.c_str()), input.length());
64 mbedtls_sha256_finish(&context, hash);
65 mbedtls_sha256_free(&context);
66
67 std::stringstream ss;
68 for (std::uint32_t i = 0; i < HASH_LENGTH; ++i) {
69 ss << std::hex << std::uppercase << std::setw(WIDTH_FOR_HEX) << std::setfill('0') << std::uint16_t(hash[i]);
70 }
71 ss >> output;
72 }
73 #endif
74
AppAccountInfo()75 AppAccountInfo::AppAccountInfo()
76 {
77 owner_ = "";
78 name_ = "";
79 appIndex_ = APP_INDEX;
80 extraInfo_ = "";
81 authorizedApps_.clear();
82 syncEnable_ = false;
83 associatedData_ = "";
84 accountCredential_ = "";
85 alias_ = "";
86 oauthTokens_.clear();
87 }
88
AppAccountInfo(const std::string & name,const std::string & owner)89 AppAccountInfo::AppAccountInfo(const std::string &name, const std::string &owner)
90 {
91 name_ = name;
92 owner_ = owner;
93 appIndex_ = APP_INDEX;
94 extraInfo_ = "";
95 authorizedApps_.clear();
96 syncEnable_ = false;
97 associatedData_ = "";
98 accountCredential_ = "";
99 alias_ = "";
100 oauthTokens_.clear();
101 }
102
GetOwner()103 std::string AppAccountInfo::GetOwner()
104 {
105 return owner_;
106 }
107
GetOwner(std::string & owner)108 void AppAccountInfo::GetOwner(std::string &owner)
109 {
110 owner = owner_;
111 }
112
SetOwner(const std::string & owner)113 void AppAccountInfo::SetOwner(const std::string &owner)
114 {
115 owner_ = owner;
116 alias_ = "";
117 }
118
GetName()119 std::string AppAccountInfo::GetName()
120 {
121 return name_;
122 }
123
GetName(std::string & name) const124 void AppAccountInfo::GetName(std::string &name) const
125 {
126 name = name_;
127 }
128
SetName(const std::string & name)129 void AppAccountInfo::SetName(const std::string &name)
130 {
131 name_ = name;
132 alias_ = "";
133 }
134
GetAppIndex()135 uint32_t AppAccountInfo::GetAppIndex()
136 {
137 return appIndex_;
138 }
139
SetAppIndex(const uint32_t & appIndex)140 void AppAccountInfo::SetAppIndex(const uint32_t &appIndex)
141 {
142 appIndex_ = appIndex;
143 alias_ = "";
144 }
145
GetExtraInfo(std::string & extraInfo) const146 void AppAccountInfo::GetExtraInfo(std::string &extraInfo) const
147 {
148 extraInfo = extraInfo_;
149 }
150
SetExtraInfo(const std::string & extraInfo)151 void AppAccountInfo::SetExtraInfo(const std::string &extraInfo)
152 {
153 extraInfo_ = extraInfo;
154 }
155
EnableAppAccess(const std::string & authorizedApp,const uint32_t apiVersion)156 ErrCode AppAccountInfo::EnableAppAccess(const std::string &authorizedApp, const uint32_t apiVersion)
157 {
158 auto it = authorizedApps_.emplace(authorizedApp);
159 if (!it.second && apiVersion < Constants::API_VERSION9) {
160 return ERR_APPACCOUNT_SERVICE_ENABLE_APP_ACCESS_ALREADY_EXISTS;
161 }
162 if (authorizedApps_.size() > MAX_APP_AUTH_LIST_SIZE) {
163 ACCOUNT_LOGE("the authorization list is too large, whose capacity for each authType is %{public}d",
164 MAX_OAUTH_LIST_SIZE);
165 authorizedApps_.erase(authorizedApp);
166 return ERR_APPACCOUNT_SERVICE_OAUTH_LIST_MAX_SIZE;
167 }
168 return ERR_OK;
169 }
170
DisableAppAccess(const std::string & authorizedApp,const uint32_t apiVersion)171 ErrCode AppAccountInfo::DisableAppAccess(const std::string &authorizedApp, const uint32_t apiVersion)
172 {
173 auto result = authorizedApps_.erase(authorizedApp);
174 if (result == 0 && apiVersion < Constants::API_VERSION9) {
175 return ERR_APPACCOUNT_SERVICE_DISABLE_APP_ACCESS_NOT_EXISTED;
176 }
177 return ERR_OK;
178 }
179
CheckAppAccess(const std::string & authorizedApp,bool & isAccessible)180 ErrCode AppAccountInfo::CheckAppAccess(const std::string &authorizedApp, bool &isAccessible)
181 {
182 isAccessible = false;
183 auto it = authorizedApps_.find(authorizedApp);
184 if (it != authorizedApps_.end()) {
185 isAccessible = true;
186 }
187 return ERR_OK;
188 }
189
GetAuthorizedApps(std::set<std::string> & apps) const190 void AppAccountInfo::GetAuthorizedApps(std::set<std::string> &apps) const
191 {
192 apps = authorizedApps_;
193 }
194
SetAuthorizedApps(const std::set<std::string> & apps)195 void AppAccountInfo::SetAuthorizedApps(const std::set<std::string> &apps)
196 {
197 authorizedApps_ = apps;
198 }
199
GetSyncEnable(bool & syncEnable) const200 void AppAccountInfo::GetSyncEnable(bool &syncEnable) const
201 {
202 syncEnable = syncEnable_;
203 }
204
SetSyncEnable(const bool & syncEnable)205 void AppAccountInfo::SetSyncEnable(const bool &syncEnable)
206 {
207 syncEnable_ = syncEnable;
208 }
209
InitCustomData(const std::map<std::string,std::string> & data)210 ErrCode AppAccountInfo::InitCustomData(const std::map<std::string, std::string> &data)
211 {
212 Json jsonObject = data;
213 try {
214 associatedData_ = jsonObject.dump();
215 } catch (Json::type_error& err) {
216 ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
217 return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
218 }
219 return ERR_OK;
220 }
221
GetAllAssociatedData(std::map<std::string,std::string> & data) const222 ErrCode AppAccountInfo::GetAllAssociatedData(std::map<std::string, std::string> &data) const
223 {
224 auto jsonObject = Json::parse(associatedData_, nullptr, false);
225 if (jsonObject.is_discarded() || !jsonObject.is_object()) {
226 ACCOUNT_LOGE("jsonObject is_discarded");
227 return ERR_APPACCOUNT_SERVICE_GET_ASSOCIATED_DATA;
228 }
229 try {
230 data = jsonObject.get<std::map<std::string, std::string>>();
231 } catch (Json::type_error& err) {
232 ACCOUNT_LOGE("failed to convert json object to map, reason: %{public}s", err.what());
233 return ERR_APPACCOUNT_SERVICE_GET_ASSOCIATED_DATA;
234 }
235 return ERR_OK;
236 }
237
GetAssociatedData(const std::string & key,std::string & value) const238 ErrCode AppAccountInfo::GetAssociatedData(const std::string &key, std::string &value) const
239 {
240 auto jsonObject = Json::parse(associatedData_, nullptr, false);
241 if (jsonObject.is_discarded()) {
242 ACCOUNT_LOGI("jsonObject is_discarded");
243 jsonObject = Json::object();
244 }
245
246 if (jsonObject.find(key) == jsonObject.end()) {
247 ACCOUNT_LOGE("failed to find value, key = %{public}s", key.c_str());
248 return ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_KEY_NOT_EXIST;
249 }
250
251 value = jsonObject.at(key);
252 return ERR_OK;
253 }
254
SetAssociatedData(const std::string & key,const std::string & value)255 ErrCode AppAccountInfo::SetAssociatedData(const std::string &key, const std::string &value)
256 {
257 auto jsonObject = Json::parse(associatedData_, nullptr, false);
258 if (jsonObject.is_discarded() || (!jsonObject.is_object())) {
259 ACCOUNT_LOGI("jsonObject is discarded");
260 jsonObject = Json::object();
261 }
262 auto it = jsonObject.find(key);
263 if (it == jsonObject.end()) {
264 if (jsonObject.size() >= MAX_ASSOCIATED_DATA_NUMBER) {
265 ACCOUNT_LOGW("associated data is over size, the max number is: %{public}d", MAX_ASSOCIATED_DATA_NUMBER);
266 return ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_OVER_SIZE;
267 }
268 jsonObject.emplace(key, value);
269 } else {
270 jsonObject[key] = value;
271 }
272
273 try {
274 associatedData_ = jsonObject.dump();
275 } catch (Json::type_error& err) {
276 ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
277 return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
278 }
279 return ERR_OK;
280 }
281
GetAccountCredential(const std::string & credentialType,std::string & credential) const282 ErrCode AppAccountInfo::GetAccountCredential(const std::string &credentialType, std::string &credential) const
283 {
284 auto jsonObject = Json::parse(accountCredential_, nullptr, false);
285 if (jsonObject.is_discarded()) {
286 jsonObject = Json::object();
287 }
288
289 if (jsonObject.find(credentialType) == jsonObject.end()) {
290 ACCOUNT_LOGE("failed to find value, credentialType = %{public}s", credentialType.c_str());
291 return ERR_APPACCOUNT_SERVICE_ACCOUNT_CREDENTIAL_NOT_EXIST;
292 }
293
294 credential = jsonObject.at(credentialType);
295 return ERR_OK;
296 }
297
SetAccountCredential(const std::string & credentialType,const std::string & credential)298 ErrCode AppAccountInfo::SetAccountCredential(
299 const std::string &credentialType, const std::string &credential)
300 {
301 Json jsonObject;
302 if (accountCredential_.empty()) {
303 jsonObject = Json::object();
304 } else {
305 jsonObject = Json::parse(accountCredential_, nullptr, false);
306 if (jsonObject.is_discarded() || !jsonObject.is_object()) {
307 ACCOUNT_LOGE("jsonObject is not an object");
308 return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
309 }
310 }
311 #ifndef HAS_ASSET_PART
312 jsonObject[credentialType] = credential;
313 #else
314 auto it = jsonObject.find(credentialType);
315 if (it == jsonObject.end()) {
316 std::string credentialTypeAlias;
317 ComputeHash(credentialType, credentialTypeAlias);
318 jsonObject[credentialType] = GetAlias() + credentialTypeAlias;
319 } else {
320 return ERR_OK;
321 }
322 #endif
323
324 try {
325 accountCredential_ = jsonObject.dump();
326 } catch (Json::type_error& err) {
327 ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
328 return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
329 }
330 return ERR_OK;
331 }
332
DeleteAccountCredential(const std::string & credentialType)333 ErrCode AppAccountInfo::DeleteAccountCredential(const std::string &credentialType)
334 {
335 auto jsonObject = Json::parse(accountCredential_, nullptr, false);
336 if (jsonObject.is_discarded() || !jsonObject.is_object() || (jsonObject.erase(credentialType) == 0)) {
337 ACCOUNT_LOGE("credential not found");
338 return ERR_APPACCOUNT_SERVICE_ACCOUNT_CREDENTIAL_NOT_EXIST;
339 }
340 accountCredential_ = jsonObject.dump();
341 return ERR_OK;
342 }
343
GetOAuthToken(const std::string & authType,std::string & token,const uint32_t apiVersion) const344 ErrCode AppAccountInfo::GetOAuthToken(const std::string &authType, std::string &token, const uint32_t apiVersion) const
345 {
346 token = "";
347 auto it = oauthTokens_.find(authType);
348 if (apiVersion >= Constants::API_VERSION9) {
349 if ((it == oauthTokens_.end()) || (!it->second.status)) {
350 ACCOUNT_LOGE("oauth token not exist");
351 return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST;
352 }
353 } else {
354 if ((it == oauthTokens_.end()) || (it->second.token.empty())) {
355 ACCOUNT_LOGE("oauth token not exist");
356 return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST;
357 }
358 }
359 token = it->second.token;
360 return ERR_OK;
361 }
362
SetOAuthToken(const std::string & authType,const std::string & token)363 ErrCode AppAccountInfo::SetOAuthToken(const std::string &authType, const std::string &token)
364 {
365 auto it = oauthTokens_.find(authType);
366 if (it != oauthTokens_.end()) {
367 #ifndef HAS_ASSET_PART
368 it->second.token = token;
369 #endif
370 it->second.status = true;
371 return ERR_OK;
372 }
373 if (oauthTokens_.size() >= MAX_TOKEN_NUMBER) {
374 ACCOUNT_LOGE("too many types of oauth token, capacity for each account is %{public}d", MAX_TOKEN_NUMBER);
375 return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_MAX_SIZE;
376 }
377 OAuthTokenInfo tokenInfo;
378 tokenInfo.status = !token.empty();
379 #ifndef HAS_ASSET_PART
380 tokenInfo.token = token;
381 #else
382 std::string authTypeAlias;
383 ComputeHash(authType, authTypeAlias);
384 tokenInfo.token = GetAlias() + authTypeAlias;
385 #endif
386 oauthTokens_.emplace(authType, tokenInfo);
387 return ERR_OK;
388 }
389
DeleteOAuthToken(const std::string & authType,const std::string & token)390 ErrCode AppAccountInfo::DeleteOAuthToken(const std::string &authType, const std::string &token)
391 {
392 auto it = oauthTokens_.find(authType);
393 if ((it != oauthTokens_.end()) && (it->second.token == token)) {
394 #ifndef HAS_ASSET_PART
395 it->second.token = "";
396 #endif
397 it->second.status = false;
398 return ERR_OK;
399 }
400 return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST;
401 }
402
DeleteAuthToken(const std::string & authType,const std::string & token,bool isOwnerSelf)403 ErrCode AppAccountInfo::DeleteAuthToken(const std::string &authType, const std::string &token, bool isOwnerSelf)
404 {
405 auto it = oauthTokens_.find(authType);
406 if (it == oauthTokens_.end()) {
407 return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST;
408 }
409 if (it->second.token != token) {
410 return ERR_OK;
411 }
412 if (isOwnerSelf) {
413 oauthTokens_.erase(it);
414 }
415 it->second.status = false;
416 return ERR_OK;
417 }
418
SetOAuthTokenVisibility(const std::string & authType,const std::string & bundleName,bool isVisible,const uint32_t apiVersion)419 ErrCode AppAccountInfo::SetOAuthTokenVisibility(
420 const std::string &authType, const std::string &bundleName, bool isVisible, const uint32_t apiVersion)
421 {
422 if (bundleName == owner_) {
423 return ERR_OK;
424 }
425 auto it = oauthTokens_.find(authType);
426 if (it == oauthTokens_.end()) {
427 if (apiVersion >= Constants::API_VERSION9) {
428 return ERR_APPACCOUNT_SERVICE_OAUTH_TYPE_NOT_EXIST;
429 }
430 if (!isVisible) {
431 return ERR_OK;
432 }
433 if (oauthTokens_.size() >= MAX_TOKEN_NUMBER) {
434 ACCOUNT_LOGE("too many types of oauth token, capacity for each account is %{public}d", MAX_TOKEN_NUMBER);
435 return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_MAX_SIZE;
436 }
437 OAuthTokenInfo tokenInfo;
438 tokenInfo.authList.emplace(bundleName);
439 oauthTokens_.emplace(authType, tokenInfo);
440 return ERR_OK;
441 }
442 if (!isVisible) {
443 it->second.authList.erase(bundleName);
444 return ERR_OK;
445 }
446 it->second.authList.emplace(bundleName);
447 if (it->second.authList.size() > MAX_OAUTH_LIST_SIZE) {
448 ACCOUNT_LOGE("the authorization list is too large, whose capacity for each authType is %{public}d",
449 MAX_OAUTH_LIST_SIZE);
450 it->second.authList.erase(bundleName);
451 return ERR_APPACCOUNT_SERVICE_OAUTH_LIST_MAX_SIZE;
452 }
453 return ERR_OK;
454 }
455
CheckOAuthTokenVisibility(const std::string & authType,const std::string & bundleName,bool & isVisible,const uint32_t apiVersion) const456 ErrCode AppAccountInfo::CheckOAuthTokenVisibility(
457 const std::string &authType, const std::string &bundleName, bool &isVisible, const uint32_t apiVersion) const
458 {
459 isVisible = false;
460 if (bundleName == owner_) {
461 isVisible = true;
462 return ERR_OK;
463 }
464 auto tokenInfoIt = oauthTokens_.find(authType);
465 if (tokenInfoIt == oauthTokens_.end()) {
466 if (apiVersion >= Constants::API_VERSION9) {
467 return ERR_APPACCOUNT_SERVICE_OAUTH_TYPE_NOT_EXIST;
468 } else {
469 return ERR_OK;
470 }
471 }
472 std::set<std::string> authList = tokenInfoIt->second.authList;
473 auto it = authList.find(bundleName);
474 if (it != authList.end()) {
475 isVisible = true;
476 }
477 return ERR_OK;
478 }
479
GetAllOAuthTokens(std::vector<OAuthTokenInfo> & tokenInfos) const480 ErrCode AppAccountInfo::GetAllOAuthTokens(std::vector<OAuthTokenInfo> &tokenInfos) const
481 {
482 tokenInfos.clear();
483 for (auto it = oauthTokens_.begin(); it != oauthTokens_.end(); ++it) {
484 tokenInfos.push_back(it->second);
485 }
486 return ERR_OK;
487 }
488
GetOAuthList(const std::string & authType,std::set<std::string> & oauthList,const uint32_t apiVersion) const489 ErrCode AppAccountInfo::GetOAuthList(
490 const std::string &authType, std::set<std::string> &oauthList, const uint32_t apiVersion) const
491 {
492 oauthList.clear();
493 auto it = oauthTokens_.find(authType);
494 if (it == oauthTokens_.end()) {
495 if (apiVersion >= Constants::API_VERSION9) {
496 return ERR_APPACCOUNT_SERVICE_OAUTH_TYPE_NOT_EXIST;
497 } else {
498 return ERR_OK;
499 }
500 }
501 oauthList = it->second.authList;
502 return ERR_OK;
503 }
504
Marshalling(Parcel & parcel) const505 bool AppAccountInfo::Marshalling(Parcel &parcel) const
506 {
507 if (!parcel.WriteString(owner_)) {
508 ACCOUNT_LOGE("failed to write string for owner_");
509 return false;
510 }
511
512 if (!parcel.WriteString(name_)) {
513 ACCOUNT_LOGE("failed to write string for name_");
514 return false;
515 }
516
517 if (!parcel.WriteString(extraInfo_)) {
518 ACCOUNT_LOGE("failed to write string for extraInfo_");
519 return false;
520 }
521
522 if (!WriteStringSet(authorizedApps_, parcel)) {
523 ACCOUNT_LOGE("failed to write string set for authorizedApps_");
524 return false;
525 }
526
527 if (!parcel.WriteBool(syncEnable_)) {
528 ACCOUNT_LOGE("failed to write bool for syncEnable_");
529 return false;
530 }
531
532 if (!parcel.WriteString(associatedData_)) {
533 ACCOUNT_LOGE("failed to write string for associatedData_");
534 return false;
535 }
536
537 if (!parcel.WriteString(accountCredential_)) {
538 ACCOUNT_LOGE("failed to write string for accountCredential_");
539 return false;
540 }
541
542 if (!WriteTokenInfos(oauthTokens_, parcel)) {
543 ACCOUNT_LOGE("failed to write string map for oauthTokens_");
544 return false;
545 }
546 return true;
547 }
548
Unmarshalling(Parcel & parcel)549 AppAccountInfo *AppAccountInfo::Unmarshalling(Parcel &parcel)
550 {
551 AppAccountInfo *appAccountInfo = new (std::nothrow) AppAccountInfo();
552
553 if ((appAccountInfo != nullptr) && (!appAccountInfo->ReadFromParcel(parcel))) {
554 ACCOUNT_LOGE("failed to read from parcel");
555 delete appAccountInfo;
556 appAccountInfo = nullptr;
557 }
558
559 return appAccountInfo;
560 }
561
ToJson() const562 Json AppAccountInfo::ToJson() const
563 {
564 auto tokenArray = Json::array();
565 for (auto it = oauthTokens_.begin(); it != oauthTokens_.end(); ++it) {
566 if (!it->second.status && it->second.authList.empty()) {
567 continue;
568 }
569 auto tokenObject = Json {
570 {OAUTH_TYPE, it->first},
571 {OAUTH_TOKEN, it->second.token},
572 {OAUTH_TOKEN_STATUS, it->second.status},
573 {OAUTH_AUTH_LIST, it->second.authList}
574 };
575 tokenArray.push_back(tokenObject);
576 }
577 auto jsonObject = Json {
578 {OWNER, owner_},
579 {NAME, name_},
580 {ALIAS, alias_},
581 {EXTRA_INFO, extraInfo_},
582 {AUTHORIZED_APPS, authorizedApps_},
583 {SYNC_ENABLE, syncEnable_},
584 {ASSOCIATED_DATA, associatedData_},
585 {ACCOUNT_CREDENTIAL, accountCredential_},
586 {OAUTH_TOKEN_INFOS, tokenArray},
587 };
588
589 return jsonObject;
590 }
591
ParseTokenInfosFromJson(const Json & jsonObject)592 void AppAccountInfo::ParseTokenInfosFromJson(const Json &jsonObject)
593 {
594 oauthTokens_.clear();
595 for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
596 OAuthTokenInfo tokenInfo;
597 if (it->find(OAUTH_TOKEN) != it->end() && it->at(OAUTH_TOKEN).is_string()) {
598 it->at(OAUTH_TOKEN).get_to(tokenInfo.token);
599 }
600 if (it->find(OAUTH_TOKEN_STATUS) != it->end() && it->at(OAUTH_TOKEN_STATUS).is_boolean()) {
601 it->at(OAUTH_TOKEN_STATUS).get_to(tokenInfo.status);
602 }
603 if (it->find(OAUTH_TYPE) != it->end() && it->at(OAUTH_TYPE).is_string()) {
604 it->at(OAUTH_TYPE).get_to(tokenInfo.authType);
605 }
606 if (it->find(OAUTH_AUTH_LIST) != it->end() && it->at(OAUTH_AUTH_LIST).is_array()) {
607 it->at(OAUTH_AUTH_LIST).get_to(tokenInfo.authList);
608 }
609 oauthTokens_.emplace(tokenInfo.authType, tokenInfo);
610 }
611 }
612
FromJson(const Json & jsonObject)613 bool AppAccountInfo::FromJson(const Json &jsonObject)
614 {
615 const auto &jsonObjectEnd = jsonObject.end();
616
617 OHOS::AccountSA::GetDataByType<std::string>(
618 jsonObject, jsonObjectEnd, OWNER, owner_, OHOS::AccountSA::JsonType::STRING);
619 OHOS::AccountSA::GetDataByType<std::string>(
620 jsonObject, jsonObjectEnd, NAME, name_, OHOS::AccountSA::JsonType::STRING);
621 OHOS::AccountSA::GetDataByType<std::string>(
622 jsonObject, jsonObjectEnd, ALIAS, alias_, OHOS::AccountSA::JsonType::STRING);
623 OHOS::AccountSA::GetDataByType<std::string>(
624 jsonObject, jsonObjectEnd, EXTRA_INFO, extraInfo_, OHOS::AccountSA::JsonType::STRING);
625 OHOS::AccountSA::GetDataByType<bool>(
626 jsonObject, jsonObjectEnd, SYNC_ENABLE, syncEnable_, OHOS::AccountSA::JsonType::BOOLEAN);
627 OHOS::AccountSA::GetDataByType<std::set<std::string>>(
628 jsonObject, jsonObjectEnd, AUTHORIZED_APPS, authorizedApps_, OHOS::AccountSA::JsonType::ARRAY);
629 OHOS::AccountSA::GetDataByType<std::string>(
630 jsonObject, jsonObjectEnd, ASSOCIATED_DATA, associatedData_, OHOS::AccountSA::JsonType::STRING);
631 OHOS::AccountSA::GetDataByType<std::string>(
632 jsonObject, jsonObjectEnd, ACCOUNT_CREDENTIAL, accountCredential_, OHOS::AccountSA::JsonType::STRING);
633 if (jsonObject.find(OAUTH_TOKEN_INFOS) != jsonObjectEnd) {
634 ParseTokenInfosFromJson(jsonObject.at(OAUTH_TOKEN_INFOS));
635 }
636 return true;
637 }
638
ToString() const639 std::string AppAccountInfo::ToString() const
640 {
641 auto jsonObject = ToJson();
642 try {
643 return jsonObject.dump();
644 } catch (Json::type_error& err) {
645 ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
646 return "";
647 }
648 }
649
GetPrimeKey() const650 std::string AppAccountInfo::GetPrimeKey() const
651 {
652 return (owner_ + HYPHEN + std::to_string(appIndex_) + HYPHEN + name_ + HYPHEN);
653 }
654
GetAlias()655 std::string AppAccountInfo::GetAlias()
656 {
657 #ifdef HAS_ASSET_PART
658 if (alias_.empty()) {
659 ComputeHash(GetPrimeKey(), alias_);
660 }
661 #endif
662 return alias_;
663 }
664
ReadFromParcel(Parcel & parcel)665 bool AppAccountInfo::ReadFromParcel(Parcel &parcel)
666 {
667 if (!parcel.ReadString(owner_)) {
668 ACCOUNT_LOGE("failed to read string for owner_");
669 return false;
670 }
671
672 if (!parcel.ReadString(name_)) {
673 ACCOUNT_LOGE("failed to read string for name_");
674 return false;
675 }
676
677 if (!parcel.ReadString(extraInfo_)) {
678 ACCOUNT_LOGE("failed to read string for extraInfo_");
679 return false;
680 }
681
682 if (!ReadStringSet(authorizedApps_, parcel)) {
683 ACCOUNT_LOGE("failed to read string set for authorizedApps_");
684 return false;
685 }
686
687 if (!parcel.ReadBool(syncEnable_)) {
688 ACCOUNT_LOGE("failed to read string for syncEnable_");
689 return false;
690 }
691
692 if (!parcel.ReadString(associatedData_)) {
693 ACCOUNT_LOGE("failed to read string for associatedData_");
694 return false;
695 }
696
697 if (!parcel.ReadString(accountCredential_)) {
698 ACCOUNT_LOGE("failed to read string for accountCredential_");
699 return false;
700 }
701
702 if (!ReadTokenInfos(oauthTokens_, parcel)) {
703 ACCOUNT_LOGE("failed to read string map for oauthTokens_");
704 return false;
705 }
706 return true;
707 }
708
WriteStringSet(const std::set<std::string> & stringSet,Parcel & data) const709 bool AppAccountInfo::WriteStringSet(const std::set<std::string> &stringSet, Parcel &data) const
710 {
711 if (!data.WriteUint32(stringSet.size())) {
712 ACCOUNT_LOGE("failed to WriteInt32 for stringSet.size()");
713 return false;
714 }
715
716 for (auto it : stringSet) {
717 if (!data.WriteString(it)) {
718 ACCOUNT_LOGE("failed to WriteString for it");
719 return false;
720 }
721 }
722
723 return true;
724 }
725
ReadStringSet(std::set<std::string> & stringSet,Parcel & data)726 bool AppAccountInfo::ReadStringSet(std::set<std::string> &stringSet, Parcel &data)
727 {
728 uint32_t size = 0;
729 if (!data.ReadUint32(size)) {
730 ACCOUNT_LOGE("failed to ReadInt32 for size");
731 return false;
732 }
733
734 if (size > Constants::MAX_CUSTOM_DATA_SIZE) {
735 ACCOUNT_LOGE("ReadStringSet oversize");
736 return false;
737 }
738 stringSet.clear();
739 for (uint32_t index = 0; index < size; index += 1) {
740 std::string it = data.ReadString();
741 if (it.size() == 0) {
742 ACCOUNT_LOGE("failed to ReadString for it");
743 return false;
744 }
745 stringSet.emplace(it);
746 }
747
748 return true;
749 }
750
WriteStringMap(const std::map<std::string,std::string> & stringMap,Parcel & data) const751 bool AppAccountInfo::WriteStringMap(const std::map<std::string, std::string> &stringMap, Parcel &data) const
752 {
753 if (!data.WriteInt32(stringMap.size())) {
754 ACCOUNT_LOGE("failed to WriteInt32 for stringSet.size()");
755 return false;
756 }
757
758 for (auto& it : stringMap) {
759 if (!data.WriteString(it.first)) {
760 ACCOUNT_LOGE("failed to WriteString for authType");
761 return false;
762 }
763 if (!data.WriteString(it.second)) {
764 ACCOUNT_LOGE("failed to WriteString for token");
765 return false;
766 }
767 }
768
769 return true;
770 }
771
WriteTokenInfos(const std::map<std::string,OAuthTokenInfo> & tokenInfos,Parcel & data) const772 bool AppAccountInfo::WriteTokenInfos(const std::map<std::string, OAuthTokenInfo> &tokenInfos, Parcel &data) const
773 {
774 if (!data.WriteUint32(tokenInfos.size())) {
775 ACCOUNT_LOGE("failed to WriteInt32 for stringSet.size()");
776 return false;
777 }
778 for (auto& it : tokenInfos) {
779 if (!data.WriteString(it.first)) {
780 ACCOUNT_LOGE("failed to WriteString for authType");
781 return false;
782 }
783 if (!data.WriteString(it.second.token)) {
784 ACCOUNT_LOGE("failed to WriteString for token");
785 return false;
786 }
787 if (!WriteStringSet(it.second.authList, data)) {
788 ACCOUNT_LOGE("failed to WriteString for authList");
789 return false;
790 }
791 }
792 return true;
793 }
794
ReadStringMap(std::map<std::string,std::string> & stringMap,Parcel & data)795 bool AppAccountInfo::ReadStringMap(std::map<std::string, std::string> &stringMap, Parcel &data)
796 {
797 int32_t size = 0;
798 if (!data.ReadInt32(size)) {
799 ACCOUNT_LOGE("failed to ReadInt32 for size");
800 return false;
801 }
802 if ((size < 0) || (size > MAX_MAP_SZIE)) {
803 ACCOUNT_LOGE("ReadStringMap oversize");
804 return false;
805 }
806 stringMap.clear();
807 for (int32_t index = 0; index < size; ++index) {
808 std::string key;
809 std::string value;
810 if (!data.ReadString(key)) {
811 ACCOUNT_LOGE("failed to ReadString for key");
812 return false;
813 }
814 if (!data.ReadString(value)) {
815 ACCOUNT_LOGE("failed to ReadString for value");
816 return false;
817 }
818 stringMap.emplace(key, value);
819 }
820
821 return true;
822 }
823
ReadTokenInfos(std::map<std::string,OAuthTokenInfo> & tokenInfos,Parcel & data)824 bool AppAccountInfo::ReadTokenInfos(std::map<std::string, OAuthTokenInfo> &tokenInfos, Parcel &data)
825 {
826 uint32_t size = 0;
827 if (!data.ReadUint32(size)) {
828 ACCOUNT_LOGE("failed to ReadInt32 for size");
829 return false;
830 }
831 if (size > MAX_TOKEN_NUMBER) {
832 ACCOUNT_LOGE("invalid token number");
833 return false;
834 }
835 tokenInfos.clear();
836 for (uint32_t index = 0; index < size; ++index) {
837 OAuthTokenInfo tokenInfo;
838 if (!data.ReadString(tokenInfo.authType)) {
839 ACCOUNT_LOGE("failed to ReadString for authType");
840 return false;
841 }
842 if (!data.ReadString(tokenInfo.token)) {
843 ACCOUNT_LOGE("failed to ReadString for token");
844 return false;
845 }
846 if (!ReadStringSet(tokenInfo.authList, data)) {
847 ACCOUNT_LOGE("failed to ReadString for authList");
848 return false;
849 }
850 tokenInfos.emplace(tokenInfo.authType, tokenInfo);
851 }
852 return true;
853 }
854 } // namespace AccountSA
855 } // namespace OHOS
856