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 ERR_APPACCOUNT_SERVICE_ENABLE_APP_ACCESS_ALREADY_EXISTS;
356     }
357 
358     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
359     if (result != ERR_OK) {
360         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
361         return result;
362     }
363 
364     // save authorized account into data storage
365     result = SaveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
366     if (result != ERR_OK) {
367         ACCOUNT_LOGE("failed to save authorized account into data storage, result %{public}d.", result);
368         return result;
369     }
370 
371     return ERR_OK;
372 }
373 
DisableAppAccess(const std::string &name, const std::string &authorizedApp, AppAccountCallingInfo &appAccountCallingInfo, AppAccountInfo &appAccountInfo, const uint32_t apiVersion)374 ErrCode AppAccountControlManager::DisableAppAccess(const std::string &name, const std::string &authorizedApp,
375     AppAccountCallingInfo &appAccountCallingInfo, AppAccountInfo &appAccountInfo, const uint32_t apiVersion)
376 {
377     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
378     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
379     if (result != ERR_OK) {
380         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
381         return result;
382     }
383 
384     result = appAccountInfo.DisableAppAccess(authorizedApp, apiVersion);
385     if (result != ERR_OK) {
386         ACCOUNT_LOGE("failed to disable app access, result %{public}d.", result);
387         return ERR_APPACCOUNT_SERVICE_DISABLE_APP_ACCESS_NOT_EXISTED;
388     }
389 
390     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
391     if (result != ERR_OK) {
392         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
393         return result;
394     }
395 
396     // remove authorized account from data storage
397     result = RemoveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
398     if (result != ERR_OK) {
399         ACCOUNT_LOGE("failed to save authorized account into data storage, result %{public}d.", result);
400         return result;
401     }
402 
403     return ERR_OK;
404 }
405 
CheckAppAccess(const std::string &name, const std::string &authorizedApp, bool &isAccessible, const AppAccountCallingInfo &appAccountCallingInfo)406 ErrCode AppAccountControlManager::CheckAppAccess(const std::string &name, const std::string &authorizedApp,
407     bool &isAccessible, const AppAccountCallingInfo &appAccountCallingInfo)
408 {
409     isAccessible = false;
410     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
411     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
412     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
413     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
414     if (result != ERR_OK) {
415         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
416         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
417     }
418     return appAccountInfo.CheckAppAccess(authorizedApp, isAccessible);
419 }
420 
CheckAppAccountSyncEnable(const std::string &name, bool &syncEnable, const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)421 ErrCode AppAccountControlManager::CheckAppAccountSyncEnable(const std::string &name,
422     bool &syncEnable, const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
423 {
424     AppAccountInfo appAccountInfo(name, bundleName);
425     appAccountInfo.SetAppIndex(appIndex);
426     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
427     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
428     if (result != ERR_OK) {
429         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
430         return result;
431     }
432 
433     appAccountInfo.GetSyncEnable(syncEnable);
434 
435     return ERR_OK;
436 }
437 
SetAppAccountSyncEnable(const std::string &name, const bool &syncEnable, const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)438 ErrCode AppAccountControlManager::SetAppAccountSyncEnable(const std::string &name, const bool &syncEnable,
439     const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
440 {
441     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
442     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
443     if (result != ERR_OK) {
444         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
445         return result;
446     }
447 
448     appAccountInfo.SetSyncEnable(syncEnable);
449 
450     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
451     if (result != ERR_OK) {
452         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
453         return result;
454     }
455 
456     return ERR_OK;
457 }
458 
PopDataFromAssociatedDataCache()459 void AppAccountControlManager::PopDataFromAssociatedDataCache()
460 {
461     auto it = associatedDataCache_.begin();
462     auto toPopedIt = it++;
463     for (; it != associatedDataCache_.end(); ++it) {
464         if (toPopedIt->second.freq > it->second.freq) {
465             toPopedIt = it;
466         }
467         it->second.freq = 0;
468     }
469     associatedDataCache_.erase(toPopedIt);
470 }
471 
GetAssociatedDataFromStorage(const std::string &name, const std::string &key, std::string &value, const uid_t &uid, const uint32_t &appIndex)472 ErrCode AppAccountControlManager::GetAssociatedDataFromStorage(const std::string &name, const std::string &key,
473     std::string &value, const uid_t &uid, const uint32_t &appIndex)
474 {
475     std::string bundleName;
476     if (BundleManagerAdapter::GetInstance()->GetNameForUid(uid, bundleName) != ERR_OK) {
477         ACCOUNT_LOGE("failed to get bundle name");
478         return ERR_APPACCOUNT_SERVICE_GET_BUNDLE_NAME;
479     }
480     AppAccountInfo appAccountInfo(name, bundleName);
481     appAccountInfo.SetAppIndex(appIndex);
482     std::shared_ptr<AppAccountDataStorage> storePtr = GetDataStorage(uid);
483     if (storePtr == nullptr) {
484         ACCOUNT_LOGE("failed to get data storage");
485         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
486     }
487     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, storePtr);
488     if (result != ERR_OK) {
489         ACCOUNT_LOGE("failed to get account info from data storage");
490         return result;
491     }
492     AssociatedDataCacheItem item;
493     item.name = name;
494     item.freq = 0;
495     appAccountInfo.GetAllAssociatedData(item.data);
496     auto it = item.data.find(key);
497     if (it != item.data.end()) {
498         value = it->second;
499     } else {
500         result = ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_KEY_NOT_EXIST;
501     }
502     if ((associatedDataCache_.size() == 0) && (!RegisterApplicationStateObserver())) {
503         ACCOUNT_LOGE("failed to register application state observer");
504         return result;
505     }
506     if (associatedDataCache_.size() >= ASSOCIATED_DATA_CACHE_MAX_SIZE) {
507         PopDataFromAssociatedDataCache();
508     }
509     associatedDataCache_.emplace(uid, item);
510     return result;
511 }
512 
GetAssociatedData(const std::string &name, const std::string &key, std::string &value, const uid_t &uid)513 ErrCode AppAccountControlManager::GetAssociatedData(const std::string &name, const std::string &key,
514     std::string &value, const uid_t &uid)
515 {
516     std::lock_guard<std::mutex> lock(associatedDataMutex_);
517     auto it = associatedDataCache_.find(uid);
518     if ((it == associatedDataCache_.end()) || (it->second.name != name)) {
519         uint32_t callingTokenId = IPCSkeleton::GetCallingTokenID();
520         Security::AccessToken::HapTokenInfo hapTokenInfo;
521         int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callingTokenId, hapTokenInfo);
522         if ((result != 0) || (hapTokenInfo.instIndex < 0)) {
523             ACCOUNT_LOGE("failed to get app index");
524             return ERR_APPACCOUNT_SERVICE_GET_APP_INDEX;
525         }
526         associatedDataCache_.erase(uid);
527         return GetAssociatedDataFromStorage(name, key, value, uid, hapTokenInfo.instIndex);
528     }
529     it->second.freq++;
530     auto dataIt = it->second.data.find(key);
531     if (dataIt == it->second.data.end()) {
532         return ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_KEY_NOT_EXIST;
533     }
534     value = dataIt->second;
535     return ERR_OK;
536 }
537 
SetAssociatedData(const std::string &name, const std::string &key, const std::string &value, const AppAccountCallingInfo &appAccountCallingInfo)538 ErrCode AppAccountControlManager::SetAssociatedData(const std::string &name, const std::string &key,
539     const std::string &value, const AppAccountCallingInfo &appAccountCallingInfo)
540 {
541     std::shared_ptr<AppAccountDataStorage> storePtr = GetDataStorage(appAccountCallingInfo.callingUid);
542     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
543     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
544     std::lock_guard<std::mutex> lock(associatedDataMutex_);
545     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, storePtr);
546     if (result != ERR_OK) {
547         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
548         return result;
549     }
550     result = appAccountInfo.SetAssociatedData(key, value);
551     if (result != ERR_OK) {
552         ACCOUNT_LOGE("failed to set associated data, result %{public}d.", result);
553         return result;
554     }
555     result = SaveAccountInfoIntoDataStorage(appAccountInfo, storePtr, appAccountCallingInfo.callingUid);
556     if (result != ERR_OK) {
557         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
558         return result;
559     }
560     auto it = associatedDataCache_.find(appAccountCallingInfo.callingUid);
561     if ((it != associatedDataCache_.end()) && (it->second.name == name)) {
562         it->second.data[key] = value;
563     }
564     return ERR_OK;
565 }
566 
GetAccountCredential(const std::string &name, const std::string &credentialType, std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo)567 ErrCode AppAccountControlManager::GetAccountCredential(const std::string &name, const std::string &credentialType,
568     std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo)
569 {
570     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
571     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
572     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
573         GetDataStorage(appAccountCallingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
574     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
575     if (result != ERR_OK) {
576         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
577         return result;
578     }
579 
580     result = appAccountInfo.GetAccountCredential(credentialType, credential);
581     if (result != ERR_OK) {
582         return result;
583     }
584 #ifdef HAS_ASSET_PART
585     std::string alias = credential;
586     credential = "";
587     GetDataFromAsset(appAccountCallingInfo.callingUid / UID_TRANSFORM_DIVISOR, alias, credential);
588 #endif
589     return result;
590 }
591 
SetAccountCredential(const std::string &name, const std::string &credentialType, const std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo)592 ErrCode AppAccountControlManager::SetAccountCredential(const std::string &name, const std::string &credentialType,
593     const std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo)
594 {
595     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
596         GetDataStorage(appAccountCallingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
597     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
598     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
599     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
600     if (result != ERR_OK) {
601         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
602         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
603     }
604     result = appAccountInfo.SetAccountCredential(credentialType, credential);
605     if (result != ERR_OK) {
606         ACCOUNT_LOGE("failed to set account credential, result %{public}d.", result);
607         return result;
608     }
609 
610     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
611     if (result != ERR_OK) {
612         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
613         return result;
614     }
615 #ifdef HAS_ASSET_PART
616     std::string hapLabel = appAccountCallingInfo.bundleName + Constants::HYPHEN +
617         std::to_string(appAccountCallingInfo.appIndex);
618     std::string credentialAlias;
619     appAccountInfo.GetAccountCredential(credentialType, credentialAlias);
620     int32_t localId = appAccountCallingInfo.callingUid / UID_TRANSFORM_DIVISOR;
621     result = SaveDataToAsset(localId, hapLabel, appAccountInfo.GetAlias(), credentialAlias, credential);
622 #endif
623     return result;
624 }
625 
DeleteAccountCredential(const std::string &name, const std::string &credentialType, const AppAccountCallingInfo &callingInfo)626 ErrCode AppAccountControlManager::DeleteAccountCredential(const std::string &name, const std::string &credentialType,
627     const AppAccountCallingInfo &callingInfo)
628 {
629     AppAccountInfo appAccountInfo(name, callingInfo.bundleName);
630     appAccountInfo.SetAppIndex(callingInfo.appIndex);
631     auto dataStoragePtr = GetDataStorage(callingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
632     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
633     if (result != ERR_OK) {
634         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
635         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
636     }
637 #ifdef HAS_ASSET_PART
638     std::string alias;
639     appAccountInfo.GetAccountCredential(credentialType, alias);
640     RemoveDataFromAsset(callingInfo.callingUid / UID_TRANSFORM_DIVISOR, alias);
641 #endif
642     result = appAccountInfo.DeleteAccountCredential(credentialType);
643     if (result != ERR_OK) {
644         ACCOUNT_LOGE("failed to delete account credential, result %{public}d.", result);
645         return result;
646     }
647 
648     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, callingInfo.callingUid);
649     if (result != ERR_OK) {
650         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
651     }
652     return result;
653 }
654 
GetOAuthToken( const AuthenticatorSessionRequest &request, std::string &token, const uint32_t apiVersion)655 ErrCode AppAccountControlManager::GetOAuthToken(
656     const AuthenticatorSessionRequest &request, std::string &token, const uint32_t apiVersion)
657 {
658     AppAccountInfo appAccountInfo(request.name, request.owner);
659     appAccountInfo.SetAppIndex(request.appIndex);
660     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
661         GetDataStorage(request.callerUid, false, DistributedKv::SecurityLevel::S4);
662     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
663     if (result != ERR_OK) {
664         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
665         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
666     }
667     bool isVisible = false;
668     result = appAccountInfo.CheckOAuthTokenVisibility(
669         request.authType, request.callerBundleName, isVisible, apiVersion);
670     if ((result != ERR_OK) || (!isVisible)) {
671         ACCOUNT_LOGE("failed to get oauth token for permission denied, result %{public}d.", result);
672         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
673     }
674     result = appAccountInfo.GetOAuthToken(request.authType, token, apiVersion);
675     if (result != ERR_OK) {
676         return result;
677     }
678 #ifdef HAS_ASSET_PART
679     std::string alias = token;
680     token = "";
681     GetDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias, token);
682     if (token.empty() && (apiVersion < Constants::API_VERSION9)) {
683         return ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST;
684     }
685 #endif
686     return ERR_OK;
687 }
688 
SetOAuthToken(const AuthenticatorSessionRequest &request)689 ErrCode AppAccountControlManager::SetOAuthToken(const AuthenticatorSessionRequest &request)
690 {
691     std::lock_guard<std::mutex> lock(mutex_);
692     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
693     appAccountInfo.SetAppIndex(request.appIndex);
694     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
695         GetDataStorage(request.callerUid, false, DistributedKv::SecurityLevel::S4);
696     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
697     if (result != ERR_OK) {
698         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
699         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
700     }
701     result = appAccountInfo.SetOAuthToken(request.authType, request.token);
702     if (result != ERR_OK) {
703         ACCOUNT_LOGE("failed to set oauth token, result %{public}d.", result);
704         return result;
705     }
706     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
707     if (result != ERR_OK) {
708         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
709         return result;
710     }
711 #ifdef HAS_ASSET_PART
712     std::string hapLabel = request.callerBundleName + Constants::HYPHEN + std::to_string(request.appIndex);
713     std::string authTypeAlias;
714     appAccountInfo.GetOAuthToken(request.authType, authTypeAlias);
715     int32_t localId = request.callerUid / UID_TRANSFORM_DIVISOR;
716     result = SaveDataToAsset(localId, hapLabel, appAccountInfo.GetAlias(), authTypeAlias, request.token);
717 #endif
718     return result;
719 }
720 
DeleteOAuthToken( const AuthenticatorSessionRequest &request, const uint32_t apiVersion)721 ErrCode AppAccountControlManager::DeleteOAuthToken(
722     const AuthenticatorSessionRequest &request, const uint32_t apiVersion)
723 {
724     std::lock_guard<std::mutex> lock(mutex_);
725     AppAccountInfo appAccountInfo(request.name, request.owner);
726     appAccountInfo.SetAppIndex(request.appIndex);
727     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
728     ErrCode ret = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
729     if (ret != ERR_OK) {
730         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", ret);
731         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
732     }
733     bool isVisible = false;
734     ret = appAccountInfo.CheckOAuthTokenVisibility(request.authType, request.callerBundleName, isVisible, apiVersion);
735     if ((!isVisible) || (ret != ERR_OK)) {
736         ACCOUNT_LOGE("failed to delete oauth token for permission denied, result %{public}d.", ret);
737         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
738     }
739     std::string token = request.token;
740 #ifdef HAS_ASSET_PART
741     std::string alias;
742     ret = appAccountInfo.GetOAuthToken(request.authType, alias, apiVersion);
743     if (ret != ERR_OK) {
744         return apiVersion >= Constants::API_VERSION9 ? ret : ERR_OK;
745     }
746     GetDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias, token);
747     if (token != request.token) {
748         return ERR_OK;
749     }
750     RemoveDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias);
751     token = alias;
752 #endif
753     if (apiVersion >= Constants::API_VERSION9) {
754         bool isOwnerSelf = request.owner == request.callerBundleName;
755         ret = appAccountInfo.DeleteAuthToken(request.authType, token, isOwnerSelf);
756         if (ret != ERR_OK) {
757             return ret;
758         }
759     } else {
760         ret = appAccountInfo.DeleteOAuthToken(request.authType, token);
761         if (ret == ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST) {
762             return ERR_OK;
763         }
764     }
765     ret = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
766     if (ret != ERR_OK) {
767         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", ret);
768         return ret;
769     }
770     return ret;
771 }
772 
SetOAuthTokenVisibility( const AuthenticatorSessionRequest &request, const uint32_t apiVersion)773 ErrCode AppAccountControlManager::SetOAuthTokenVisibility(
774     const AuthenticatorSessionRequest &request, const uint32_t apiVersion)
775 {
776     std::lock_guard<std::mutex> lock(mutex_);
777     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
778     appAccountInfo.SetAppIndex(request.appIndex);
779     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
780     ErrCode ret = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
781     if (ret != ERR_OK) {
782         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", ret);
783         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
784     }
785     ret = appAccountInfo.SetOAuthTokenVisibility(
786         request.authType, request.bundleName, request.isTokenVisible, apiVersion);
787     if (ret != ERR_OK) {
788         ACCOUNT_LOGE("failed to set oauth token visibility, result %{public}d.", ret);
789         return ret;
790     }
791     ret = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
792     if (ret != ERR_OK) {
793         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", ret);
794         return ret;
795     }
796     return ERR_OK;
797 }
798 
CheckOAuthTokenVisibility( const AuthenticatorSessionRequest &request, bool &isVisible, const uint32_t apiVersion)799 ErrCode AppAccountControlManager::CheckOAuthTokenVisibility(
800     const AuthenticatorSessionRequest &request, bool &isVisible, const uint32_t apiVersion)
801 {
802     isVisible = false;
803     AppAccountInfo appAccountInfo(request.name, request.owner);
804     appAccountInfo.SetAppIndex(request.appIndex);
805     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
806     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
807     if (result != ERR_OK) {
808         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
809         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
810     }
811     return appAccountInfo.CheckOAuthTokenVisibility(request.authType, request.bundleName, isVisible, apiVersion);
812 }
813 
GetAllOAuthTokens( const AuthenticatorSessionRequest &request, std::vector<OAuthTokenInfo> &tokenInfos)814 ErrCode AppAccountControlManager::GetAllOAuthTokens(
815     const AuthenticatorSessionRequest &request, std::vector<OAuthTokenInfo> &tokenInfos)
816 {
817     tokenInfos.clear();
818     AppAccountInfo appAccountInfo(request.name, request.owner);
819     appAccountInfo.SetAppIndex(request.appIndex);
820     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
821     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
822     if (result != ERR_OK) {
823         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
824         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
825     }
826     std::vector<OAuthTokenInfo> allTokenInfos;
827     result = appAccountInfo.GetAllOAuthTokens(allTokenInfos);
828     if (result != ERR_OK) {
829         ACCOUNT_LOGE("failed to get all oauth token from data storage, result %{public}d.", result);
830         return result;
831     }
832     for (auto tokenInfo : allTokenInfos) {
833         if ((request.callerBundleName != request.owner) &&
834             (tokenInfo.authList.find(request.callerBundleName) == tokenInfo.authList.end())) {
835             continue;
836         }
837 #ifdef HAS_ASSET_PART
838         std::string alias = tokenInfo.token;
839         tokenInfo.token = "";
840         GetDataFromAsset(request.callerUid / UID_TRANSFORM_DIVISOR, alias, tokenInfo.token);
841 #endif
842         if (tokenInfo.token.empty() && tokenInfo.authList.empty()) { // for api 8 logic
843             continue;
844         }
845         tokenInfo.authList.clear();
846         tokenInfos.push_back(tokenInfo);
847     }
848     return ERR_OK;
849 }
850 
GetOAuthList( const AuthenticatorSessionRequest &request, std::set<std::string> &oauthList, const uint32_t apiVersion)851 ErrCode AppAccountControlManager::GetOAuthList(
852     const AuthenticatorSessionRequest &request, std::set<std::string> &oauthList, const uint32_t apiVersion)
853 {
854     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
855     appAccountInfo.SetAppIndex(request.appIndex);
856     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
857     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
858     if (result != ERR_OK) {
859         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
860         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
861     }
862     return appAccountInfo.GetOAuthList(request.authType, oauthList, apiVersion);
863 }
864 
GetAllAccounts(const std::string &owner, std::vector<AppAccountInfo> &appAccounts, const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)865 ErrCode AppAccountControlManager::GetAllAccounts(const std::string &owner, std::vector<AppAccountInfo> &appAccounts,
866     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
867 {
868     appAccounts.clear();
869 
870     auto dataStoragePtr = GetDataStorage(uid);
871     if (dataStoragePtr == nullptr) {
872         ACCOUNT_LOGE("dataStoragePtr is nullptr");
873         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
874     }
875     ErrCode result = AccountPermissionManager::VerifyPermission(GET_ALL_APP_ACCOUNTS);
876     if ((bundleName == owner) || (result == ERR_OK)) {
877         std::string key = owner + Constants::HYPHEN + std::to_string(appIndex);
878         result = GetAllAccountsFromDataStorage(key, appAccounts, owner, dataStoragePtr);
879         if (result != ERR_OK) {
880             ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
881             return result;
882         }
883         return ERR_OK;
884     }
885 
886     std::vector<std::string> accessibleAccounts;
887     result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
888     if (result != ERR_OK) {
889         ACCOUNT_LOGE("failed to get accessible account from data storage, result %{public}d.", result);
890         return result;
891     }
892     for (auto account : accessibleAccounts) {
893         AppAccountInfo appAccountInfo;
894         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
895         if (result != ERR_OK) {
896             ACCOUNT_LOGE("failed to get account info by id, result %{public}d.", result);
897             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
898         }
899         if (appAccountInfo.GetOwner() == owner) {
900             appAccounts.emplace_back(appAccountInfo);
901         }
902     }
903     return ERR_OK;
904 }
905 
LoadAllAppAccounts(const std::shared_ptr<OHOS::AccountSA::AppAccountDataStorage> &dataStoragePtr, std::vector<AppAccountInfo> &appAccounts)906 static ErrCode LoadAllAppAccounts(const std::shared_ptr<OHOS::AccountSA::AppAccountDataStorage> &dataStoragePtr,
907     std::vector<AppAccountInfo> &appAccounts)
908 {
909     std::map<std::string, std::shared_ptr<IAccountInfo>> infos;
910     ErrCode result = dataStoragePtr->LoadAllData(infos);
911     if (result != ERR_OK) {
912         ACCOUNT_LOGE("LoadAllData failed!");
913         return result;
914     }
915     for (auto it = infos.begin(); it != infos.end(); ++it) {
916         if (it->first == AUTHORIZED_ACCOUNTS) {
917             continue;
918         }
919         AppAccountInfo curAppInfo = *(std::static_pointer_cast<AppAccountInfo>(it->second));
920         appAccounts.emplace_back(curAppInfo);
921     }
922     return ERR_OK;
923 }
924 
GetAllAccessibleAccounts(std::vector<AppAccountInfo> &appAccounts, const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)925 ErrCode AppAccountControlManager::GetAllAccessibleAccounts(std::vector<AppAccountInfo> &appAccounts,
926     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
927 {
928     appAccounts.clear();
929 
930     auto dataStoragePtr = GetDataStorage(uid);
931     if (dataStoragePtr == nullptr) {
932         ACCOUNT_LOGE("dataStoragePtr is nullptr");
933         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
934     }
935     ErrCode result = AccountPermissionManager::VerifyPermission(GET_ALL_APP_ACCOUNTS);
936     if (result == ERR_OK) {
937         return LoadAllAppAccounts(dataStoragePtr, appAccounts);
938     }
939     std::vector<std::string> accessibleAccounts;
940     result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
941     if (result != ERR_OK) {
942         ACCOUNT_LOGE("failed to get accessible account from data storage, result %{public}d.", result);
943         return result;
944     }
945 
946     for (auto account : accessibleAccounts) {
947         AppAccountInfo appAccountInfo;
948 
949         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
950         if (result != ERR_OK) {
951             ACCOUNT_LOGE("failed to get account info by id, result %{public}d.", result);
952             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
953         }
954 
955         appAccounts.emplace_back(appAccountInfo);
956     }
957 
958     std::vector<AppAccountInfo> currentAppAccounts;
959     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
960     result = GetAllAccountsFromDataStorage(key, currentAppAccounts, bundleName, dataStoragePtr);
961     if (result != ERR_OK) {
962         ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
963         return result;
964     }
965 
966     std::transform(currentAppAccounts.begin(), currentAppAccounts.end(), std::back_inserter(appAccounts),
967         [](auto account) { return account; });
968 
969     return ERR_OK;
970 }
971 
SelectAccountsByOptions( const SelectAccountsOptions &options, const sptr<IAppAccountAuthenticatorCallback> &callback, const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)972 ErrCode AppAccountControlManager::SelectAccountsByOptions(
973     const SelectAccountsOptions &options, const sptr<IAppAccountAuthenticatorCallback> &callback,
974     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
975 {
976     AAFwk::Want result;
977     if ((!options.hasAccounts) && (!options.hasOwners) && (!options.hasLabels)) {
978         callback->OnResult(ERR_JS_SUCCESS, result);
979         return ERR_OK;
980     }
981     std::set<std::string> allowedAccounts;
982     for (auto account : options.allowedAccounts) {
983         allowedAccounts.emplace(account.first + "_" + account.second);
984     }
985     std::set<std::string> allowedOwners(options.allowedOwners.begin(), options.allowedOwners.end());
986     std::vector<AppAccountInfo> accessibleAccounts;
987     ErrCode errCode = GetAllAccessibleAccounts(accessibleAccounts, uid, bundleName, appIndex);
988     if (errCode != ERR_OK) {
989         ACCOUNT_LOGE("failed to get all accessible accounts");
990         return errCode;
991     }
992     std::vector<AppAccountInfo> candidateAccounts;
993     for (auto account : accessibleAccounts) {
994         std::string owner = account.GetOwner();
995         if (options.hasOwners && allowedOwners.count(owner) == 0) {
996             continue;
997         }
998         if (options.hasAccounts && allowedAccounts.count(owner + "_" + account.GetName()) == 0) {
999             continue;
1000         }
1001         candidateAccounts.push_back(account);
1002     }
1003     if (options.requiredLabels.size() == 0) {
1004         std::vector<std::string> names;
1005         std::vector<std::string> owners;
1006         for (auto account : candidateAccounts) {
1007             names.push_back(account.GetName());
1008             owners.push_back(account.GetOwner());
1009         }
1010         result.SetParam(Constants::KEY_ACCOUNT_NAMES, names);
1011         result.SetParam(Constants::KEY_ACCOUNT_OWNERS, owners);
1012         callback->OnResult(ERR_JS_SUCCESS, result);
1013         return ERR_OK;
1014     }
1015     AuthenticatorSessionRequest request;
1016     request.callback = callback;
1017     request.callerUid = uid;
1018     request.labels = options.requiredLabels;
1019     return AppAccountAuthenticatorSessionManager::GetInstance().SelectAccountsByOptions(candidateAccounts, request);
1020 }
1021 
RemoveAssociatedDataCacheByUid(const uid_t &uid)1022 void AppAccountControlManager::RemoveAssociatedDataCacheByUid(const uid_t &uid)
1023 {
1024     std::lock_guard<std::mutex> lock(associatedDataMutex_);
1025     associatedDataCache_.erase(uid);
1026     if (associatedDataCache_.empty()) {
1027         UnregisterApplicationStateObserver();
1028     }
1029 }
1030 
RemoveAssociatedDataCacheByAccount(const uid_t &uid, const std::string &name)1031 void AppAccountControlManager::RemoveAssociatedDataCacheByAccount(const uid_t &uid, const std::string &name)
1032 {
1033     std::lock_guard<std::mutex> lock(associatedDataMutex_);
1034     auto it = associatedDataCache_.find(uid);
1035     if ((it == associatedDataCache_.end()) || (it->second.name != name)) {
1036         return;
1037     }
1038     associatedDataCache_.erase(it);
1039     if (associatedDataCache_.empty()) {
1040         UnregisterApplicationStateObserver();
1041     }
1042 }
1043 
SetOsAccountRemoved(int32_t localId, bool isRemoved)1044 void AppAccountControlManager::SetOsAccountRemoved(int32_t localId, bool isRemoved)
1045 {
1046     if (isRemoved) {
1047         removedOsAccounts_.EnsureInsert(localId, true);
1048     } else {
1049         removedOsAccounts_.Erase(localId);
1050     }
1051 }
1052 
IsOsAccountRemoved(int32_t localId)1053 bool AppAccountControlManager::IsOsAccountRemoved(int32_t localId)
1054 {
1055     bool isRemoved = false;
1056     return removedOsAccounts_.Find(localId, isRemoved);
1057 }
1058 
OnPackageRemoved( const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)1059 ErrCode AppAccountControlManager::OnPackageRemoved(
1060     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
1061 {
1062     RemoveAssociatedDataCacheByUid(uid);
1063     int32_t localId = uid / UID_TRANSFORM_DIVISOR;
1064     if (IsOsAccountRemoved(localId)) {
1065         ACCOUNT_LOGI("Account %{public}d is removed", localId);
1066         return ERR_OK;
1067     }
1068     return RemoveAppAccountData(uid, bundleName, appIndex);
1069 }
1070 
RemoveAppAccountData( const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)1071 ErrCode AppAccountControlManager::RemoveAppAccountData(
1072     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
1073 {
1074     auto dataStoragePtr = GetDataStorage(uid);
1075     if (dataStoragePtr == nullptr) {
1076         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1077         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1078     }
1079 #ifdef DISTRIBUTED_FEATURE_ENABLED
1080     auto dataStorageSyncPtr = GetDataStorage(uid, true);
1081     if (dataStorageSyncPtr == nullptr) {
1082         ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1083         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1084     }
1085 #endif // DISTRIBUTED_FEATURE_ENABLED
1086     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
1087     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
1088     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(key, accounts);
1089     if (result != ERR_OK) {
1090         ACCOUNT_LOGE("failed to get accounts by owner, result %{public}d, bundleName = %{public}s",
1091             result, bundleName.c_str());
1092         return result;
1093     }
1094     AppAccountInfo appAccountInfo;
1095     for (auto account : accounts) {
1096         appAccountInfo = *(std::static_pointer_cast<AppAccountInfo>(account.second));
1097         std::set<std::string> authorizedApps;
1098         appAccountInfo.GetAuthorizedApps(authorizedApps);
1099         appAccountInfo.SetAppIndex(appIndex);
1100         for (auto authorizedApp : authorizedApps) {
1101             RemoveAuthorizedAccountFromDataStorage(authorizedApp, appAccountInfo, dataStoragePtr);
1102 #ifdef DISTRIBUTED_FEATURE_ENABLED
1103             if (NeedSyncDataStorage(appAccountInfo) == true) {
1104                 RemoveAuthorizedAccountFromDataStorage(authorizedApp, appAccountInfo, dataStorageSyncPtr);
1105             }
1106 #endif // DISTRIBUTED_FEATURE_ENABLED
1107         }
1108         dataStoragePtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1109 #ifdef DISTRIBUTED_FEATURE_ENABLED
1110         if (NeedSyncDataStorage(appAccountInfo) == true) {
1111             dataStorageSyncPtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1112         }
1113 #else  // DISTRIBUTED_FEATURE_ENABLED
1114         ACCOUNT_LOGI("No distributed feature!");
1115 #endif // DISTRIBUTED_FEATURE_ENABLED
1116     }
1117 #ifdef HAS_ASSET_PART
1118     RemoveDataFromAssetByLabel(uid / UID_TRANSFORM_DIVISOR, SEC_ASSET_TAG_DATA_LABEL_NORMAL_1, key);
1119 #endif
1120     return ERR_OK;
1121 }
1122 
OnUserRemoved(int32_t userId)1123 ErrCode AppAccountControlManager::OnUserRemoved(int32_t userId)
1124 {
1125     std::string storeId = std::to_string(userId);
1126     std::string syncStoreId = storeId + DATA_STORAGE_SUFFIX;
1127     std::lock_guard<std::mutex> lock(storePtrMutex_);
1128     storePtrMap_.erase(storeId);
1129     storePtrMap_.erase(syncStoreId);
1130     return ERR_OK;
1131 }
1132 
RegisterApplicationStateObserver()1133 bool AppAccountControlManager::RegisterApplicationStateObserver()
1134 {
1135     if (appStateObserver_ != nullptr) {
1136         return false;
1137     }
1138     appStateObserver_ = new (std::nothrow) AppAccountAppStateObserver();
1139     if (appStateObserver_ == nullptr) {
1140         ACCOUNT_LOGE("failed to create AppAccountAppStateObserver instance");
1141         return false;
1142     }
1143     sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1144     if (samgrClient == nullptr) {
1145         ACCOUNT_LOGE("failed to system ability manager");
1146         return false;
1147     }
1148     iAppMgr_ = iface_cast<AppExecFwk::IAppMgr>(samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID));
1149     if (iAppMgr_ == nullptr) {
1150         appStateObserver_ = nullptr;
1151         ACCOUNT_LOGE("failed to get ability manager service");
1152         return false;
1153     }
1154     int32_t result = iAppMgr_->RegisterApplicationStateObserver(appStateObserver_);
1155     if (result != ERR_OK) {
1156         return false;
1157     }
1158     return true;
1159 }
1160 
UnregisterApplicationStateObserver()1161 void AppAccountControlManager::UnregisterApplicationStateObserver()
1162 {
1163     if (iAppMgr_) {
1164         iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
1165     }
1166     iAppMgr_ = nullptr;
1167     appStateObserver_ = nullptr;
1168 }
1169 
OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData)1170 void AppAccountControlManager::OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData)
1171 {
1172     if (abilityStateData.abilityState != static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED)) {
1173         return;
1174     }
1175     RemoveAssociatedDataCacheByUid(abilityStateData.uid);
1176 }
1177 
GetAllAccountsFromDataStorage(const std::string &owner, std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)1178 ErrCode AppAccountControlManager::GetAllAccountsFromDataStorage(const std::string &owner,
1179     std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName,
1180     const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1181 {
1182     appAccounts.clear();
1183 
1184     if (dataStoragePtr == nullptr) {
1185         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1186         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1187     }
1188 
1189     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
1190     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(owner, accounts);
1191     if (result != ERR_OK) {
1192         ACCOUNT_LOGE("failed to get accounts by owner, result = %{public}d, owner = %{public}s",
1193             result, owner.c_str());
1194         return result;
1195     }
1196 
1197     std::transform(accounts.begin(), accounts.end(), std::back_inserter(appAccounts),
1198         [](auto account) { return *(std::static_pointer_cast<AppAccountInfo>(account.second)); });
1199 
1200     return ERR_OK;
1201 }
1202 
GetAllAccessibleAccountsFromDataStorage( std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uint32_t &appIndex)1203 ErrCode AppAccountControlManager::GetAllAccessibleAccountsFromDataStorage(
1204     std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName,
1205     const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uint32_t &appIndex)
1206 {
1207     appAccounts.clear();
1208 
1209     if (dataStoragePtr == nullptr) {
1210         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1211         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1212     }
1213 
1214     std::vector<std::string> accessibleAccounts;
1215     ErrCode result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
1216     if (result != ERR_OK) {
1217         ACCOUNT_LOGE("failed to get accessible account from data storage, result = %{public}d.", result);
1218         return result;
1219     }
1220 
1221     for (auto account : accessibleAccounts) {
1222         AppAccountInfo appAccountInfo;
1223 
1224         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
1225         if (result != ERR_OK) {
1226             ACCOUNT_LOGE("failed to get account info by id. result %{public}d.", result);
1227             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
1228         }
1229 
1230         appAccounts.emplace_back(appAccountInfo);
1231     }
1232 
1233     std::vector<AppAccountInfo> currentAppAccounts;
1234     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
1235     result = GetAllAccountsFromDataStorage(key, currentAppAccounts, bundleName, dataStoragePtr);
1236     if (result != ERR_OK) {
1237         ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
1238         return result;
1239     }
1240 
1241     std::transform(currentAppAccounts.begin(), currentAppAccounts.end(), std::back_inserter(appAccounts),
1242         [](auto account) { return account; });
1243 
1244     return ERR_OK;
1245 }
1246 
GetDataStorageByUserId( int32_t userId, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)1247 std::shared_ptr<AppAccountDataStorage> AppAccountControlManager::GetDataStorageByUserId(
1248     int32_t userId, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)
1249 {
1250     std::string storeId = std::to_string(userId);
1251     if (autoSync == true) {
1252         storeId = storeId + DATA_STORAGE_SUFFIX;
1253     }
1254     std::lock_guard<std::mutex> lock(storePtrMutex_);
1255     auto it = storePtrMap_.find(storeId);
1256     if (it != storePtrMap_.end()) {
1257         return it->second;
1258     }
1259     AccountDataStorageOptions options;
1260     options.area = DistributedKv::EL2;
1261     options.autoSync = autoSync;
1262     options.securityLevel = securityLevel;
1263     options.baseDir = EL2_DATA_STORAGE_PATH_PREFIX + std::to_string(userId) + EL2_DATA_STORAGE_PATH_SUFFIX;
1264     auto storePtr = std::make_shared<AppAccountDataStorage>(EL2_DATA_STORE_PREFIX + storeId, options);
1265     storePtrMap_.emplace(storeId, storePtr);
1266     return storePtr;
1267 }
1268 
GetDataStorage( const uid_t &uid, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)1269 std::shared_ptr<AppAccountDataStorage> AppAccountControlManager::GetDataStorage(
1270     const uid_t &uid, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)
1271 {
1272     return GetDataStorageByUserId(uid / UID_TRANSFORM_DIVISOR, autoSync, securityLevel);
1273 }
1274 
NeedSyncDataStorage(const AppAccountInfo &appAccountInfo)1275 bool AppAccountControlManager::NeedSyncDataStorage(const AppAccountInfo &appAccountInfo)
1276 {
1277     bool syncEnable = false;
1278     appAccountInfo.GetSyncEnable(syncEnable);
1279 
1280     if (syncEnable == false) {
1281         return false;
1282     }
1283     return true;
1284 }
1285 
GetAccountInfoFromDataStorage( AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)1286 ErrCode AppAccountControlManager::GetAccountInfoFromDataStorage(
1287     AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1288 {
1289     if (dataStoragePtr == nullptr) {
1290         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1291         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1292     }
1293 
1294     return dataStoragePtr->GetAccountInfoFromDataStorage(appAccountInfo);
1295 }
1296 
AddAccountInfoIntoDataStorage( AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)1297 ErrCode AppAccountControlManager::AddAccountInfoIntoDataStorage(
1298     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1299 {
1300     if (dataStoragePtr == nullptr) {
1301         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1302         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1303     }
1304 
1305     std::string owner;
1306     appAccountInfo.GetOwner(owner);
1307 
1308     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
1309     std::string key = owner + Constants::HYPHEN + std::to_string(appAccountInfo.GetAppIndex());
1310     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(key, accounts);
1311     if (result != ERR_OK) {
1312         ACCOUNT_LOGE("failed to get accounts by owner, result %{public}d, owner = %{public}s",
1313             result, owner.c_str());
1314         return result;
1315     }
1316 
1317     if (accounts.size() >= ACCOUNT_MAX_SIZE) {
1318         ACCOUNT_LOGE("account exceeds max size");
1319         return ERR_APPACCOUNT_SERVICE_ACCOUNT_MAX_SIZE;
1320     }
1321 
1322     result = dataStoragePtr->AddAccountInfoIntoDataStorage(appAccountInfo);
1323     if (result != ERR_OK) {
1324         ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
1325         return result;
1326     }
1327 
1328     // for sync data storage
1329 #ifdef DISTRIBUTED_FEATURE_ENABLED
1330     if (NeedSyncDataStorage(appAccountInfo) == true) {
1331         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1332         if (dataStorageSyncPtr == nullptr) {
1333             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1334             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1335         }
1336 
1337         result = dataStorageSyncPtr->AddAccountInfoIntoDataStorage(appAccountInfo);
1338         if (result != ERR_OK) {
1339             ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
1340             return result;
1341         }
1342     }
1343 #else  // DISTRIBUTED_FEATURE_ENABLED
1344     ACCOUNT_LOGI("No distributed feature!");
1345 #endif // DISTRIBUTED_FEATURE_ENABLED
1346 
1347     return ERR_OK;
1348 }
1349 
SaveAccountInfoIntoDataStorage( AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)1350 ErrCode AppAccountControlManager::SaveAccountInfoIntoDataStorage(
1351     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1352 {
1353     if (dataStoragePtr == nullptr) {
1354         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1355         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1356     }
1357 
1358     ErrCode result = dataStoragePtr->SaveAccountInfoIntoDataStorage(appAccountInfo);
1359     if (result != ERR_OK) {
1360         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
1361         return result;
1362     }
1363 
1364     // for sync data storage
1365 #ifdef DISTRIBUTED_FEATURE_ENABLED
1366     if (NeedSyncDataStorage(appAccountInfo) == true) {
1367         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1368         if (dataStorageSyncPtr == nullptr) {
1369             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1370             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1371         }
1372 
1373         std::string appAccountInfoFromDataStorage;
1374         result = dataStorageSyncPtr->GetValueFromKvStore(appAccountInfo.GetPrimeKey(), appAccountInfoFromDataStorage);
1375         if (result != ERR_OK) {
1376             ACCOUNT_LOGE("failed to get config by id from data storage, result %{public}d.", result);
1377 
1378             result = dataStorageSyncPtr->AddAccountInfo(appAccountInfo);
1379             if (result != ERR_OK) {
1380                 ACCOUNT_LOGE("failed to add account info, result = %{public}d", result);
1381                 return result;
1382             }
1383         } else {
1384             result = dataStorageSyncPtr->SaveAccountInfo(appAccountInfo);
1385             if (result != ERR_OK) {
1386                 ACCOUNT_LOGE("failed to save account info, result = %{public}d", result);
1387                 return result;
1388             }
1389         }
1390     }
1391 #else  // DISTRIBUTED_FEATURE_ENABLED
1392     ACCOUNT_LOGI("No distributed feature!");
1393 #endif // DISTRIBUTED_FEATURE_ENABLED
1394 
1395     return ERR_OK;
1396 }
1397 
DeleteAccountInfoFromDataStorage( AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)1398 ErrCode AppAccountControlManager::DeleteAccountInfoFromDataStorage(
1399     AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1400 {
1401     if (dataStoragePtr == nullptr) {
1402         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1403         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1404     }
1405 
1406     ErrCode result = dataStoragePtr->GetAccountInfoFromDataStorage(appAccountInfo);
1407     if (result != ERR_OK) {
1408         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
1409         return result;
1410     }
1411 
1412     result = dataStoragePtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1413     if (result != ERR_OK) {
1414         ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
1415         return result;
1416     }
1417 
1418     // for sync data storage
1419 #ifdef DISTRIBUTED_FEATURE_ENABLED
1420     if (NeedSyncDataStorage(appAccountInfo) == true) {
1421         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1422         if (dataStorageSyncPtr == nullptr) {
1423             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1424             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1425         }
1426 
1427         result = dataStorageSyncPtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1428         if (result != ERR_OK) {
1429             ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
1430         }
1431     }
1432 #else  // DISTRIBUTED_FEATURE_ENABLED
1433     ACCOUNT_LOGI("No distributed feature!");
1434 #endif // DISTRIBUTED_FEATURE_ENABLED
1435     return ERR_OK;
1436 }
1437 
SaveAuthorizedAccount(const std::string &bundleName, AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)1438 ErrCode AppAccountControlManager::SaveAuthorizedAccount(const std::string &bundleName,
1439     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1440 {
1441     if (dataStoragePtr == nullptr) {
1442         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1443         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1444     }
1445 
1446     ErrCode result = SaveAuthorizedAccountIntoDataStorage(bundleName, appAccountInfo, dataStoragePtr);
1447     if (result != ERR_OK) {
1448         ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1449         return result;
1450     }
1451 
1452     // for sync data storage
1453 #ifdef DISTRIBUTED_FEATURE_ENABLED
1454     if (NeedSyncDataStorage(appAccountInfo) == true) {
1455         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1456         if (dataStorageSyncPtr == nullptr) {
1457             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1458             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1459         }
1460 
1461         result = SaveAuthorizedAccountIntoDataStorage(bundleName, appAccountInfo, dataStorageSyncPtr);
1462         if (result != ERR_OK) {
1463             ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1464             return result;
1465         }
1466     }
1467 #else  // DISTRIBUTED_FEATURE_ENABLED
1468     ACCOUNT_LOGI("No distributed feature!");
1469 #endif // DISTRIBUTED_FEATURE_ENABLED
1470 
1471     return ERR_OK;
1472 }
1473 
RemoveAuthorizedAccount(const std::string &bundleName, AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)1474 ErrCode AppAccountControlManager::RemoveAuthorizedAccount(const std::string &bundleName,
1475     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1476 {
1477     if (dataStoragePtr == nullptr) {
1478         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1479         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1480     }
1481 
1482     ErrCode result = RemoveAuthorizedAccountFromDataStorage(bundleName, appAccountInfo, dataStoragePtr);
1483     if (result != ERR_OK) {
1484         ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1485         return result;
1486     }
1487 
1488     // for sync data storage
1489 #ifdef DISTRIBUTED_FEATURE_ENABLED
1490     if (NeedSyncDataStorage(appAccountInfo) == true) {
1491         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1492         if (dataStorageSyncPtr == nullptr) {
1493             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1494             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1495         }
1496 
1497         result = RemoveAuthorizedAccountFromDataStorage(bundleName, appAccountInfo, dataStorageSyncPtr);
1498         if (result != ERR_OK) {
1499             ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1500             return result;
1501         }
1502     }
1503 #else  // DISTRIBUTED_FEATURE_ENABLED
1504     ACCOUNT_LOGI("No distributed feature!");
1505 #endif // DISTRIBUTED_FEATURE_ENABLED
1506 
1507     return ERR_OK;
1508 }
1509 
SaveAuthorizedAccountIntoDataStorage(const std::string &authorizedApp, AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)1510 ErrCode AppAccountControlManager::SaveAuthorizedAccountIntoDataStorage(const std::string &authorizedApp,
1511     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1512 {
1513     if (dataStoragePtr == nullptr) {
1514         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1515         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1516     }
1517 
1518     std::string authorizedAccounts;
1519     ErrCode result = dataStoragePtr->GetValueFromKvStore(AUTHORIZED_ACCOUNTS,
1520         authorizedAccounts);
1521     if (result != ERR_OK) {
1522         ACCOUNT_LOGE("failed to get config by id from data storage, result %{public}d.", result);
1523     }
1524 
1525     std::vector<std::string> accessibleAccounts;
1526     auto jsonObject = dataStoragePtr->GetAccessibleAccountsFromAuthorizedAccounts(
1527         authorizedAccounts, authorizedApp, accessibleAccounts);
1528 
1529     auto accountId = appAccountInfo.GetPrimeKey();
1530 
1531     auto it = std::find(accessibleAccounts.begin(), accessibleAccounts.end(), accountId);
1532     if (it == accessibleAccounts.end()) {
1533         accessibleAccounts.emplace_back(accountId);
1534     }
1535 
1536     auto accessibleAccountArray = Json::array();
1537     std::transform(accessibleAccounts.begin(), accessibleAccounts.end(), std::back_inserter(accessibleAccountArray),
1538         [](auto account) { return account; });
1539 
1540     jsonObject[authorizedApp] = accessibleAccountArray;
1541     try {
1542         authorizedAccounts = jsonObject.dump();
1543     } catch (Json::type_error& err) {
1544         ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
1545         return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
1546     }
1547 
1548     result = dataStoragePtr->PutValueToKvStore(AUTHORIZED_ACCOUNTS, authorizedAccounts);
1549     if (result != ERR_OK) {
1550         ACCOUNT_LOGE("PutValueToKvStore failed! result %{public}d.", result);
1551     }
1552     return result;
1553 }
1554 
RemoveAuthorizedAccountFromDataStorage(const std::string &authorizedApp, AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)1555 ErrCode AppAccountControlManager::RemoveAuthorizedAccountFromDataStorage(const std::string &authorizedApp,
1556     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1557 {
1558     if (dataStoragePtr == nullptr) {
1559         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1560         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1561     }
1562 
1563     std::string authorizedAccounts;
1564     ErrCode result = dataStoragePtr->GetValueFromKvStore(AUTHORIZED_ACCOUNTS,
1565         authorizedAccounts);
1566     if (result != ERR_OK) {
1567         ACCOUNT_LOGE("failed to get authorized accounts from data storage, result %{public}d.", result);
1568     }
1569 
1570     std::vector<std::string> accessibleAccounts;
1571     auto jsonObject = dataStoragePtr->GetAccessibleAccountsFromAuthorizedAccounts(
1572         authorizedAccounts, authorizedApp, accessibleAccounts);
1573 
1574     auto accountId = appAccountInfo.GetPrimeKey();
1575 
1576     auto it = std::find(accessibleAccounts.begin(), accessibleAccounts.end(), accountId);
1577     if (it != accessibleAccounts.end()) {
1578         accessibleAccounts.erase(it);
1579     }
1580 
1581     auto accessibleAccountArray = Json::array();
1582     std::transform(accessibleAccounts.begin(), accessibleAccounts.end(), std::back_inserter(accessibleAccountArray),
1583         [](auto account) { return account; });
1584 
1585     jsonObject[authorizedApp] = accessibleAccountArray;
1586     try {
1587         authorizedAccounts = jsonObject.dump();
1588     } catch (Json::type_error& err) {
1589         ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
1590         return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
1591     }
1592 
1593     result = dataStoragePtr->PutValueToKvStore(AUTHORIZED_ACCOUNTS, authorizedAccounts);
1594     if (result != ERR_OK) {
1595         ACCOUNT_LOGE("failed to save config info, result %{public}d.", result);
1596         return result;
1597     }
1598 
1599     return ERR_OK;
1600 }
1601 }  // namespace AccountSA
1602 }  // namespace OHOS
1603