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