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