1 /*
2  * Copyright (c) 2021-2022 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_control_manager.h"
17 
18 #include "accesstoken_kit.h"
19 #include "account_log_wrapper.h"
20 #include "account_permission_manager.h"
21 #include "app_account_app_state_observer.h"
22 #include "app_account_check_labels_session.h"
23 #include "app_account_data_storage.h"
24 #include "app_account_info.h"
25 #include "app_account_subscribe_manager.h"
26 #ifdef HAS_ASSET_PART
27 #include "asset_system_api.h"
28 #endif
29 #include "bundle_manager_adapter.h"
30 #include "ipc_skeleton.h"
31 #include "iservice_registry.h"
32 #include "ohos_account_kits.h"
33 #include "singleton.h"
34 #include "system_ability_definition.h"
35 
36 namespace OHOS {
37 namespace AccountSA {
38 namespace {
39 const std::string GET_ALL_APP_ACCOUNTS = "ohos.permission.GET_ALL_APP_ACCOUNTS";
40 const std::string DATA_STORAGE_SUFFIX = "_sync";
41 const std::string DATA_STORAGE_PREFIX = "encrypt_";
42 const std::string EL2_DATA_STORE_PREFIX = "account_";
43 const std::string EL2_DATA_STORAGE_PATH_PREFIX = "/data/service/el2/";
44 const std::string EL2_DATA_STORAGE_PATH_SUFFIX = "/account/app_account/database/";
45 const std::string AUTHORIZED_ACCOUNTS = "authorizedAccounts";
46 #ifdef HAS_ASSET_PART
47 const std::string ALIAS_SUFFIX_CREDENTIAL = "credential";
48 const std::string ALIAS_SUFFIX_TOKEN = "token";
49 #endif
50 }
51 
52 #ifdef HAS_ASSET_PART
SaveDataToAsset(int32_t localId,const std::string & hapLabel,const std::string & accountLabel,const std::string & alias,const std::string & value)53 static ErrCode SaveDataToAsset(int32_t localId, const std::string &hapLabel, const std::string &accountLabel,
54     const std::string &alias, const std::string &value)
55 {
56     if (value.empty()) {
57         return ERR_OK;
58     }
59     AssetValue hapLabelValue = { .blob = { static_cast<uint32_t>(hapLabel.size()),
60         const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(hapLabel.c_str())) } };
61     AssetValue accountLabelValue = { .blob = { static_cast<uint32_t>(accountLabel.size()),
62         const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(accountLabel.c_str())) } };
63     AssetValue aliasValue = { .blob = { static_cast<uint32_t>(alias.size()),
64         const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(alias.c_str())) } };
65     AssetValue secretValue = { .blob = { static_cast<uint32_t>(value.size()),
66         const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.c_str())) } };
67     AssetValue accessibilityValue;
68     if (localId == 0) {
69         accessibilityValue.u32 = SEC_ASSET_ACCESSIBILITY_DEVICE_POWERED_ON;
70     } else {
71         accessibilityValue.u32 = SEC_ASSET_ACCESSIBILITY_DEVICE_UNLOCKED;
72     }
73     std::vector<AssetAttr> attrs = {
74         { .tag = SEC_ASSET_TAG_SECRET, .value = secretValue },
75         { .tag = SEC_ASSET_TAG_DATA_LABEL_NORMAL_1, .value = hapLabelValue },
76         { .tag = SEC_ASSET_TAG_DATA_LABEL_NORMAL_2, .value = accountLabelValue },
77         { .tag = SEC_ASSET_TAG_ACCESSIBILITY, .value = accessibilityValue },
78         { .tag = SEC_ASSET_TAG_ALIAS, .value = aliasValue }
79     };
80     uint32_t queryCnt = 1;
81     if (localId != 0) {
82         AssetValue localIdValue = { .u32 = localId };
83         attrs.push_back({ .tag = SEC_ASSET_TAG_USER_ID, .value = localIdValue });
84         queryCnt++;
85     }
86     const AssetAttr *attrArr = attrs.data();
87     ErrCode ret = AssetAdd(attrArr, attrs.size());
88     if (ret == SEC_ASSET_DUPLICATED) {
89         ret = AssetUpdate(&attrArr[4], queryCnt, attrArr, 1);  // 4 indicates the index four
90     }
91     if (ret != ERR_OK) {
92         ACCOUNT_LOGE("fail to save data to asset, error code: %{public}d", ret);
93     }
94     return ret;
95 }
96 
GetDataFromAsset(int32_t localId,const std::string & alias,std::string & value)97 static ErrCode GetDataFromAsset(int32_t localId, const std::string &alias, std::string &value)
98 {
99     AssetValue aliasValue = { .blob = { static_cast<uint32_t>(alias.size()),
100         const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(alias.c_str())) } };
101     AssetValue u32Value = { .u32 = SEC_ASSET_RETURN_ALL };
102     std::vector<AssetAttr> attrs = {
103         { .tag = SEC_ASSET_TAG_ALIAS, .value = aliasValue },
104         { .tag = SEC_ASSET_TAG_RETURN_TYPE, .value = u32Value }
105     };
106     if (localId != 0) {
107         AssetValue localIdValue = { .u32 = localId };
108         attrs.push_back({ .tag = SEC_ASSET_TAG_USER_ID, .value = localIdValue });
109     }
110 
111     AssetResultSet resultSet = {0};
112     ErrCode ret = AssetQuery(attrs.data(), attrs.size(), &resultSet);
113     if (ret != SEC_ASSET_SUCCESS) {
114         ACCOUNT_LOGE("fail to get data from asset, error code: %{public}d", ret);
115     } else {
116         AssetAttr *secret = AssetParseAttr(resultSet.results, SEC_ASSET_TAG_SECRET);
117         if (secret == nullptr) {
118             ACCOUNT_LOGE("secret is nullptr");
119             ret = ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
120         } else {
121             AssetBlob valueBlob = secret->value.blob;
122             value = std::string(reinterpret_cast<const char *>(valueBlob.data), valueBlob.size);
123         }
124     }
125     AssetFreeResultSet(&resultSet);
126     return ret;
127 }
128 
RemoveDataFromAsset(int32_t localId,const std::string & alias)129 static ErrCode RemoveDataFromAsset(int32_t localId, const std::string &alias)
130 {
131     AssetValue aliasValue = { .blob = { static_cast<uint32_t>(alias.size()),
132         const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(alias.c_str())) } };
133     std::vector<AssetAttr> attrs = {
134         { .tag = SEC_ASSET_TAG_ALIAS, .value = aliasValue }
135     };
136     if (localId != 0) {
137         AssetValue localIdValue = { .u32 = localId };
138         attrs.push_back({ .tag = SEC_ASSET_TAG_USER_ID, .value = localIdValue });
139     }
140 
141     ErrCode ret = AssetRemove(attrs.data(), attrs.size());
142     if (ret != SEC_ASSET_SUCCESS) {
143         ACCOUNT_LOGE("fail to remove data from asset");
144     }
145     return ret;
146 }
147 
RemoveDataFromAssetByLabel(int32_t localId,int32_t tag,const std::string & label)148 static ErrCode RemoveDataFromAssetByLabel(int32_t localId, int32_t tag, const std::string &label)
149 {
150     AssetValue labelValue = { .blob = { static_cast<uint32_t>(label.size()),
151         const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(label.c_str())) } };
152     std::vector<AssetAttr> attrs = { { .tag = tag, .value = labelValue } };
153     if (localId != 0) {
154         AssetValue localIdValue = { .u32 = localId };
155         attrs.push_back({ .tag = SEC_ASSET_TAG_USER_ID, .value = localIdValue });
156     }
157 
158     ErrCode ret = AssetRemove(attrs.data(), attrs.size());
159     if (ret != SEC_ASSET_SUCCESS) {
160         ACCOUNT_LOGE("fail to remove data from asset");
161     }
162     return ret;
163 }
164 #endif
165 
MoveData()166 void AppAccountControlManager::MoveData()
167 {
168     DistributedKv::DistributedKvDataManager dataManager;
169     DistributedKv::AppId appId = { .appId = Constants::APP_ACCOUNT_APP_ID };
170     std::vector<DistributedKv::StoreId> storeIdList;
171     std::lock_guard<std::mutex> storeIdLock(storePtrMutex_);
172     OHOS::DistributedKv::Status status = dataManager.GetAllKvStoreId(appId, storeIdList);
173     if (status != OHOS::DistributedKv::Status::SUCCESS) {
174         ACCOUNT_LOGE("GetAllKvStoreId failed, status=%{public}u", status);
175         return;
176     }
177     std::lock_guard<std::mutex> accountIdLock(migratedAccountMutex_);
178     while (!migratedAccounts_.empty()) {
179         std::string userId = std::to_string(*(migratedAccounts_.begin()));
180         for (std::string &storeId : storeIdList) {
181             if (storeId.find(EL2_DATA_STORE_PREFIX) != std::string::npos
182                 || storeId.find(userId) == std::string::npos) {
183                 continue;
184             }
185             AccountDataStorageOptions options;
186             if (storeId.find(DATA_STORAGE_PREFIX) != std::string::npos) {
187                 options.encrypt = true;
188             }
189             ACCOUNT_LOGI("MoveData start, storeId=%{public}s", storeId.c_str());
190             auto oldPtr = std::make_shared<AppAccountDataStorage>(storeId, options);
191             options.encrypt = false;
192             options.area = DistributedKv::EL2;
193             options.baseDir = EL2_DATA_STORAGE_PATH_PREFIX + userId + EL2_DATA_STORAGE_PATH_SUFFIX;
194             auto newPtr = std::make_shared<AppAccountDataStorage>(EL2_DATA_STORE_PREFIX + userId, options);
195             ErrCode result = newPtr->MoveData(oldPtr);
196             if (result != ERR_OK) {
197                 ACCOUNT_LOGE("MoveData failed, storeId=%{public}s, result=%{public}u",
198                     storeId.c_str(), result);
199                 continue;
200             }
201             result = oldPtr->DeleteKvStore();
202             if (result != ERR_OK) {
203                 ACCOUNT_LOGE("DeleteKvStore failed, storeId=%{public}s, result=%{public}u", storeId.c_str(), result);
204             }
205         }
206         migratedAccounts_.erase(migratedAccounts_.begin());
207     }
208     ACCOUNT_LOGI("MoveData complete");
209 }
210 
AddMigratedAccount(int32_t localId)211 void AppAccountControlManager::AddMigratedAccount(int32_t localId)
212 {
213     {
214         std::lock_guard<std::mutex> lock(migratedAccountMutex_);
215         migratedAccounts_.insert(localId);
216     }
217     MoveData();
218 }
219 
GetInstance()220 AppAccountControlManager &AppAccountControlManager::GetInstance()
221 {
222     static AppAccountControlManager *instance = new (std::nothrow) AppAccountControlManager();
223     return *instance;
224 }
225 
AddAccount(const std::string & name,const std::string & extraInfo,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)226 ErrCode AppAccountControlManager::AddAccount(const std::string &name, const std::string &extraInfo, const uid_t &uid,
227     const std::string &bundleName, AppAccountInfo &appAccountInfo)
228 {
229     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
230     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
231     if (result != ERR_OK) {
232         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
233 
234         appAccountInfo.SetExtraInfo(extraInfo);
235 
236         result = AddAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
237         if (result != ERR_OK) {
238             ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
239             return result;
240         }
241     } else {
242         ACCOUNT_LOGE("add existing account");
243         return ERR_APPACCOUNT_SERVICE_ADD_EXISTING_ACCOUNT;
244     }
245 
246     return ERR_OK;
247 }
248 
CreateAccount(const std::string & name,const CreateAccountOptions & options,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)249 ErrCode AppAccountControlManager::CreateAccount(const std::string &name, const CreateAccountOptions &options,
250     const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
251 {
252     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
253     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
254     if (result != ERR_OK) {
255         result = appAccountInfo.InitCustomData(options.customData);
256         if (result != ERR_OK) {
257             ACCOUNT_LOGE("failed to set custom data, result %{public}d.", result);
258             return ERR_APPACCOUNT_SERVICE_SET_ASSOCIATED_DATA;
259         }
260         result = AddAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
261         if (result != ERR_OK) {
262             ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
263             return result;
264         }
265     } else {
266         ACCOUNT_LOGE("add existing account");
267         return ERR_APPACCOUNT_SERVICE_ADD_EXISTING_ACCOUNT;
268     }
269 
270     return ERR_OK;
271 }
272 
DeleteAccount(const std::string & name,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)273 ErrCode AppAccountControlManager::DeleteAccount(
274     const std::string &name, const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
275 {
276     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
277     ErrCode result = DeleteAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr, uid);
278     if (result != ERR_OK) {
279         ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
280         return result;
281     }
282     RemoveAssociatedDataCacheByAccount(uid, name);
283 #ifdef HAS_ASSET_PART
284     RemoveDataFromAssetByLabel(uid / UID_TRANSFORM_DIVISOR, SEC_ASSET_TAG_DATA_LABEL_NORMAL_2,
285         appAccountInfo.GetPrimeKey());
286 #endif
287 
288     std::set<std::string> authorizedApps;
289     appAccountInfo.GetAuthorizedApps(authorizedApps);
290     for (auto authorizedApp : authorizedApps) {
291         // remove authorized account from data storage
292         result = RemoveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, uid);
293         if (result != ERR_OK) {
294             ACCOUNT_LOGE("failed to save authorized account into data storage, result %{public}d.", result);
295             return result;
296         }
297     }
298 
299     return ERR_OK;
300 }
301 
GetAccountExtraInfo(const std::string & name,std::string & extraInfo,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)302 ErrCode AppAccountControlManager::GetAccountExtraInfo(const std::string &name, std::string &extraInfo,
303     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
304 {
305     AppAccountInfo appAccountInfo(name, bundleName);
306     appAccountInfo.SetAppIndex(appIndex);
307     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
308     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
309     if (result != ERR_OK) {
310         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
311         return result;
312     }
313 
314     appAccountInfo.GetExtraInfo(extraInfo);
315 
316     return ERR_OK;
317 }
318 
SetAccountExtraInfo(const std::string & name,const std::string & extraInfo,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)319 ErrCode AppAccountControlManager::SetAccountExtraInfo(const std::string &name, const std::string &extraInfo,
320     const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
321 {
322     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
323     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
324     if (result != ERR_OK) {
325         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
326         return result;
327     }
328 
329     appAccountInfo.SetExtraInfo(extraInfo);
330 
331     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
332     if (result != ERR_OK) {
333         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
334         return result;
335     }
336 
337     ACCOUNT_LOGD("end, result = %{public}d", result);
338 
339     return result;
340 }
341 
EnableAppAccess(const std::string & name,const std::string & authorizedApp,AppAccountCallingInfo & appAccountCallingInfo,AppAccountInfo & appAccountInfo,const uint32_t apiVersion)342 ErrCode AppAccountControlManager::EnableAppAccess(const std::string &name, const std::string &authorizedApp,
343     AppAccountCallingInfo &appAccountCallingInfo, AppAccountInfo &appAccountInfo, const uint32_t apiVersion)
344 {
345     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
346     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
347     if (result != ERR_OK) {
348         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
349         return result;
350     }
351 
352     result = appAccountInfo.EnableAppAccess(authorizedApp, apiVersion);
353     if (result != ERR_OK) {
354         ACCOUNT_LOGE("Failed to enable app access, result=%{public}d.", result);
355         return result;
356     }
357     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
358     if (result != ERR_OK) {
359         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
360         return result;
361     }
362 
363     // save authorized account into data storage
364     result = SaveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
365     if (result != ERR_OK) {
366         ACCOUNT_LOGE("Failed to save authorized account into data storage, result=%{public}d.", result);
367         return result;
368     }
369 
370     return ERR_OK;
371 }
372 
DisableAppAccess(const std::string & name,const std::string & authorizedApp,AppAccountCallingInfo & appAccountCallingInfo,AppAccountInfo & appAccountInfo,const uint32_t apiVersion)373 ErrCode AppAccountControlManager::DisableAppAccess(const std::string &name, const std::string &authorizedApp,
374     AppAccountCallingInfo &appAccountCallingInfo, AppAccountInfo &appAccountInfo, const uint32_t apiVersion)
375 {
376     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
377     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
378     if (result != ERR_OK) {
379         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
380         return result;
381     }
382 
383     result = appAccountInfo.DisableAppAccess(authorizedApp, apiVersion);
384     if (result != ERR_OK) {
385         ACCOUNT_LOGE("failed to disable app access, result %{public}d.", result);
386         return ERR_APPACCOUNT_SERVICE_DISABLE_APP_ACCESS_NOT_EXISTED;
387     }
388 
389     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
390     if (result != ERR_OK) {
391         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
392         return result;
393     }
394 
395     // remove authorized account from data storage
396     result = RemoveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
397     if (result != ERR_OK) {
398         ACCOUNT_LOGE("failed to save authorized account into data storage, result %{public}d.", result);
399         return result;
400     }
401 
402     return ERR_OK;
403 }
404 
CheckAppAccess(const std::string & name,const std::string & authorizedApp,bool & isAccessible,const AppAccountCallingInfo & appAccountCallingInfo)405 ErrCode AppAccountControlManager::CheckAppAccess(const std::string &name, const std::string &authorizedApp,
406     bool &isAccessible, const AppAccountCallingInfo &appAccountCallingInfo)
407 {
408     isAccessible = false;
409     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
410     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
411     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
412     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
413     if (result != ERR_OK) {
414         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
415         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
416     }
417     return appAccountInfo.CheckAppAccess(authorizedApp, isAccessible);
418 }
419 
CheckAppAccountSyncEnable(const std::string & name,bool & syncEnable,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)420 ErrCode AppAccountControlManager::CheckAppAccountSyncEnable(const std::string &name,
421     bool &syncEnable, const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
422 {
423     AppAccountInfo appAccountInfo(name, bundleName);
424     appAccountInfo.SetAppIndex(appIndex);
425     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
426     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
427     if (result != ERR_OK) {
428         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
429         return result;
430     }
431 
432     appAccountInfo.GetSyncEnable(syncEnable);
433 
434     return ERR_OK;
435 }
436 
SetAppAccountSyncEnable(const std::string & name,const bool & syncEnable,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)437 ErrCode AppAccountControlManager::SetAppAccountSyncEnable(const std::string &name, const bool &syncEnable,
438     const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
439 {
440     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
441     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
442     if (result != ERR_OK) {
443         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
444         return result;
445     }
446 
447     appAccountInfo.SetSyncEnable(syncEnable);
448 
449     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
450     if (result != ERR_OK) {
451         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
452         return result;
453     }
454 
455     return ERR_OK;
456 }
457 
PopDataFromAssociatedDataCache()458 void AppAccountControlManager::PopDataFromAssociatedDataCache()
459 {
460     auto it = associatedDataCache_.begin();
461     auto toPopedIt = it++;
462     for (; it != associatedDataCache_.end(); ++it) {
463         if (toPopedIt->second.freq > it->second.freq) {
464             toPopedIt = it;
465         }
466         it->second.freq = 0;
467     }
468     associatedDataCache_.erase(toPopedIt);
469 }
470 
GetAssociatedDataFromStorage(const std::string & name,const std::string & key,std::string & value,const uid_t & uid,const uint32_t & appIndex)471 ErrCode AppAccountControlManager::GetAssociatedDataFromStorage(const std::string &name, const std::string &key,
472     std::string &value, const uid_t &uid, const uint32_t &appIndex)
473 {
474     std::string bundleName;
475     if (BundleManagerAdapter::GetInstance()->GetNameForUid(uid, bundleName) != ERR_OK) {
476         ACCOUNT_LOGE("failed to get bundle name");
477         return ERR_APPACCOUNT_SERVICE_GET_BUNDLE_NAME;
478     }
479     AppAccountInfo appAccountInfo(name, bundleName);
480     appAccountInfo.SetAppIndex(appIndex);
481     std::shared_ptr<AppAccountDataStorage> storePtr = GetDataStorage(uid);
482     if (storePtr == nullptr) {
483         ACCOUNT_LOGE("failed to get data storage");
484         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
485     }
486     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, storePtr);
487     if (result != ERR_OK) {
488         ACCOUNT_LOGE("failed to get account info from data storage");
489         return result;
490     }
491     AssociatedDataCacheItem item;
492     item.name = name;
493     item.freq = 0;
494     appAccountInfo.GetAllAssociatedData(item.data);
495     auto it = item.data.find(key);
496     if (it != item.data.end()) {
497         value = it->second;
498     } else {
499         result = ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_KEY_NOT_EXIST;
500     }
501     if ((associatedDataCache_.size() == 0) && (!RegisterApplicationStateObserver())) {
502         ACCOUNT_LOGE("failed to register application state observer");
503         return result;
504     }
505     if (associatedDataCache_.size() >= ASSOCIATED_DATA_CACHE_MAX_SIZE) {
506         PopDataFromAssociatedDataCache();
507     }
508     associatedDataCache_.emplace(uid, item);
509     return result;
510 }
511 
GetAssociatedData(const std::string & name,const std::string & key,std::string & value,const uid_t & uid)512 ErrCode AppAccountControlManager::GetAssociatedData(const std::string &name, const std::string &key,
513     std::string &value, const uid_t &uid)
514 {
515     std::lock_guard<std::mutex> lock(associatedDataMutex_);
516     auto it = associatedDataCache_.find(uid);
517     if ((it == associatedDataCache_.end()) || (it->second.name != name)) {
518         uint32_t callingTokenId = IPCSkeleton::GetCallingTokenID();
519         Security::AccessToken::HapTokenInfo hapTokenInfo;
520         int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callingTokenId, hapTokenInfo);
521         if ((result != 0) || (hapTokenInfo.instIndex < 0)) {
522             ACCOUNT_LOGE("failed to get app index");
523             return ERR_APPACCOUNT_SERVICE_GET_APP_INDEX;
524         }
525         associatedDataCache_.erase(uid);
526         return GetAssociatedDataFromStorage(name, key, value, uid, hapTokenInfo.instIndex);
527     }
528     it->second.freq++;
529     auto dataIt = it->second.data.find(key);
530     if (dataIt == it->second.data.end()) {
531         return ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_KEY_NOT_EXIST;
532     }
533     value = dataIt->second;
534     return ERR_OK;
535 }
536 
SetAssociatedData(const std::string & name,const std::string & key,const std::string & value,const AppAccountCallingInfo & appAccountCallingInfo)537 ErrCode AppAccountControlManager::SetAssociatedData(const std::string &name, const std::string &key,
538     const std::string &value, const AppAccountCallingInfo &appAccountCallingInfo)
539 {
540     std::shared_ptr<AppAccountDataStorage> storePtr = GetDataStorage(appAccountCallingInfo.callingUid);
541     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
542     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
543     std::lock_guard<std::mutex> lock(associatedDataMutex_);
544     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, storePtr);
545     if (result != ERR_OK) {
546         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
547         return result;
548     }
549     result = appAccountInfo.SetAssociatedData(key, value);
550     if (result != ERR_OK) {
551         ACCOUNT_LOGE("failed to set associated data, result %{public}d.", result);
552         return result;
553     }
554     result = SaveAccountInfoIntoDataStorage(appAccountInfo, storePtr, appAccountCallingInfo.callingUid);
555     if (result != ERR_OK) {
556         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
557         return result;
558     }
559     auto it = associatedDataCache_.find(appAccountCallingInfo.callingUid);
560     if ((it != associatedDataCache_.end()) && (it->second.name == name)) {
561         it->second.data[key] = value;
562     }
563     return ERR_OK;
564 }
565 
GetAccountCredential(const std::string & name,const std::string & credentialType,std::string & credential,const AppAccountCallingInfo & appAccountCallingInfo)566 ErrCode AppAccountControlManager::GetAccountCredential(const std::string &name, const std::string &credentialType,
567     std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo)
568 {
569     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
570     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
571     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
572         GetDataStorage(appAccountCallingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
573     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
574     if (result != ERR_OK) {
575         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
576         return result;
577     }
578 
579     result = appAccountInfo.GetAccountCredential(credentialType, credential);
580     if (result != ERR_OK) {
581         return result;
582     }
583 #ifdef HAS_ASSET_PART
584     std::string alias = credential;
585     credential = "";
586     GetDataFromAsset(appAccountCallingInfo.callingUid / UID_TRANSFORM_DIVISOR, alias, credential);
587 #endif
588     return result;
589 }
590 
SetAccountCredential(const std::string & name,const std::string & credentialType,const std::string & credential,const AppAccountCallingInfo & appAccountCallingInfo)591 ErrCode AppAccountControlManager::SetAccountCredential(const std::string &name, const std::string &credentialType,
592     const std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo)
593 {
594     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
595         GetDataStorage(appAccountCallingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
596     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
597     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
598     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
599     if (result != ERR_OK) {
600         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
601         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
602     }
603     result = appAccountInfo.SetAccountCredential(credentialType, credential);
604     if (result != ERR_OK) {
605         ACCOUNT_LOGE("failed to set account credential, result %{public}d.", result);
606         return result;
607     }
608 
609     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
610     if (result != ERR_OK) {
611         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
612         return result;
613     }
614 #ifdef HAS_ASSET_PART
615     std::string hapLabel = appAccountCallingInfo.bundleName + Constants::HYPHEN +
616         std::to_string(appAccountCallingInfo.appIndex);
617     std::string credentialAlias;
618     appAccountInfo.GetAccountCredential(credentialType, credentialAlias);
619     int32_t localId = appAccountCallingInfo.callingUid / UID_TRANSFORM_DIVISOR;
620     result = SaveDataToAsset(localId, hapLabel, appAccountInfo.GetAlias(), credentialAlias, credential);
621 #endif
622     return result;
623 }
624 
DeleteAccountCredential(const std::string & name,const std::string & credentialType,const AppAccountCallingInfo & callingInfo)625 ErrCode AppAccountControlManager::DeleteAccountCredential(const std::string &name, const std::string &credentialType,
626     const AppAccountCallingInfo &callingInfo)
627 {
628     AppAccountInfo appAccountInfo(name, callingInfo.bundleName);
629     appAccountInfo.SetAppIndex(callingInfo.appIndex);
630     auto dataStoragePtr = GetDataStorage(callingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
631     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
632     if (result != ERR_OK) {
633         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
634         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
635     }
636 #ifdef HAS_ASSET_PART
637     std::string alias;
638     appAccountInfo.GetAccountCredential(credentialType, alias);
639     RemoveDataFromAsset(callingInfo.callingUid / UID_TRANSFORM_DIVISOR, alias);
640 #endif
641     result = appAccountInfo.DeleteAccountCredential(credentialType);
642     if (result != ERR_OK) {
643         ACCOUNT_LOGE("failed to delete account credential, result %{public}d.", result);
644         return result;
645     }
646 
647     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, callingInfo.callingUid);
648     if (result != ERR_OK) {
649         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
650     }
651     return result;
652 }
653 
GetOAuthToken(const AuthenticatorSessionRequest & request,std::string & token,const uint32_t apiVersion)654 ErrCode AppAccountControlManager::GetOAuthToken(
655     const AuthenticatorSessionRequest &request, std::string &token, const uint32_t apiVersion)
656 {
657     AppAccountInfo appAccountInfo(request.name, request.owner);
658     appAccountInfo.SetAppIndex(request.appIndex);
659     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
660         GetDataStorage(request.callerUid, false, DistributedKv::SecurityLevel::S4);
661     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
662     if (result != ERR_OK) {
663         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
664         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
665     }
666     bool isVisible = false;
667     result = appAccountInfo.CheckOAuthTokenVisibility(
668         request.authType, request.callerBundleName, isVisible, apiVersion);
669     if ((result != ERR_OK) || (!isVisible)) {
670         ACCOUNT_LOGE("failed to get oauth token for permission denied, result %{public}d.", result);
671         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
672     }
673     result = appAccountInfo.GetOAuthToken(request.authType, token, apiVersion);
674     if (result != ERR_OK) {
675         return result;
676     }
677 #ifdef HAS_ASSET_PART
678     std::string alias = token;
679     token = "";
680     GetDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias, token);
681     if (token.empty() && (apiVersion < Constants::API_VERSION9)) {
682         return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST;
683     }
684 #endif
685     return ERR_OK;
686 }
687 
SetOAuthToken(const AuthenticatorSessionRequest & request)688 ErrCode AppAccountControlManager::SetOAuthToken(const AuthenticatorSessionRequest &request)
689 {
690     std::lock_guard<std::mutex> lock(mutex_);
691     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
692     appAccountInfo.SetAppIndex(request.appIndex);
693     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
694         GetDataStorage(request.callerUid, false, DistributedKv::SecurityLevel::S4);
695     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
696     if (result != ERR_OK) {
697         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
698         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
699     }
700     result = appAccountInfo.SetOAuthToken(request.authType, request.token);
701     if (result != ERR_OK) {
702         ACCOUNT_LOGE("failed to set oauth token, result %{public}d.", result);
703         return result;
704     }
705     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
706     if (result != ERR_OK) {
707         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
708         return result;
709     }
710 #ifdef HAS_ASSET_PART
711     std::string hapLabel = request.callerBundleName + Constants::HYPHEN + std::to_string(request.appIndex);
712     std::string authTypeAlias;
713     appAccountInfo.GetOAuthToken(request.authType, authTypeAlias);
714     int32_t localId = request.callerUid / UID_TRANSFORM_DIVISOR;
715     result = SaveDataToAsset(localId, hapLabel, appAccountInfo.GetAlias(), authTypeAlias, request.token);
716 #endif
717     return result;
718 }
719 
DeleteOAuthToken(const AuthenticatorSessionRequest & request,const uint32_t apiVersion)720 ErrCode AppAccountControlManager::DeleteOAuthToken(
721     const AuthenticatorSessionRequest &request, const uint32_t apiVersion)
722 {
723     std::lock_guard<std::mutex> lock(mutex_);
724     AppAccountInfo appAccountInfo(request.name, request.owner);
725     appAccountInfo.SetAppIndex(request.appIndex);
726     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
727     ErrCode ret = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
728     if (ret != ERR_OK) {
729         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", ret);
730         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
731     }
732     bool isVisible = false;
733     ret = appAccountInfo.CheckOAuthTokenVisibility(request.authType, request.callerBundleName, isVisible, apiVersion);
734     if ((!isVisible) || (ret != ERR_OK)) {
735         ACCOUNT_LOGE("failed to delete oauth token for permission denied, result %{public}d.", ret);
736         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
737     }
738     std::string token = request.token;
739 #ifdef HAS_ASSET_PART
740     std::string alias;
741     ret = appAccountInfo.GetOAuthToken(request.authType, alias, apiVersion);
742     if (ret != ERR_OK) {
743         return apiVersion >= Constants::API_VERSION9 ? ret : ERR_OK;
744     }
745     GetDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias, token);
746     if (token != request.token) {
747         return ERR_OK;
748     }
749     RemoveDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias);
750     token = alias;
751 #endif
752     if (apiVersion >= Constants::API_VERSION9) {
753         bool isOwnerSelf = request.owner == request.callerBundleName;
754         ret = appAccountInfo.DeleteAuthToken(request.authType, token, isOwnerSelf);
755         if (ret != ERR_OK) {
756             return ret;
757         }
758     } else {
759         ret = appAccountInfo.DeleteOAuthToken(request.authType, token);
760         if (ret == ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST) {
761             return ERR_OK;
762         }
763     }
764     ret = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
765     if (ret != ERR_OK) {
766         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", ret);
767         return ret;
768     }
769     return ret;
770 }
771 
SetOAuthTokenVisibility(const AuthenticatorSessionRequest & request,const uint32_t apiVersion)772 ErrCode AppAccountControlManager::SetOAuthTokenVisibility(
773     const AuthenticatorSessionRequest &request, const uint32_t apiVersion)
774 {
775     std::lock_guard<std::mutex> lock(mutex_);
776     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
777     appAccountInfo.SetAppIndex(request.appIndex);
778     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
779     ErrCode ret = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
780     if (ret != ERR_OK) {
781         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", ret);
782         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
783     }
784     ret = appAccountInfo.SetOAuthTokenVisibility(
785         request.authType, request.bundleName, request.isTokenVisible, apiVersion);
786     if (ret != ERR_OK) {
787         ACCOUNT_LOGE("failed to set oauth token visibility, result %{public}d.", ret);
788         return ret;
789     }
790     ret = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
791     if (ret != ERR_OK) {
792         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", ret);
793         return ret;
794     }
795     return ERR_OK;
796 }
797 
CheckOAuthTokenVisibility(const AuthenticatorSessionRequest & request,bool & isVisible,const uint32_t apiVersion)798 ErrCode AppAccountControlManager::CheckOAuthTokenVisibility(
799     const AuthenticatorSessionRequest &request, bool &isVisible, const uint32_t apiVersion)
800 {
801     isVisible = false;
802     AppAccountInfo appAccountInfo(request.name, request.owner);
803     appAccountInfo.SetAppIndex(request.appIndex);
804     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
805     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
806     if (result != ERR_OK) {
807         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
808         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
809     }
810     return appAccountInfo.CheckOAuthTokenVisibility(request.authType, request.bundleName, isVisible, apiVersion);
811 }
812 
GetAllOAuthTokens(const AuthenticatorSessionRequest & request,std::vector<OAuthTokenInfo> & tokenInfos)813 ErrCode AppAccountControlManager::GetAllOAuthTokens(
814     const AuthenticatorSessionRequest &request, std::vector<OAuthTokenInfo> &tokenInfos)
815 {
816     tokenInfos.clear();
817     AppAccountInfo appAccountInfo(request.name, request.owner);
818     appAccountInfo.SetAppIndex(request.appIndex);
819     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
820     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
821     if (result != ERR_OK) {
822         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
823         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
824     }
825     std::vector<OAuthTokenInfo> allTokenInfos;
826     result = appAccountInfo.GetAllOAuthTokens(allTokenInfos);
827     if (result != ERR_OK) {
828         ACCOUNT_LOGE("failed to get all oauth token from data storage, result %{public}d.", result);
829         return result;
830     }
831     for (auto tokenInfo : allTokenInfos) {
832         if ((request.callerBundleName != request.owner) &&
833             (tokenInfo.authList.find(request.callerBundleName) == tokenInfo.authList.end())) {
834             continue;
835         }
836 #ifdef HAS_ASSET_PART
837         std::string alias = tokenInfo.token;
838         tokenInfo.token = "";
839         GetDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias, tokenInfo.token);
840 #endif
841         if (tokenInfo.token.empty() && tokenInfo.authList.empty()) { // for api 8 logic
842             continue;
843         }
844         tokenInfo.authList.clear();
845         tokenInfos.push_back(tokenInfo);
846     }
847     return ERR_OK;
848 }
849 
GetOAuthList(const AuthenticatorSessionRequest & request,std::set<std::string> & oauthList,const uint32_t apiVersion)850 ErrCode AppAccountControlManager::GetOAuthList(
851     const AuthenticatorSessionRequest &request, std::set<std::string> &oauthList, const uint32_t apiVersion)
852 {
853     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
854     appAccountInfo.SetAppIndex(request.appIndex);
855     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
856     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
857     if (result != ERR_OK) {
858         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
859         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
860     }
861     return appAccountInfo.GetOAuthList(request.authType, oauthList, apiVersion);
862 }
863 
GetAllAccounts(const std::string & owner,std::vector<AppAccountInfo> & appAccounts,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)864 ErrCode AppAccountControlManager::GetAllAccounts(const std::string &owner, std::vector<AppAccountInfo> &appAccounts,
865     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
866 {
867     appAccounts.clear();
868 
869     auto dataStoragePtr = GetDataStorage(uid);
870     if (dataStoragePtr == nullptr) {
871         ACCOUNT_LOGE("dataStoragePtr is nullptr");
872         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
873     }
874     ErrCode result = AccountPermissionManager::VerifyPermission(GET_ALL_APP_ACCOUNTS);
875     if ((bundleName == owner) || (result == ERR_OK)) {
876         std::string key = owner + Constants::HYPHEN + std::to_string(appIndex);
877         result = GetAllAccountsFromDataStorage(key, appAccounts, owner, dataStoragePtr);
878         if (result != ERR_OK) {
879             ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
880             return result;
881         }
882         return ERR_OK;
883     }
884 
885     std::vector<std::string> accessibleAccounts;
886     result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
887     if (result != ERR_OK) {
888         ACCOUNT_LOGE("failed to get accessible account from data storage, result %{public}d.", result);
889         return result;
890     }
891     for (auto account : accessibleAccounts) {
892         AppAccountInfo appAccountInfo;
893         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
894         if (result != ERR_OK) {
895             ACCOUNT_LOGE("failed to get account info by id, result %{public}d.", result);
896             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
897         }
898         if (appAccountInfo.GetOwner() == owner) {
899             appAccounts.emplace_back(appAccountInfo);
900         }
901     }
902     return ERR_OK;
903 }
904 
LoadAllAppAccounts(const std::shared_ptr<OHOS::AccountSA::AppAccountDataStorage> & dataStoragePtr,std::vector<AppAccountInfo> & appAccounts)905 static ErrCode LoadAllAppAccounts(const std::shared_ptr<OHOS::AccountSA::AppAccountDataStorage> &dataStoragePtr,
906     std::vector<AppAccountInfo> &appAccounts)
907 {
908     std::map<std::string, std::shared_ptr<IAccountInfo>> infos;
909     ErrCode result = dataStoragePtr->LoadAllData(infos);
910     if (result != ERR_OK) {
911         ACCOUNT_LOGE("LoadAllData failed!");
912         return result;
913     }
914     for (auto it = infos.begin(); it != infos.end(); ++it) {
915         if (it->first == AUTHORIZED_ACCOUNTS) {
916             continue;
917         }
918         AppAccountInfo curAppInfo = *(std::static_pointer_cast<AppAccountInfo>(it->second));
919         appAccounts.emplace_back(curAppInfo);
920     }
921     return ERR_OK;
922 }
923 
GetAllAccessibleAccounts(std::vector<AppAccountInfo> & appAccounts,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)924 ErrCode AppAccountControlManager::GetAllAccessibleAccounts(std::vector<AppAccountInfo> &appAccounts,
925     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
926 {
927     appAccounts.clear();
928 
929     auto dataStoragePtr = GetDataStorage(uid);
930     if (dataStoragePtr == nullptr) {
931         ACCOUNT_LOGE("dataStoragePtr is nullptr");
932         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
933     }
934     ErrCode result = AccountPermissionManager::VerifyPermission(GET_ALL_APP_ACCOUNTS);
935     if (result == ERR_OK) {
936         return LoadAllAppAccounts(dataStoragePtr, appAccounts);
937     }
938     std::vector<std::string> accessibleAccounts;
939     result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
940     if (result != ERR_OK) {
941         ACCOUNT_LOGE("failed to get accessible account from data storage, result %{public}d.", result);
942         return result;
943     }
944 
945     for (auto account : accessibleAccounts) {
946         AppAccountInfo appAccountInfo;
947 
948         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
949         if (result != ERR_OK) {
950             ACCOUNT_LOGE("failed to get account info by id, result %{public}d.", result);
951             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
952         }
953 
954         appAccounts.emplace_back(appAccountInfo);
955     }
956 
957     std::vector<AppAccountInfo> currentAppAccounts;
958     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
959     result = GetAllAccountsFromDataStorage(key, currentAppAccounts, bundleName, dataStoragePtr);
960     if (result != ERR_OK) {
961         ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
962         return result;
963     }
964 
965     std::transform(currentAppAccounts.begin(), currentAppAccounts.end(), std::back_inserter(appAccounts),
966         [](auto account) { return account; });
967 
968     return ERR_OK;
969 }
970 
SelectAccountsByOptions(const SelectAccountsOptions & options,const sptr<IAppAccountAuthenticatorCallback> & callback,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)971 ErrCode AppAccountControlManager::SelectAccountsByOptions(
972     const SelectAccountsOptions &options, const sptr<IAppAccountAuthenticatorCallback> &callback,
973     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
974 {
975     AAFwk::Want result;
976     if ((!options.hasAccounts) && (!options.hasOwners) && (!options.hasLabels)) {
977         callback->OnResult(ERR_JS_SUCCESS, result);
978         return ERR_OK;
979     }
980     std::set<std::string> allowedAccounts;
981     for (auto account : options.allowedAccounts) {
982         allowedAccounts.emplace(account.first + "_" + account.second);
983     }
984     std::set<std::string> allowedOwners(options.allowedOwners.begin(), options.allowedOwners.end());
985     std::vector<AppAccountInfo> accessibleAccounts;
986     ErrCode errCode = GetAllAccessibleAccounts(accessibleAccounts, uid, bundleName, appIndex);
987     if (errCode != ERR_OK) {
988         ACCOUNT_LOGE("failed to get all accessible accounts");
989         return errCode;
990     }
991     std::vector<AppAccountInfo> candidateAccounts;
992     for (auto account : accessibleAccounts) {
993         std::string owner = account.GetOwner();
994         if (options.hasOwners && allowedOwners.count(owner) == 0) {
995             continue;
996         }
997         if (options.hasAccounts && allowedAccounts.count(owner + "_" + account.GetName()) == 0) {
998             continue;
999         }
1000         candidateAccounts.push_back(account);
1001     }
1002     if (options.requiredLabels.size() == 0) {
1003         std::vector<std::string> names;
1004         std::vector<std::string> owners;
1005         for (auto account : candidateAccounts) {
1006             names.push_back(account.GetName());
1007             owners.push_back(account.GetOwner());
1008         }
1009         result.SetParam(Constants::KEY_ACCOUNT_NAMES, names);
1010         result.SetParam(Constants::KEY_ACCOUNT_OWNERS, owners);
1011         callback->OnResult(ERR_JS_SUCCESS, result);
1012         return ERR_OK;
1013     }
1014     AuthenticatorSessionRequest request;
1015     request.callback = callback;
1016     request.callerUid = uid;
1017     request.labels = options.requiredLabels;
1018     return AppAccountAuthenticatorSessionManager::GetInstance().SelectAccountsByOptions(candidateAccounts, request);
1019 }
1020 
RemoveAssociatedDataCacheByUid(const uid_t & uid)1021 void AppAccountControlManager::RemoveAssociatedDataCacheByUid(const uid_t &uid)
1022 {
1023     std::lock_guard<std::mutex> lock(associatedDataMutex_);
1024     associatedDataCache_.erase(uid);
1025     if (associatedDataCache_.empty()) {
1026         UnregisterApplicationStateObserver();
1027     }
1028 }
1029 
RemoveAssociatedDataCacheByAccount(const uid_t & uid,const std::string & name)1030 void AppAccountControlManager::RemoveAssociatedDataCacheByAccount(const uid_t &uid, const std::string &name)
1031 {
1032     std::lock_guard<std::mutex> lock(associatedDataMutex_);
1033     auto it = associatedDataCache_.find(uid);
1034     if ((it == associatedDataCache_.end()) || (it->second.name != name)) {
1035         return;
1036     }
1037     associatedDataCache_.erase(it);
1038     if (associatedDataCache_.empty()) {
1039         UnregisterApplicationStateObserver();
1040     }
1041 }
1042 
SetOsAccountRemoved(int32_t localId,bool isRemoved)1043 void AppAccountControlManager::SetOsAccountRemoved(int32_t localId, bool isRemoved)
1044 {
1045     if (isRemoved) {
1046         removedOsAccounts_.EnsureInsert(localId, true);
1047     } else {
1048         removedOsAccounts_.Erase(localId);
1049     }
1050 }
1051 
IsOsAccountRemoved(int32_t localId)1052 bool AppAccountControlManager::IsOsAccountRemoved(int32_t localId)
1053 {
1054     bool isRemoved = false;
1055     return removedOsAccounts_.Find(localId, isRemoved);
1056 }
1057 
OnPackageRemoved(const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)1058 ErrCode AppAccountControlManager::OnPackageRemoved(
1059     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
1060 {
1061     RemoveAssociatedDataCacheByUid(uid);
1062     int32_t localId = uid / UID_TRANSFORM_DIVISOR;
1063     if (IsOsAccountRemoved(localId)) {
1064         ACCOUNT_LOGI("Account %{public}d is removed", localId);
1065         return ERR_OK;
1066     }
1067     return RemoveAppAccountData(uid, bundleName, appIndex);
1068 }
1069 
RemoveAppAccountData(const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)1070 ErrCode AppAccountControlManager::RemoveAppAccountData(
1071     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
1072 {
1073     auto dataStoragePtr = GetDataStorage(uid);
1074     if (dataStoragePtr == nullptr) {
1075         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1076         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1077     }
1078 #ifdef DISTRIBUTED_FEATURE_ENABLED
1079     auto dataStorageSyncPtr = GetDataStorage(uid, true);
1080     if (dataStorageSyncPtr == nullptr) {
1081         ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1082         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1083     }
1084 #endif // DISTRIBUTED_FEATURE_ENABLED
1085     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
1086     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
1087     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(key, accounts);
1088     if (result != ERR_OK) {
1089         ACCOUNT_LOGE("failed to get accounts by owner, result %{public}d, bundleName = %{public}s",
1090             result, bundleName.c_str());
1091         return result;
1092     }
1093     AppAccountInfo appAccountInfo;
1094     for (auto account : accounts) {
1095         appAccountInfo = *(std::static_pointer_cast<AppAccountInfo>(account.second));
1096         std::set<std::string> authorizedApps;
1097         appAccountInfo.GetAuthorizedApps(authorizedApps);
1098         appAccountInfo.SetAppIndex(appIndex);
1099         for (auto authorizedApp : authorizedApps) {
1100             RemoveAuthorizedAccountFromDataStorage(authorizedApp, appAccountInfo, dataStoragePtr);
1101 #ifdef DISTRIBUTED_FEATURE_ENABLED
1102             if (NeedSyncDataStorage(appAccountInfo) == true) {
1103                 RemoveAuthorizedAccountFromDataStorage(authorizedApp, appAccountInfo, dataStorageSyncPtr);
1104             }
1105 #endif // DISTRIBUTED_FEATURE_ENABLED
1106         }
1107         dataStoragePtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1108 #ifdef DISTRIBUTED_FEATURE_ENABLED
1109         if (NeedSyncDataStorage(appAccountInfo) == true) {
1110             dataStorageSyncPtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1111         }
1112 #else  // DISTRIBUTED_FEATURE_ENABLED
1113         ACCOUNT_LOGI("No distributed feature!");
1114 #endif // DISTRIBUTED_FEATURE_ENABLED
1115     }
1116 #ifdef HAS_ASSET_PART
1117     RemoveDataFromAssetByLabel(uid / UID_TRANSFORM_DIVISOR, SEC_ASSET_TAG_DATA_LABEL_NORMAL_1, key);
1118 #endif
1119     return ERR_OK;
1120 }
1121 
OnUserRemoved(int32_t userId)1122 ErrCode AppAccountControlManager::OnUserRemoved(int32_t userId)
1123 {
1124     std::string storeId = std::to_string(userId);
1125     std::string syncStoreId = storeId + DATA_STORAGE_SUFFIX;
1126     std::lock_guard<std::mutex> lock(storePtrMutex_);
1127     storePtrMap_.erase(storeId);
1128     storePtrMap_.erase(syncStoreId);
1129     return ERR_OK;
1130 }
1131 
RegisterApplicationStateObserver()1132 bool AppAccountControlManager::RegisterApplicationStateObserver()
1133 {
1134     if (appStateObserver_ != nullptr) {
1135         return false;
1136     }
1137     appStateObserver_ = new (std::nothrow) AppAccountAppStateObserver();
1138     if (appStateObserver_ == nullptr) {
1139         ACCOUNT_LOGE("failed to create AppAccountAppStateObserver instance");
1140         return false;
1141     }
1142     sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1143     if (samgrClient == nullptr) {
1144         ACCOUNT_LOGE("failed to system ability manager");
1145         return false;
1146     }
1147     iAppMgr_ = iface_cast<AppExecFwk::IAppMgr>(samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID));
1148     if (iAppMgr_ == nullptr) {
1149         appStateObserver_ = nullptr;
1150         ACCOUNT_LOGE("failed to get ability manager service");
1151         return false;
1152     }
1153     int32_t result = iAppMgr_->RegisterApplicationStateObserver(appStateObserver_);
1154     if (result != ERR_OK) {
1155         return false;
1156     }
1157     return true;
1158 }
1159 
UnregisterApplicationStateObserver()1160 void AppAccountControlManager::UnregisterApplicationStateObserver()
1161 {
1162     if (iAppMgr_) {
1163         iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
1164     }
1165     iAppMgr_ = nullptr;
1166     appStateObserver_ = nullptr;
1167 }
1168 
OnAbilityStateChanged(const AppExecFwk::AbilityStateData & abilityStateData)1169 void AppAccountControlManager::OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData)
1170 {
1171     if (abilityStateData.abilityState != static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED)) {
1172         return;
1173     }
1174     RemoveAssociatedDataCacheByUid(abilityStateData.uid);
1175 }
1176 
GetAllAccountsFromDataStorage(const std::string & owner,std::vector<AppAccountInfo> & appAccounts,const std::string & bundleName,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)1177 ErrCode AppAccountControlManager::GetAllAccountsFromDataStorage(const std::string &owner,
1178     std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName,
1179     const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1180 {
1181     appAccounts.clear();
1182 
1183     if (dataStoragePtr == nullptr) {
1184         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1185         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1186     }
1187 
1188     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
1189     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(owner, accounts);
1190     if (result != ERR_OK) {
1191         ACCOUNT_LOGE("failed to get accounts by owner, result = %{public}d, owner = %{public}s",
1192             result, owner.c_str());
1193         return result;
1194     }
1195 
1196     std::transform(accounts.begin(), accounts.end(), std::back_inserter(appAccounts),
1197         [](auto account) { return *(std::static_pointer_cast<AppAccountInfo>(account.second)); });
1198 
1199     return ERR_OK;
1200 }
1201 
GetAllAccessibleAccountsFromDataStorage(std::vector<AppAccountInfo> & appAccounts,const std::string & bundleName,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uint32_t & appIndex)1202 ErrCode AppAccountControlManager::GetAllAccessibleAccountsFromDataStorage(
1203     std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName,
1204     const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uint32_t &appIndex)
1205 {
1206     appAccounts.clear();
1207 
1208     if (dataStoragePtr == nullptr) {
1209         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1210         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1211     }
1212 
1213     std::vector<std::string> accessibleAccounts;
1214     ErrCode result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
1215     if (result != ERR_OK) {
1216         ACCOUNT_LOGE("failed to get accessible account from data storage, result = %{public}d.", result);
1217         return result;
1218     }
1219 
1220     for (auto account : accessibleAccounts) {
1221         AppAccountInfo appAccountInfo;
1222 
1223         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
1224         if (result != ERR_OK) {
1225             ACCOUNT_LOGE("failed to get account info by id. result %{public}d.", result);
1226             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
1227         }
1228 
1229         appAccounts.emplace_back(appAccountInfo);
1230     }
1231 
1232     std::vector<AppAccountInfo> currentAppAccounts;
1233     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
1234     result = GetAllAccountsFromDataStorage(key, currentAppAccounts, bundleName, dataStoragePtr);
1235     if (result != ERR_OK) {
1236         ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
1237         return result;
1238     }
1239 
1240     std::transform(currentAppAccounts.begin(), currentAppAccounts.end(), std::back_inserter(appAccounts),
1241         [](auto account) { return account; });
1242 
1243     return ERR_OK;
1244 }
1245 
GetDataStorageByUserId(int32_t userId,const bool & autoSync,DistributedKv::SecurityLevel securityLevel)1246 std::shared_ptr<AppAccountDataStorage> AppAccountControlManager::GetDataStorageByUserId(
1247     int32_t userId, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)
1248 {
1249     std::string storeId = std::to_string(userId);
1250     if (autoSync == true) {
1251         storeId = storeId + DATA_STORAGE_SUFFIX;
1252     }
1253     std::lock_guard<std::mutex> lock(storePtrMutex_);
1254     auto it = storePtrMap_.find(storeId);
1255     if (it != storePtrMap_.end()) {
1256         return it->second;
1257     }
1258     AccountDataStorageOptions options;
1259     options.area = DistributedKv::EL2;
1260     options.autoSync = autoSync;
1261     options.securityLevel = securityLevel;
1262     options.baseDir = EL2_DATA_STORAGE_PATH_PREFIX + std::to_string(userId) + EL2_DATA_STORAGE_PATH_SUFFIX;
1263     auto storePtr = std::make_shared<AppAccountDataStorage>(EL2_DATA_STORE_PREFIX + storeId, options);
1264     storePtrMap_.emplace(storeId, storePtr);
1265     return storePtr;
1266 }
1267 
GetDataStorage(const uid_t & uid,const bool & autoSync,DistributedKv::SecurityLevel securityLevel)1268 std::shared_ptr<AppAccountDataStorage> AppAccountControlManager::GetDataStorage(
1269     const uid_t &uid, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)
1270 {
1271     return GetDataStorageByUserId(uid / UID_TRANSFORM_DIVISOR, autoSync, securityLevel);
1272 }
1273 
NeedSyncDataStorage(const AppAccountInfo & appAccountInfo)1274 bool AppAccountControlManager::NeedSyncDataStorage(const AppAccountInfo &appAccountInfo)
1275 {
1276     bool syncEnable = false;
1277     appAccountInfo.GetSyncEnable(syncEnable);
1278 
1279     if (syncEnable == false) {
1280         return false;
1281     }
1282     return true;
1283 }
1284 
GetAccountInfoFromDataStorage(AppAccountInfo & appAccountInfo,std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)1285 ErrCode AppAccountControlManager::GetAccountInfoFromDataStorage(
1286     AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1287 {
1288     if (dataStoragePtr == nullptr) {
1289         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1290         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1291     }
1292 
1293     return dataStoragePtr->GetAccountInfoFromDataStorage(appAccountInfo);
1294 }
1295 
AddAccountInfoIntoDataStorage(AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1296 ErrCode AppAccountControlManager::AddAccountInfoIntoDataStorage(
1297     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1298 {
1299     if (dataStoragePtr == nullptr) {
1300         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1301         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1302     }
1303 
1304     std::string owner;
1305     appAccountInfo.GetOwner(owner);
1306 
1307     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
1308     std::string key = owner + Constants::HYPHEN + std::to_string(appAccountInfo.GetAppIndex());
1309     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(key, accounts);
1310     if (result != ERR_OK) {
1311         ACCOUNT_LOGE("failed to get accounts by owner, result %{public}d, owner = %{public}s",
1312             result, owner.c_str());
1313         return result;
1314     }
1315 
1316     if (accounts.size() >= ACCOUNT_MAX_SIZE) {
1317         ACCOUNT_LOGE("account exceeds max size");
1318         return ERR_APPACCOUNT_SERVICE_ACCOUNT_MAX_SIZE;
1319     }
1320 
1321     result = dataStoragePtr->AddAccountInfoIntoDataStorage(appAccountInfo);
1322     if (result != ERR_OK) {
1323         ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
1324         return result;
1325     }
1326 
1327     // for sync data storage
1328 #ifdef DISTRIBUTED_FEATURE_ENABLED
1329     if (NeedSyncDataStorage(appAccountInfo) == true) {
1330         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1331         if (dataStorageSyncPtr == nullptr) {
1332             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1333             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1334         }
1335 
1336         result = dataStorageSyncPtr->AddAccountInfoIntoDataStorage(appAccountInfo);
1337         if (result != ERR_OK) {
1338             ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
1339             return result;
1340         }
1341     }
1342 #else  // DISTRIBUTED_FEATURE_ENABLED
1343     ACCOUNT_LOGI("No distributed feature!");
1344 #endif // DISTRIBUTED_FEATURE_ENABLED
1345 
1346     return ERR_OK;
1347 }
1348 
SaveAccountInfoIntoDataStorage(AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1349 ErrCode AppAccountControlManager::SaveAccountInfoIntoDataStorage(
1350     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1351 {
1352     if (dataStoragePtr == nullptr) {
1353         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1354         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1355     }
1356 
1357     ErrCode result = dataStoragePtr->SaveAccountInfoIntoDataStorage(appAccountInfo);
1358     if (result != ERR_OK) {
1359         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
1360         return result;
1361     }
1362 
1363     // for sync data storage
1364 #ifdef DISTRIBUTED_FEATURE_ENABLED
1365     if (NeedSyncDataStorage(appAccountInfo) == true) {
1366         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1367         if (dataStorageSyncPtr == nullptr) {
1368             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1369             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1370         }
1371 
1372         std::string appAccountInfoFromDataStorage;
1373         result = dataStorageSyncPtr->GetValueFromKvStore(appAccountInfo.GetPrimeKey(), appAccountInfoFromDataStorage);
1374         if (result != ERR_OK) {
1375             ACCOUNT_LOGE("failed to get config by id from data storage, result %{public}d.", result);
1376 
1377             result = dataStorageSyncPtr->AddAccountInfo(appAccountInfo);
1378             if (result != ERR_OK) {
1379                 ACCOUNT_LOGE("failed to add account info, result = %{public}d", result);
1380                 return result;
1381             }
1382         } else {
1383             result = dataStorageSyncPtr->SaveAccountInfo(appAccountInfo);
1384             if (result != ERR_OK) {
1385                 ACCOUNT_LOGE("failed to save account info, result = %{public}d", result);
1386                 return result;
1387             }
1388         }
1389     }
1390 #else  // DISTRIBUTED_FEATURE_ENABLED
1391     ACCOUNT_LOGI("No distributed feature!");
1392 #endif // DISTRIBUTED_FEATURE_ENABLED
1393 
1394     return ERR_OK;
1395 }
1396 
DeleteAccountInfoFromDataStorage(AppAccountInfo & appAccountInfo,std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1397 ErrCode AppAccountControlManager::DeleteAccountInfoFromDataStorage(
1398     AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1399 {
1400     if (dataStoragePtr == nullptr) {
1401         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1402         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1403     }
1404 
1405     ErrCode result = dataStoragePtr->GetAccountInfoFromDataStorage(appAccountInfo);
1406     if (result != ERR_OK) {
1407         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
1408         return result;
1409     }
1410 
1411     result = dataStoragePtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1412     if (result != ERR_OK) {
1413         ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
1414         return result;
1415     }
1416 
1417     // for sync data storage
1418 #ifdef DISTRIBUTED_FEATURE_ENABLED
1419     if (NeedSyncDataStorage(appAccountInfo) == true) {
1420         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1421         if (dataStorageSyncPtr == nullptr) {
1422             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1423             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1424         }
1425 
1426         result = dataStorageSyncPtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1427         if (result != ERR_OK) {
1428             ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
1429         }
1430     }
1431 #else  // DISTRIBUTED_FEATURE_ENABLED
1432     ACCOUNT_LOGI("No distributed feature!");
1433 #endif // DISTRIBUTED_FEATURE_ENABLED
1434     return ERR_OK;
1435 }
1436 
SaveAuthorizedAccount(const std::string & bundleName,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1437 ErrCode AppAccountControlManager::SaveAuthorizedAccount(const std::string &bundleName,
1438     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1439 {
1440     if (dataStoragePtr == nullptr) {
1441         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1442         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1443     }
1444 
1445     ErrCode result = SaveAuthorizedAccountIntoDataStorage(bundleName, appAccountInfo, dataStoragePtr);
1446     if (result != ERR_OK) {
1447         ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1448         return result;
1449     }
1450 
1451     // for sync data storage
1452 #ifdef DISTRIBUTED_FEATURE_ENABLED
1453     if (NeedSyncDataStorage(appAccountInfo) == true) {
1454         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1455         if (dataStorageSyncPtr == nullptr) {
1456             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1457             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1458         }
1459 
1460         result = SaveAuthorizedAccountIntoDataStorage(bundleName, appAccountInfo, dataStorageSyncPtr);
1461         if (result != ERR_OK) {
1462             ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1463             return result;
1464         }
1465     }
1466 #else  // DISTRIBUTED_FEATURE_ENABLED
1467     ACCOUNT_LOGI("No distributed feature!");
1468 #endif // DISTRIBUTED_FEATURE_ENABLED
1469 
1470     return ERR_OK;
1471 }
1472 
RemoveAuthorizedAccount(const std::string & bundleName,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1473 ErrCode AppAccountControlManager::RemoveAuthorizedAccount(const std::string &bundleName,
1474     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1475 {
1476     if (dataStoragePtr == nullptr) {
1477         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1478         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1479     }
1480 
1481     ErrCode result = RemoveAuthorizedAccountFromDataStorage(bundleName, appAccountInfo, dataStoragePtr);
1482     if (result != ERR_OK) {
1483         ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1484         return result;
1485     }
1486 
1487     // for sync data storage
1488 #ifdef DISTRIBUTED_FEATURE_ENABLED
1489     if (NeedSyncDataStorage(appAccountInfo) == true) {
1490         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1491         if (dataStorageSyncPtr == nullptr) {
1492             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1493             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1494         }
1495 
1496         result = RemoveAuthorizedAccountFromDataStorage(bundleName, appAccountInfo, dataStorageSyncPtr);
1497         if (result != ERR_OK) {
1498             ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1499             return result;
1500         }
1501     }
1502 #else  // DISTRIBUTED_FEATURE_ENABLED
1503     ACCOUNT_LOGI("No distributed feature!");
1504 #endif // DISTRIBUTED_FEATURE_ENABLED
1505 
1506     return ERR_OK;
1507 }
1508 
SaveAuthorizedAccountIntoDataStorage(const std::string & authorizedApp,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)1509 ErrCode AppAccountControlManager::SaveAuthorizedAccountIntoDataStorage(const std::string &authorizedApp,
1510     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1511 {
1512     if (dataStoragePtr == nullptr) {
1513         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1514         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1515     }
1516 
1517     std::string authorizedAccounts;
1518     ErrCode result = dataStoragePtr->GetValueFromKvStore(AUTHORIZED_ACCOUNTS,
1519         authorizedAccounts);
1520     if (result != ERR_OK) {
1521         ACCOUNT_LOGE("failed to get config by id from data storage, result %{public}d.", result);
1522     }
1523 
1524     std::vector<std::string> accessibleAccounts;
1525     auto jsonObject = dataStoragePtr->GetAccessibleAccountsFromAuthorizedAccounts(
1526         authorizedAccounts, authorizedApp, accessibleAccounts);
1527 
1528     auto accountId = appAccountInfo.GetPrimeKey();
1529 
1530     auto it = std::find(accessibleAccounts.begin(), accessibleAccounts.end(), accountId);
1531     if (it == accessibleAccounts.end()) {
1532         accessibleAccounts.emplace_back(accountId);
1533     }
1534 
1535     auto accessibleAccountArray = Json::array();
1536     std::transform(accessibleAccounts.begin(), accessibleAccounts.end(), std::back_inserter(accessibleAccountArray),
1537         [](auto account) { return account; });
1538 
1539     jsonObject[authorizedApp] = accessibleAccountArray;
1540     try {
1541         authorizedAccounts = jsonObject.dump();
1542     } catch (Json::type_error& err) {
1543         ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
1544         return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
1545     }
1546 
1547     result = dataStoragePtr->PutValueToKvStore(AUTHORIZED_ACCOUNTS, authorizedAccounts);
1548     if (result != ERR_OK) {
1549         ACCOUNT_LOGE("PutValueToKvStore failed! result %{public}d.", result);
1550     }
1551     return result;
1552 }
1553 
RemoveAuthorizedAccountFromDataStorage(const std::string & authorizedApp,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)1554 ErrCode AppAccountControlManager::RemoveAuthorizedAccountFromDataStorage(const std::string &authorizedApp,
1555     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1556 {
1557     if (dataStoragePtr == nullptr) {
1558         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1559         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1560     }
1561 
1562     std::string authorizedAccounts;
1563     ErrCode result = dataStoragePtr->GetValueFromKvStore(AUTHORIZED_ACCOUNTS,
1564         authorizedAccounts);
1565     if (result != ERR_OK) {
1566         ACCOUNT_LOGE("failed to get authorized accounts from data storage, result %{public}d.", result);
1567     }
1568 
1569     std::vector<std::string> accessibleAccounts;
1570     auto jsonObject = dataStoragePtr->GetAccessibleAccountsFromAuthorizedAccounts(
1571         authorizedAccounts, authorizedApp, accessibleAccounts);
1572 
1573     auto accountId = appAccountInfo.GetPrimeKey();
1574 
1575     auto it = std::find(accessibleAccounts.begin(), accessibleAccounts.end(), accountId);
1576     if (it != accessibleAccounts.end()) {
1577         accessibleAccounts.erase(it);
1578     }
1579 
1580     auto accessibleAccountArray = Json::array();
1581     std::transform(accessibleAccounts.begin(), accessibleAccounts.end(), std::back_inserter(accessibleAccountArray),
1582         [](auto account) { return account; });
1583 
1584     jsonObject[authorizedApp] = accessibleAccountArray;
1585     try {
1586         authorizedAccounts = jsonObject.dump();
1587     } catch (Json::type_error& err) {
1588         ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
1589         return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
1590     }
1591 
1592     result = dataStoragePtr->PutValueToKvStore(AUTHORIZED_ACCOUNTS, authorizedAccounts);
1593     if (result != ERR_OK) {
1594         ACCOUNT_LOGE("failed to save config info, result %{public}d.", result);
1595         return result;
1596     }
1597 
1598     return ERR_OK;
1599 }
1600 }  // namespace AccountSA
1601 }  // namespace OHOS
1602