• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "bundle_manager_adapter.h"
27 #include "ipc_skeleton.h"
28 #include "iservice_registry.h"
29 #include "ohos_account_kits.h"
30 #include "singleton.h"
31 #include "system_ability_definition.h"
32 
33 namespace OHOS {
34 namespace AccountSA {
35 namespace {
36 const std::string GET_ALL_APP_ACCOUNTS = "ohos.permission.GET_ALL_APP_ACCOUNTS";
37 const std::string DATA_STORAGE_SUFFIX = "_sync";
38 const std::string AUTHORIZED_ACCOUNTS = "authorizedAccounts";
39 }
GetInstance()40 AppAccountControlManager &AppAccountControlManager::GetInstance()
41 {
42     static AppAccountControlManager *instance = new (std::nothrow) AppAccountControlManager();
43     return *instance;
44 }
45 
AddAccount(const std::string & name,const std::string & extraInfo,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)46 ErrCode AppAccountControlManager::AddAccount(const std::string &name, const std::string &extraInfo, const uid_t &uid,
47     const std::string &bundleName, AppAccountInfo &appAccountInfo)
48 {
49     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
50     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
51     if (result != ERR_OK) {
52         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
53 
54         appAccountInfo.SetExtraInfo(extraInfo);
55 
56         result = AddAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
57         if (result != ERR_OK) {
58             ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
59             return result;
60         }
61     } else {
62         ACCOUNT_LOGE("add existing account");
63         return ERR_APPACCOUNT_SERVICE_ADD_EXISTING_ACCOUNT;
64     }
65 
66     return ERR_OK;
67 }
68 
CreateAccount(const std::string & name,const CreateAccountOptions & options,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)69 ErrCode AppAccountControlManager::CreateAccount(const std::string &name, const CreateAccountOptions &options,
70     const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
71 {
72     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
73     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
74     if (result != ERR_OK) {
75         result = appAccountInfo.InitCustomData(options.customData);
76         if (result != ERR_OK) {
77             ACCOUNT_LOGE("failed to set custom data, result %{public}d.", result);
78             return ERR_APPACCOUNT_SERVICE_SET_ASSOCIATED_DATA;
79         }
80         result = AddAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
81         if (result != ERR_OK) {
82             ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
83             return result;
84         }
85     } else {
86         ACCOUNT_LOGE("add existing account");
87         return ERR_APPACCOUNT_SERVICE_ADD_EXISTING_ACCOUNT;
88     }
89 
90     return ERR_OK;
91 }
92 
DeleteAccount(const std::string & name,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)93 ErrCode AppAccountControlManager::DeleteAccount(
94     const std::string &name, const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
95 {
96     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
97     ErrCode result = DeleteAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr, uid);
98     if (result != ERR_OK) {
99         ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
100         return result;
101     }
102     RemoveAssociatedDataCacheByAccount(uid, name);
103 
104     std::set<std::string> authorizedApps;
105     appAccountInfo.GetAuthorizedApps(authorizedApps);
106     for (auto authorizedApp : authorizedApps) {
107         // remove authorized account from data storage
108         result = RemoveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, uid);
109         if (result != ERR_OK) {
110             ACCOUNT_LOGE("failed to save authorized account into data storage, result %{public}d.", result);
111             return result;
112         }
113     }
114 
115     return ERR_OK;
116 }
117 
GetAccountExtraInfo(const std::string & name,std::string & extraInfo,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)118 ErrCode AppAccountControlManager::GetAccountExtraInfo(const std::string &name, std::string &extraInfo,
119     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
120 {
121     AppAccountInfo appAccountInfo(name, bundleName);
122     appAccountInfo.SetAppIndex(appIndex);
123     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
124     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
125     if (result != ERR_OK) {
126         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
127         return result;
128     }
129 
130     appAccountInfo.GetExtraInfo(extraInfo);
131 
132     return ERR_OK;
133 }
134 
SetAccountExtraInfo(const std::string & name,const std::string & extraInfo,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)135 ErrCode AppAccountControlManager::SetAccountExtraInfo(const std::string &name, const std::string &extraInfo,
136     const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
137 {
138     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
139     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
140     if (result != ERR_OK) {
141         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
142         return result;
143     }
144 
145     appAccountInfo.SetExtraInfo(extraInfo);
146 
147     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
148     if (result != ERR_OK) {
149         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
150         return result;
151     }
152 
153     ACCOUNT_LOGD("end, result = %{public}d", result);
154 
155     return result;
156 }
157 
EnableAppAccess(const std::string & name,const std::string & authorizedApp,AppAccountCallingInfo & appAccountCallingInfo,AppAccountInfo & appAccountInfo,const uint32_t apiVersion)158 ErrCode AppAccountControlManager::EnableAppAccess(const std::string &name, const std::string &authorizedApp,
159     AppAccountCallingInfo &appAccountCallingInfo, AppAccountInfo &appAccountInfo, const uint32_t apiVersion)
160 {
161     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
162     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
163     if (result != ERR_OK) {
164         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
165         return result;
166     }
167 
168     result = appAccountInfo.EnableAppAccess(authorizedApp, apiVersion);
169     if (result != ERR_OK) {
170         ACCOUNT_LOGE("failed to enable app access, result %{public}d.", result);
171         return ERR_APPACCOUNT_SERVICE_ENABLE_APP_ACCESS_ALREADY_EXISTS;
172     }
173 
174     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
175     if (result != ERR_OK) {
176         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
177         return result;
178     }
179 
180     // save authorized account into data storage
181     result = SaveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
182     if (result != ERR_OK) {
183         ACCOUNT_LOGE("failed to save authorized account into data storage, result %{public}d.", result);
184         return result;
185     }
186 
187     return ERR_OK;
188 }
189 
DisableAppAccess(const std::string & name,const std::string & authorizedApp,AppAccountCallingInfo & appAccountCallingInfo,AppAccountInfo & appAccountInfo,const uint32_t apiVersion)190 ErrCode AppAccountControlManager::DisableAppAccess(const std::string &name, const std::string &authorizedApp,
191     AppAccountCallingInfo &appAccountCallingInfo, AppAccountInfo &appAccountInfo, const uint32_t apiVersion)
192 {
193     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
194     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
195     if (result != ERR_OK) {
196         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
197         return result;
198     }
199 
200     result = appAccountInfo.DisableAppAccess(authorizedApp, apiVersion);
201     if (result != ERR_OK) {
202         ACCOUNT_LOGE("failed to disable app access, result %{public}d.", result);
203         return ERR_APPACCOUNT_SERVICE_DISABLE_APP_ACCESS_NOT_EXISTED;
204     }
205 
206     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
207     if (result != ERR_OK) {
208         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
209         return result;
210     }
211 
212     // remove authorized account from data storage
213     result = RemoveAuthorizedAccount(authorizedApp, appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
214     if (result != ERR_OK) {
215         ACCOUNT_LOGE("failed to save authorized account into data storage, result %{public}d.", result);
216         return result;
217     }
218 
219     return ERR_OK;
220 }
221 
CheckAppAccess(const std::string & name,const std::string & authorizedApp,bool & isAccessible,const AppAccountCallingInfo & appAccountCallingInfo)222 ErrCode AppAccountControlManager::CheckAppAccess(const std::string &name, const std::string &authorizedApp,
223     bool &isAccessible, const AppAccountCallingInfo &appAccountCallingInfo)
224 {
225     isAccessible = false;
226     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(appAccountCallingInfo.callingUid);
227     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
228     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
229     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
230     if (result != ERR_OK) {
231         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
232         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
233     }
234     return appAccountInfo.CheckAppAccess(authorizedApp, isAccessible);
235 }
236 
CheckAppAccountSyncEnable(const std::string & name,bool & syncEnable,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)237 ErrCode AppAccountControlManager::CheckAppAccountSyncEnable(const std::string &name,
238     bool &syncEnable, const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
239 {
240     AppAccountInfo appAccountInfo(name, bundleName);
241     appAccountInfo.SetAppIndex(appIndex);
242     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
243     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
244     if (result != ERR_OK) {
245         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
246         return result;
247     }
248 
249     appAccountInfo.GetSyncEnable(syncEnable);
250 
251     return ERR_OK;
252 }
253 
SetAppAccountSyncEnable(const std::string & name,const bool & syncEnable,const uid_t & uid,const std::string & bundleName,AppAccountInfo & appAccountInfo)254 ErrCode AppAccountControlManager::SetAppAccountSyncEnable(const std::string &name, const bool &syncEnable,
255     const uid_t &uid, const std::string &bundleName, AppAccountInfo &appAccountInfo)
256 {
257     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(uid);
258     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
259     if (result != ERR_OK) {
260         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
261         return result;
262     }
263 
264     appAccountInfo.SetSyncEnable(syncEnable);
265 
266     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, uid);
267     if (result != ERR_OK) {
268         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
269         return result;
270     }
271 
272     return ERR_OK;
273 }
274 
PopDataFromAssociatedDataCache()275 void AppAccountControlManager::PopDataFromAssociatedDataCache()
276 {
277     auto it = associatedDataCache_.begin();
278     auto toPopedIt = it++;
279     for (; it != associatedDataCache_.end(); ++it) {
280         if (toPopedIt->second.freq > it->second.freq) {
281             toPopedIt = it;
282         }
283         it->second.freq = 0;
284     }
285     associatedDataCache_.erase(toPopedIt);
286 }
287 
GetAssociatedDataFromStorage(const std::string & name,const std::string & key,std::string & value,const uid_t & uid,const uint32_t & appIndex)288 ErrCode AppAccountControlManager::GetAssociatedDataFromStorage(const std::string &name, const std::string &key,
289     std::string &value, const uid_t &uid, const uint32_t &appIndex)
290 {
291     std::string bundleName;
292     if (BundleManagerAdapter::GetInstance()->GetNameForUid(uid, bundleName) != ERR_OK) {
293         ACCOUNT_LOGE("failed to get bundle name");
294         return ERR_APPACCOUNT_SERVICE_GET_BUNDLE_NAME;
295     }
296     AppAccountInfo appAccountInfo(name, bundleName);
297     appAccountInfo.SetAppIndex(appIndex);
298     std::shared_ptr<AppAccountDataStorage> storePtr = GetDataStorage(uid);
299     if (storePtr == nullptr) {
300         ACCOUNT_LOGE("failed to get data storage");
301         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
302     }
303     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, storePtr);
304     if (result != ERR_OK) {
305         ACCOUNT_LOGE("failed to get account info from data storage");
306         return result;
307     }
308     AssociatedDataCacheItem item;
309     item.name = name;
310     item.freq = 0;
311     appAccountInfo.GetAllAssociatedData(item.data);
312     auto it = item.data.find(key);
313     if (it != item.data.end()) {
314         value = it->second;
315     } else {
316         result = ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_KEY_NOT_EXIST;
317     }
318     if ((associatedDataCache_.size() == 0) && (!RegisterApplicationStateObserver())) {
319         ACCOUNT_LOGE("failed to register application state observer");
320         return result;
321     }
322     if (associatedDataCache_.size() >= ASSOCIATED_DATA_CACHE_MAX_SIZE) {
323         PopDataFromAssociatedDataCache();
324     }
325     associatedDataCache_.emplace(uid, item);
326     return result;
327 }
328 
GetAssociatedData(const std::string & name,const std::string & key,std::string & value,const uid_t & uid)329 ErrCode AppAccountControlManager::GetAssociatedData(const std::string &name, const std::string &key,
330     std::string &value, const uid_t &uid)
331 {
332     std::lock_guard<std::mutex> lock(associatedDataMutex_);
333     auto it = associatedDataCache_.find(uid);
334     if ((it == associatedDataCache_.end()) || (it->second.name != name)) {
335         uint32_t callingTokenId = IPCSkeleton::GetCallingTokenID();
336         Security::AccessToken::HapTokenInfo hapTokenInfo;
337         int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callingTokenId, hapTokenInfo);
338         if ((result != 0) || (hapTokenInfo.instIndex < 0)) {
339             ACCOUNT_LOGE("failed to get app index");
340             return ERR_APPACCOUNT_SERVICE_GET_APP_INDEX;
341         }
342         associatedDataCache_.erase(uid);
343         return GetAssociatedDataFromStorage(name, key, value, uid, hapTokenInfo.instIndex);
344     }
345     it->second.freq++;
346     auto dataIt = it->second.data.find(key);
347     if (dataIt == it->second.data.end()) {
348         return ERR_APPACCOUNT_SERVICE_ASSOCIATED_DATA_KEY_NOT_EXIST;
349     }
350     value = dataIt->second;
351     return ERR_OK;
352 }
353 
SetAssociatedData(const std::string & name,const std::string & key,const std::string & value,const AppAccountCallingInfo & appAccountCallingInfo)354 ErrCode AppAccountControlManager::SetAssociatedData(const std::string &name, const std::string &key,
355     const std::string &value, const AppAccountCallingInfo &appAccountCallingInfo)
356 {
357     std::shared_ptr<AppAccountDataStorage> storePtr = GetDataStorage(appAccountCallingInfo.callingUid);
358     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
359     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
360     std::lock_guard<std::mutex> lock(associatedDataMutex_);
361     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, storePtr);
362     if (result != ERR_OK) {
363         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
364         return result;
365     }
366     result = appAccountInfo.SetAssociatedData(key, value);
367     if (result != ERR_OK) {
368         ACCOUNT_LOGE("failed to set associated data, result %{public}d.", result);
369         return result;
370     }
371     result = SaveAccountInfoIntoDataStorage(appAccountInfo, storePtr, appAccountCallingInfo.callingUid);
372     if (result != ERR_OK) {
373         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
374         return result;
375     }
376     auto it = associatedDataCache_.find(appAccountCallingInfo.callingUid);
377     if ((it != associatedDataCache_.end()) && (it->second.name == name)) {
378         it->second.data[key] = value;
379     }
380     return ERR_OK;
381 }
382 
GetAccountCredential(const std::string & name,const std::string & credentialType,std::string & credential,const AppAccountCallingInfo & appAccountCallingInfo)383 ErrCode AppAccountControlManager::GetAccountCredential(const std::string &name, const std::string &credentialType,
384     std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo)
385 {
386     AppAccountInfo appAccountInfo(name, appAccountCallingInfo.bundleName);
387     appAccountInfo.SetAppIndex(appAccountCallingInfo.appIndex);
388     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
389         GetDataStorage(appAccountCallingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
390     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
391     if (result != ERR_OK) {
392         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
393         return result;
394     }
395 
396     result = appAccountInfo.GetAccountCredential(credentialType, credential);
397     if (result != ERR_OK) {
398         ACCOUNT_LOGE("failed to get account credential, result %{public}d.", result);
399         return result;
400     }
401 
402     return ERR_OK;
403 }
404 
SetAccountCredential(const std::string & name,const std::string & credentialType,const std::string & credential,const AppAccountCallingInfo & appAccountCallingInfo,bool isDelete)405 ErrCode AppAccountControlManager::SetAccountCredential(const std::string &name, const std::string &credentialType,
406     const std::string &credential, const AppAccountCallingInfo &appAccountCallingInfo, bool isDelete)
407 {
408     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
409         GetDataStorage(appAccountCallingInfo.callingUid, false, DistributedKv::SecurityLevel::S4);
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 
418     result = appAccountInfo.SetAccountCredential(credentialType, credential, isDelete);
419     if (result != ERR_OK) {
420         ACCOUNT_LOGE("failed to set account credential, result %{public}d.", result);
421         return result;
422     }
423 
424     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, appAccountCallingInfo.callingUid);
425     if (result != ERR_OK) {
426         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
427         return result;
428     }
429 
430     return ERR_OK;
431 }
432 
GetOAuthToken(const AuthenticatorSessionRequest & request,std::string & token,const uint32_t apiVersion)433 ErrCode AppAccountControlManager::GetOAuthToken(
434     const AuthenticatorSessionRequest &request, std::string &token, const uint32_t apiVersion)
435 {
436     AppAccountInfo appAccountInfo(request.name, request.owner);
437     appAccountInfo.SetAppIndex(request.appIndex);
438     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
439         GetDataStorage(request.callerUid, false, DistributedKv::SecurityLevel::S4);
440     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
441     if (result != ERR_OK) {
442         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
443         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
444     }
445     bool isVisible = false;
446     result = appAccountInfo.CheckOAuthTokenVisibility(
447         request.authType, request.callerBundleName, isVisible, apiVersion);
448     if ((result != ERR_OK) || (!isVisible)) {
449         ACCOUNT_LOGE("failed to get oauth token for permission denied, result %{public}d.", result);
450         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
451     }
452     return appAccountInfo.GetOAuthToken(request.authType, token, apiVersion);
453 }
454 
SetOAuthToken(const AuthenticatorSessionRequest & request)455 ErrCode AppAccountControlManager::SetOAuthToken(const AuthenticatorSessionRequest &request)
456 {
457     std::lock_guard<std::mutex> lock(mutex_);
458     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
459     appAccountInfo.SetAppIndex(request.appIndex);
460     std::shared_ptr<AppAccountDataStorage> dataStoragePtr =
461         GetDataStorage(request.callerUid, false, DistributedKv::SecurityLevel::S4);
462     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
463     if (result != ERR_OK) {
464         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
465         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
466     }
467     result = appAccountInfo.SetOAuthToken(request.authType, request.token);
468     if (result != ERR_OK) {
469         ACCOUNT_LOGE("failed to set oauth token, result %{public}d.", result);
470         return result;
471     }
472     result = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
473     if (result != ERR_OK) {
474         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
475         return result;
476     }
477     return ERR_OK;
478 }
479 
DeleteOAuthToken(const AuthenticatorSessionRequest & request,const uint32_t apiVersion)480 ErrCode AppAccountControlManager::DeleteOAuthToken(
481     const AuthenticatorSessionRequest &request, const uint32_t apiVersion)
482 {
483     std::lock_guard<std::mutex> lock(mutex_);
484     AppAccountInfo appAccountInfo(request.name, request.owner);
485     appAccountInfo.SetAppIndex(request.appIndex);
486     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
487     ErrCode ret = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
488     if (ret != ERR_OK) {
489         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", ret);
490         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
491     }
492     bool isOwnerSelf = false;
493     if (request.owner == request.callerBundleName) {
494         isOwnerSelf = true;
495     }
496     bool isVisible = false;
497     ret = appAccountInfo.CheckOAuthTokenVisibility(request.authType, request.callerBundleName, isVisible, apiVersion);
498     if ((!isVisible) || (ret != ERR_OK)) {
499         ACCOUNT_LOGE("failed to delete oauth token for permission denied, result %{public}d.", ret);
500         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
501     }
502     if (apiVersion >= Constants::API_VERSION9) {
503         ret = appAccountInfo.DeleteAuthToken(request.authType, request.token, isOwnerSelf);
504         if (ret != ERR_OK) {
505             return ret;
506         }
507     } else {
508         ret = appAccountInfo.DeleteOAuthToken(request.authType, request.token);
509         if (ret == ERR_APPACCOUNT_SERVICE_OAUTH_TOKEN_NOT_EXIST) {
510             return ERR_OK;
511         }
512     }
513     ret = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
514     if (ret != ERR_OK) {
515         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", ret);
516         return ret;
517     }
518     return ERR_OK;
519 }
520 
SetOAuthTokenVisibility(const AuthenticatorSessionRequest & request,const uint32_t apiVersion)521 ErrCode AppAccountControlManager::SetOAuthTokenVisibility(
522     const AuthenticatorSessionRequest &request, const uint32_t apiVersion)
523 {
524     std::lock_guard<std::mutex> lock(mutex_);
525     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
526     appAccountInfo.SetAppIndex(request.appIndex);
527     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
528     ErrCode ret = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
529     if (ret != ERR_OK) {
530         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", ret);
531         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
532     }
533     ret = appAccountInfo.SetOAuthTokenVisibility(
534         request.authType, request.bundleName, request.isTokenVisible, apiVersion);
535     if (ret != ERR_OK) {
536         ACCOUNT_LOGE("failed to set oauth token visibility, result %{public}d.", ret);
537         return ret;
538     }
539     ret = SaveAccountInfoIntoDataStorage(appAccountInfo, dataStoragePtr, request.callerUid);
540     if (ret != ERR_OK) {
541         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", ret);
542         return ret;
543     }
544     return ERR_OK;
545 }
546 
CheckOAuthTokenVisibility(const AuthenticatorSessionRequest & request,bool & isVisible,const uint32_t apiVersion)547 ErrCode AppAccountControlManager::CheckOAuthTokenVisibility(
548     const AuthenticatorSessionRequest &request, bool &isVisible, const uint32_t apiVersion)
549 {
550     isVisible = false;
551     AppAccountInfo appAccountInfo(request.name, request.owner);
552     appAccountInfo.SetAppIndex(request.appIndex);
553     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
554     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
555     if (result != ERR_OK) {
556         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
557         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
558     }
559     return appAccountInfo.CheckOAuthTokenVisibility(request.authType, request.bundleName, isVisible, apiVersion);
560 }
561 
GetAllOAuthTokens(const AuthenticatorSessionRequest & request,std::vector<OAuthTokenInfo> & tokenInfos)562 ErrCode AppAccountControlManager::GetAllOAuthTokens(
563     const AuthenticatorSessionRequest &request, std::vector<OAuthTokenInfo> &tokenInfos)
564 {
565     tokenInfos.clear();
566     AppAccountInfo appAccountInfo(request.name, request.owner);
567     appAccountInfo.SetAppIndex(request.appIndex);
568     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
569     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
570     if (result != ERR_OK) {
571         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
572         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
573     }
574     std::vector<OAuthTokenInfo> allTokenInfos;
575     result = appAccountInfo.GetAllOAuthTokens(allTokenInfos);
576     if (result != ERR_OK) {
577         ACCOUNT_LOGE("failed to get all oauth token from data storage, result %{public}d.", result);
578         return result;
579     }
580     if (request.callerBundleName == request.owner) {
581         tokenInfos = allTokenInfos;
582         return ERR_OK;
583     }
584     for (auto tokenInfo : allTokenInfos) {
585         if (tokenInfo.token.empty()) {
586             continue;
587         }
588         auto it = tokenInfo.authList.find(request.callerBundleName);
589         if (it != tokenInfo.authList.end()) {
590             tokenInfo.authList.clear();
591             tokenInfos.push_back(tokenInfo);
592         }
593     }
594     return ERR_OK;
595 }
596 
GetOAuthList(const AuthenticatorSessionRequest & request,std::set<std::string> & oauthList,const uint32_t apiVersion)597 ErrCode AppAccountControlManager::GetOAuthList(
598     const AuthenticatorSessionRequest &request, std::set<std::string> &oauthList, const uint32_t apiVersion)
599 {
600     AppAccountInfo appAccountInfo(request.name, request.callerBundleName);
601     appAccountInfo.SetAppIndex(request.appIndex);
602     std::shared_ptr<AppAccountDataStorage> dataStoragePtr = GetDataStorage(request.callerUid);
603     ErrCode result = GetAccountInfoFromDataStorage(appAccountInfo, dataStoragePtr);
604     if (result != ERR_OK) {
605         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
606         return ERR_APPACCOUNT_SERVICE_ACCOUNT_NOT_EXIST;
607     }
608     return appAccountInfo.GetOAuthList(request.authType, oauthList, apiVersion);
609 }
610 
GetAllAccounts(const std::string & owner,std::vector<AppAccountInfo> & appAccounts,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)611 ErrCode AppAccountControlManager::GetAllAccounts(const std::string &owner, std::vector<AppAccountInfo> &appAccounts,
612     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
613 {
614     appAccounts.clear();
615 
616     auto dataStoragePtr = GetDataStorage(uid);
617     if (dataStoragePtr == nullptr) {
618         ACCOUNT_LOGE("dataStoragePtr is nullptr");
619         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
620     }
621     ErrCode result = AccountPermissionManager::VerifyPermission(GET_ALL_APP_ACCOUNTS);
622     if ((bundleName == owner) || (result == ERR_OK)) {
623         std::string key = owner + Constants::HYPHEN + std::to_string(appIndex);
624         result = GetAllAccountsFromDataStorage(key, appAccounts, owner, dataStoragePtr);
625         if (result != ERR_OK) {
626             ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
627             return result;
628         }
629         return ERR_OK;
630     }
631 
632     std::vector<std::string> accessibleAccounts;
633     result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
634     if (result != ERR_OK) {
635         ACCOUNT_LOGE("failed to get accessible account from data storage, result %{public}d.", result);
636         return result;
637     }
638     for (auto account : accessibleAccounts) {
639         AppAccountInfo appAccountInfo;
640         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
641         if (result != ERR_OK) {
642             ACCOUNT_LOGE("failed to get account info by id, result %{public}d.", result);
643             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
644         }
645         if (appAccountInfo.GetOwner() == owner) {
646             appAccounts.emplace_back(appAccountInfo);
647         }
648     }
649     return ERR_OK;
650 }
651 
LoadAllAppAccounts(const std::shared_ptr<OHOS::AccountSA::AppAccountDataStorage> & dataStoragePtr,std::vector<AppAccountInfo> & appAccounts)652 static ErrCode LoadAllAppAccounts(const std::shared_ptr<OHOS::AccountSA::AppAccountDataStorage> &dataStoragePtr,
653     std::vector<AppAccountInfo> &appAccounts)
654 {
655     std::map<std::string, std::shared_ptr<IAccountInfo>> infos;
656     ErrCode result = dataStoragePtr->LoadAllData(infos);
657     if (result != ERR_OK) {
658         ACCOUNT_LOGE("LoadAllData failed!");
659         return result;
660     }
661     for (auto it = infos.begin(); it != infos.end(); ++it) {
662         if (it->first == AUTHORIZED_ACCOUNTS) {
663             continue;
664         }
665         AppAccountInfo curAppInfo = *(std::static_pointer_cast<AppAccountInfo>(it->second));
666         appAccounts.emplace_back(curAppInfo);
667     }
668     return ERR_OK;
669 }
670 
GetAllAccessibleAccounts(std::vector<AppAccountInfo> & appAccounts,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)671 ErrCode AppAccountControlManager::GetAllAccessibleAccounts(std::vector<AppAccountInfo> &appAccounts,
672     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
673 {
674     appAccounts.clear();
675 
676     auto dataStoragePtr = GetDataStorage(uid);
677     if (dataStoragePtr == nullptr) {
678         ACCOUNT_LOGE("dataStoragePtr is nullptr");
679         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
680     }
681     ErrCode result = AccountPermissionManager::VerifyPermission(GET_ALL_APP_ACCOUNTS);
682     if (result == ERR_OK) {
683         return LoadAllAppAccounts(dataStoragePtr, appAccounts);
684     }
685     std::vector<std::string> accessibleAccounts;
686     result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
687     if (result != ERR_OK) {
688         ACCOUNT_LOGE("failed to get accessible account from data storage, result %{public}d.", result);
689         return result;
690     }
691 
692     for (auto account : accessibleAccounts) {
693         AppAccountInfo appAccountInfo;
694 
695         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
696         if (result != ERR_OK) {
697             ACCOUNT_LOGE("failed to get account info by id, result %{public}d.", result);
698             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
699         }
700 
701         appAccounts.emplace_back(appAccountInfo);
702     }
703 
704     std::vector<AppAccountInfo> currentAppAccounts;
705     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
706     result = GetAllAccountsFromDataStorage(key, currentAppAccounts, bundleName, dataStoragePtr);
707     if (result != ERR_OK) {
708         ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
709         return result;
710     }
711 
712     std::transform(currentAppAccounts.begin(), currentAppAccounts.end(), std::back_inserter(appAccounts),
713         [](auto account) { return account; });
714 
715     return ERR_OK;
716 }
717 
SelectAccountsByOptions(const SelectAccountsOptions & options,const sptr<IAppAccountAuthenticatorCallback> & callback,const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)718 ErrCode AppAccountControlManager::SelectAccountsByOptions(
719     const SelectAccountsOptions &options, const sptr<IAppAccountAuthenticatorCallback> &callback,
720     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
721 {
722     AAFwk::Want result;
723     if ((!options.hasAccounts) && (!options.hasOwners) && (!options.hasLabels)) {
724         callback->OnResult(ERR_JS_SUCCESS, result);
725         return ERR_OK;
726     }
727     std::set<std::string> allowedAccounts;
728     for (auto account : options.allowedAccounts) {
729         allowedAccounts.emplace(account.first + "_" + account.second);
730     }
731     std::set<std::string> allowedOwners(options.allowedOwners.begin(), options.allowedOwners.end());
732     std::vector<AppAccountInfo> accessibleAccounts;
733     ErrCode errCode = GetAllAccessibleAccounts(accessibleAccounts, uid, bundleName, appIndex);
734     if (errCode != ERR_OK) {
735         ACCOUNT_LOGE("failed to get all accessible accounts");
736         return errCode;
737     }
738     std::vector<AppAccountInfo> candidateAccounts;
739     for (auto account : accessibleAccounts) {
740         std::string owner = account.GetOwner();
741         if (options.hasOwners && allowedOwners.count(owner) == 0) {
742             continue;
743         }
744         if (options.hasAccounts && allowedAccounts.count(owner + "_" + account.GetName()) == 0) {
745             continue;
746         }
747         candidateAccounts.push_back(account);
748     }
749     if (options.requiredLabels.size() == 0) {
750         std::vector<std::string> names;
751         std::vector<std::string> owners;
752         for (auto account : candidateAccounts) {
753             names.push_back(account.GetName());
754             owners.push_back(account.GetOwner());
755         }
756         result.SetParam(Constants::KEY_ACCOUNT_NAMES, names);
757         result.SetParam(Constants::KEY_ACCOUNT_OWNERS, owners);
758         callback->OnResult(ERR_JS_SUCCESS, result);
759         return ERR_OK;
760     }
761     AuthenticatorSessionRequest request;
762     request.callback = callback;
763     request.callerUid = uid;
764     request.labels = options.requiredLabels;
765     return AppAccountAuthenticatorSessionManager::GetInstance().SelectAccountsByOptions(candidateAccounts, request);
766 }
767 
RemoveAssociatedDataCacheByUid(const uid_t & uid)768 void AppAccountControlManager::RemoveAssociatedDataCacheByUid(const uid_t &uid)
769 {
770     std::lock_guard<std::mutex> lock(associatedDataMutex_);
771     associatedDataCache_.erase(uid);
772     if (associatedDataCache_.empty()) {
773         UnregisterApplicationStateObserver();
774     }
775 }
776 
RemoveAssociatedDataCacheByAccount(const uid_t & uid,const std::string & name)777 void AppAccountControlManager::RemoveAssociatedDataCacheByAccount(const uid_t &uid, const std::string &name)
778 {
779     std::lock_guard<std::mutex> lock(associatedDataMutex_);
780     auto it = associatedDataCache_.find(uid);
781     if ((it == associatedDataCache_.end()) || (it->second.name != name)) {
782         return;
783     }
784     associatedDataCache_.erase(it);
785     if (associatedDataCache_.empty()) {
786         UnregisterApplicationStateObserver();
787     }
788 }
789 
OnPackageRemoved(const uid_t & uid,const std::string & bundleName,const uint32_t & appIndex)790 ErrCode AppAccountControlManager::OnPackageRemoved(
791     const uid_t &uid, const std::string &bundleName, const uint32_t &appIndex)
792 {
793     RemoveAssociatedDataCacheByUid(uid);
794     auto dataStoragePtr = GetDataStorage(uid);
795     if (dataStoragePtr == nullptr) {
796         ACCOUNT_LOGE("dataStoragePtr is nullptr");
797         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
798     }
799 #ifdef DISTRIBUTED_FEATURE_ENABLED
800     auto dataStorageSyncPtr = GetDataStorage(uid, true);
801     if (dataStorageSyncPtr == nullptr) {
802         ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
803         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
804     }
805 #endif // DISTRIBUTED_FEATURE_ENABLED
806     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
807     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
808     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(key, accounts);
809     if (result != ERR_OK) {
810         ACCOUNT_LOGE("failed to get accounts by owner, result %{public}d, bundleName = %{public}s",
811             result, bundleName.c_str());
812         return result;
813     }
814     AppAccountInfo appAccountInfo;
815     for (auto account : accounts) {
816         appAccountInfo = *(std::static_pointer_cast<AppAccountInfo>(account.second));
817         std::set<std::string> authorizedApps;
818         appAccountInfo.GetAuthorizedApps(authorizedApps);
819         appAccountInfo.SetAppIndex(appIndex);
820         for (auto authorizedApp : authorizedApps) {
821             RemoveAuthorizedAccountFromDataStorage(authorizedApp, appAccountInfo, dataStoragePtr);
822 #ifdef DISTRIBUTED_FEATURE_ENABLED
823             if (NeedSyncDataStorage(appAccountInfo) == true) {
824                 RemoveAuthorizedAccountFromDataStorage(authorizedApp, appAccountInfo, dataStorageSyncPtr);
825             }
826 #endif // DISTRIBUTED_FEATURE_ENABLED
827         }
828         dataStoragePtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
829 #ifdef DISTRIBUTED_FEATURE_ENABLED
830         if (NeedSyncDataStorage(appAccountInfo) == true) {
831             dataStorageSyncPtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
832         }
833 #else  // DISTRIBUTED_FEATURE_ENABLED
834         ACCOUNT_LOGI("No distributed feature!");
835 #endif // DISTRIBUTED_FEATURE_ENABLED
836     }
837     return ERR_OK;
838 }
839 
OnUserRemoved(int32_t userId)840 ErrCode AppAccountControlManager::OnUserRemoved(int32_t userId)
841 {
842     std::string storeId = std::to_string(userId);
843     std::string syncStoreId = storeId + DATA_STORAGE_SUFFIX;
844     std::lock_guard<std::mutex> lock(storePtrMutex_);
845     storePtrMap_.erase(storeId);
846     storePtrMap_.erase(syncStoreId);
847     return ERR_OK;
848 }
849 
RegisterApplicationStateObserver()850 bool AppAccountControlManager::RegisterApplicationStateObserver()
851 {
852     if (appStateObserver_ != nullptr) {
853         return false;
854     }
855     appStateObserver_ = new (std::nothrow) AppAccountAppStateObserver();
856     if (appStateObserver_ == nullptr) {
857         ACCOUNT_LOGE("failed to create AppAccountAppStateObserver instance");
858         return false;
859     }
860     sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
861     if (samgrClient == nullptr) {
862         ACCOUNT_LOGE("failed to system ability manager");
863         return false;
864     }
865     iAppMgr_ = iface_cast<AppExecFwk::IAppMgr>(samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID));
866     if (iAppMgr_ == nullptr) {
867         appStateObserver_ = nullptr;
868         ACCOUNT_LOGE("failed to get ability manager service");
869         return false;
870     }
871     int32_t result = iAppMgr_->RegisterApplicationStateObserver(appStateObserver_);
872     if (result != ERR_OK) {
873         return false;
874     }
875     return true;
876 }
877 
UnregisterApplicationStateObserver()878 void AppAccountControlManager::UnregisterApplicationStateObserver()
879 {
880     if (iAppMgr_) {
881         iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
882     }
883     iAppMgr_ = nullptr;
884     appStateObserver_ = nullptr;
885 }
886 
OnAbilityStateChanged(const AppExecFwk::AbilityStateData & abilityStateData)887 void AppAccountControlManager::OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData)
888 {
889     if (abilityStateData.abilityState != static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED)) {
890         return;
891     }
892     RemoveAssociatedDataCacheByUid(abilityStateData.uid);
893 }
894 
GetAllAccountsFromDataStorage(const std::string & owner,std::vector<AppAccountInfo> & appAccounts,const std::string & bundleName,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)895 ErrCode AppAccountControlManager::GetAllAccountsFromDataStorage(const std::string &owner,
896     std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName,
897     const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
898 {
899     appAccounts.clear();
900 
901     if (dataStoragePtr == nullptr) {
902         ACCOUNT_LOGE("dataStoragePtr is nullptr");
903         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
904     }
905 
906     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
907     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(owner, accounts);
908     if (result != ERR_OK) {
909         ACCOUNT_LOGE("failed to get accounts by owner, result = %{public}d, owner = %{public}s",
910             result, owner.c_str());
911         return result;
912     }
913 
914     std::transform(accounts.begin(), accounts.end(), std::back_inserter(appAccounts),
915         [](auto account) { return *(std::static_pointer_cast<AppAccountInfo>(account.second)); });
916 
917     return ERR_OK;
918 }
919 
GetAllAccessibleAccountsFromDataStorage(std::vector<AppAccountInfo> & appAccounts,const std::string & bundleName,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uint32_t & appIndex)920 ErrCode AppAccountControlManager::GetAllAccessibleAccountsFromDataStorage(
921     std::vector<AppAccountInfo> &appAccounts, const std::string &bundleName,
922     const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uint32_t &appIndex)
923 {
924     appAccounts.clear();
925 
926     if (dataStoragePtr == nullptr) {
927         ACCOUNT_LOGE("dataStoragePtr is nullptr");
928         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
929     }
930 
931     std::vector<std::string> accessibleAccounts;
932     ErrCode result = dataStoragePtr->GetAccessibleAccountsFromDataStorage(bundleName, accessibleAccounts);
933     if (result != ERR_OK) {
934         ACCOUNT_LOGE("failed to get accessible account from data storage, result = %{public}d.", result);
935         return result;
936     }
937 
938     for (auto account : accessibleAccounts) {
939         AppAccountInfo appAccountInfo;
940 
941         result = dataStoragePtr->GetAccountInfoById(account, appAccountInfo);
942         if (result != ERR_OK) {
943             ACCOUNT_LOGE("failed to get account info by id. result %{public}d.", result);
944             return ERR_APPACCOUNT_SERVICE_GET_ACCOUNT_INFO_BY_ID;
945         }
946 
947         appAccounts.emplace_back(appAccountInfo);
948     }
949 
950     std::vector<AppAccountInfo> currentAppAccounts;
951     std::string key = bundleName + Constants::HYPHEN + std::to_string(appIndex);
952     result = GetAllAccountsFromDataStorage(key, currentAppAccounts, bundleName, dataStoragePtr);
953     if (result != ERR_OK) {
954         ACCOUNT_LOGE("failed to get all accounts from data storage, result = %{public}d", result);
955         return result;
956     }
957 
958     std::transform(currentAppAccounts.begin(), currentAppAccounts.end(), std::back_inserter(appAccounts),
959         [](auto account) { return account; });
960 
961     return ERR_OK;
962 }
963 
GetDataStorageByUserId(int32_t userId,const bool & autoSync,DistributedKv::SecurityLevel securityLevel)964 std::shared_ptr<AppAccountDataStorage> AppAccountControlManager::GetDataStorageByUserId(
965     int32_t userId, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)
966 {
967     std::string storeId = std::to_string(userId);
968     if (autoSync == true) {
969         storeId = storeId + DATA_STORAGE_SUFFIX;
970     }
971     std::lock_guard<std::mutex> lock(storePtrMutex_);
972     auto it = storePtrMap_.find(storeId);
973     if (it != storePtrMap_.end()) {
974         return it->second;
975     }
976     AccountDataStorageOptions options;
977     options.autoSync = autoSync;
978     options.securityLevel = securityLevel;
979     auto storePtr = std::make_shared<AppAccountDataStorage>(storeId, options);
980     storePtrMap_.emplace(storeId, storePtr);
981     return storePtr;
982 }
983 
GetDataStorage(const uid_t & uid,const bool & autoSync,DistributedKv::SecurityLevel securityLevel)984 std::shared_ptr<AppAccountDataStorage> AppAccountControlManager::GetDataStorage(
985     const uid_t &uid, const bool &autoSync, DistributedKv::SecurityLevel securityLevel)
986 {
987     return GetDataStorageByUserId(uid / UID_TRANSFORM_DIVISOR, autoSync, securityLevel);
988 }
989 
NeedSyncDataStorage(const AppAccountInfo & appAccountInfo)990 bool AppAccountControlManager::NeedSyncDataStorage(const AppAccountInfo &appAccountInfo)
991 {
992     bool syncEnable = false;
993     appAccountInfo.GetSyncEnable(syncEnable);
994 
995     if (syncEnable == false) {
996         return false;
997     }
998     return true;
999 }
1000 
GetAccountInfoFromDataStorage(AppAccountInfo & appAccountInfo,std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)1001 ErrCode AppAccountControlManager::GetAccountInfoFromDataStorage(
1002     AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1003 {
1004     if (dataStoragePtr == nullptr) {
1005         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1006         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1007     }
1008 
1009     return dataStoragePtr->GetAccountInfoFromDataStorage(appAccountInfo);
1010 }
1011 
AddAccountInfoIntoDataStorage(AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1012 ErrCode AppAccountControlManager::AddAccountInfoIntoDataStorage(
1013     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1014 {
1015     if (dataStoragePtr == nullptr) {
1016         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1017         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1018     }
1019 
1020     std::string owner;
1021     appAccountInfo.GetOwner(owner);
1022 
1023     std::map<std::string, std::shared_ptr<IAccountInfo>> accounts;
1024     std::string key = owner + Constants::HYPHEN + std::to_string(appAccountInfo.GetAppIndex());
1025     ErrCode result = dataStoragePtr->LoadDataByLocalFuzzyQuery(key, accounts);
1026     if (result != ERR_OK) {
1027         ACCOUNT_LOGE("failed to get accounts by owner, result %{public}d, owner = %{public}s",
1028             result, owner.c_str());
1029         return result;
1030     }
1031 
1032     if (accounts.size() >= ACCOUNT_MAX_SIZE) {
1033         ACCOUNT_LOGE("account exceeds max size");
1034         return ERR_APPACCOUNT_SERVICE_ACCOUNT_MAX_SIZE;
1035     }
1036 
1037     result = dataStoragePtr->AddAccountInfoIntoDataStorage(appAccountInfo);
1038     if (result != ERR_OK) {
1039         ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
1040         return result;
1041     }
1042 
1043     // for sync data storage
1044 #ifdef DISTRIBUTED_FEATURE_ENABLED
1045     if (NeedSyncDataStorage(appAccountInfo) == true) {
1046         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1047         if (dataStorageSyncPtr == nullptr) {
1048             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1049             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1050         }
1051 
1052         result = dataStorageSyncPtr->AddAccountInfoIntoDataStorage(appAccountInfo);
1053         if (result != ERR_OK) {
1054             ACCOUNT_LOGE("failed to add account info into data storage, result %{public}d.", result);
1055             return result;
1056         }
1057     }
1058 #else  // DISTRIBUTED_FEATURE_ENABLED
1059     ACCOUNT_LOGI("No distributed feature!");
1060 #endif // DISTRIBUTED_FEATURE_ENABLED
1061 
1062     return ERR_OK;
1063 }
1064 
SaveAccountInfoIntoDataStorage(AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1065 ErrCode AppAccountControlManager::SaveAccountInfoIntoDataStorage(
1066     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1067 {
1068     if (dataStoragePtr == nullptr) {
1069         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1070         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1071     }
1072 
1073     ErrCode result = dataStoragePtr->SaveAccountInfoIntoDataStorage(appAccountInfo);
1074     if (result != ERR_OK) {
1075         ACCOUNT_LOGE("failed to save account info into data storage, result %{public}d.", result);
1076         return result;
1077     }
1078 
1079     // for sync data storage
1080 #ifdef DISTRIBUTED_FEATURE_ENABLED
1081     if (NeedSyncDataStorage(appAccountInfo) == true) {
1082         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1083         if (dataStorageSyncPtr == nullptr) {
1084             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1085             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1086         }
1087 
1088         std::string appAccountInfoFromDataStorage;
1089         result = dataStorageSyncPtr->GetValueFromKvStore(appAccountInfo.GetPrimeKey(), appAccountInfoFromDataStorage);
1090         if (result != ERR_OK) {
1091             ACCOUNT_LOGE("failed to get config by id from data storage, result %{public}d.", result);
1092 
1093             result = dataStorageSyncPtr->AddAccountInfo(appAccountInfo);
1094             if (result != ERR_OK) {
1095                 ACCOUNT_LOGE("failed to add account info, result = %{public}d", result);
1096                 return result;
1097             }
1098         } else {
1099             result = dataStorageSyncPtr->SaveAccountInfo(appAccountInfo);
1100             if (result != ERR_OK) {
1101                 ACCOUNT_LOGE("failed to save account info, result = %{public}d", result);
1102                 return result;
1103             }
1104         }
1105     }
1106 #else  // DISTRIBUTED_FEATURE_ENABLED
1107     ACCOUNT_LOGI("No distributed feature!");
1108 #endif // DISTRIBUTED_FEATURE_ENABLED
1109 
1110     return ERR_OK;
1111 }
1112 
DeleteAccountInfoFromDataStorage(AppAccountInfo & appAccountInfo,std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1113 ErrCode AppAccountControlManager::DeleteAccountInfoFromDataStorage(
1114     AppAccountInfo &appAccountInfo, std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1115 {
1116     if (dataStoragePtr == nullptr) {
1117         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1118         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1119     }
1120 
1121     ErrCode result = dataStoragePtr->GetAccountInfoFromDataStorage(appAccountInfo);
1122     if (result != ERR_OK) {
1123         ACCOUNT_LOGE("failed to get account info from data storage, result %{public}d.", result);
1124         return result;
1125     }
1126 
1127     result = dataStoragePtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1128     if (result != ERR_OK) {
1129         ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
1130         return result;
1131     }
1132 
1133     // for sync data storage
1134 #ifdef DISTRIBUTED_FEATURE_ENABLED
1135     if (NeedSyncDataStorage(appAccountInfo) == true) {
1136         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1137         if (dataStorageSyncPtr == nullptr) {
1138             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1139             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1140         }
1141 
1142         result = dataStorageSyncPtr->DeleteAccountInfoFromDataStorage(appAccountInfo);
1143         if (result != ERR_OK) {
1144             ACCOUNT_LOGE("failed to delete account info from data storage, result %{public}d.", result);
1145         }
1146     }
1147 #else  // DISTRIBUTED_FEATURE_ENABLED
1148     ACCOUNT_LOGI("No distributed feature!");
1149 #endif // DISTRIBUTED_FEATURE_ENABLED
1150     return ERR_OK;
1151 }
1152 
SaveAuthorizedAccount(const std::string & bundleName,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1153 ErrCode AppAccountControlManager::SaveAuthorizedAccount(const std::string &bundleName,
1154     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1155 {
1156     if (dataStoragePtr == nullptr) {
1157         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1158         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1159     }
1160 
1161     ErrCode result = SaveAuthorizedAccountIntoDataStorage(bundleName, appAccountInfo, dataStoragePtr);
1162     if (result != ERR_OK) {
1163         ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1164         return result;
1165     }
1166 
1167     // for sync data storage
1168 #ifdef DISTRIBUTED_FEATURE_ENABLED
1169     if (NeedSyncDataStorage(appAccountInfo) == true) {
1170         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1171         if (dataStorageSyncPtr == nullptr) {
1172             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1173             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1174         }
1175 
1176         result = SaveAuthorizedAccountIntoDataStorage(bundleName, appAccountInfo, dataStorageSyncPtr);
1177         if (result != ERR_OK) {
1178             ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1179             return result;
1180         }
1181     }
1182 #else  // DISTRIBUTED_FEATURE_ENABLED
1183     ACCOUNT_LOGI("No distributed feature!");
1184 #endif // DISTRIBUTED_FEATURE_ENABLED
1185 
1186     return ERR_OK;
1187 }
1188 
RemoveAuthorizedAccount(const std::string & bundleName,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr,const uid_t & uid)1189 ErrCode AppAccountControlManager::RemoveAuthorizedAccount(const std::string &bundleName,
1190     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr, const uid_t &uid)
1191 {
1192     if (dataStoragePtr == nullptr) {
1193         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1194         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1195     }
1196 
1197     ErrCode result = RemoveAuthorizedAccountFromDataStorage(bundleName, appAccountInfo, dataStoragePtr);
1198     if (result != ERR_OK) {
1199         ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1200         return result;
1201     }
1202 
1203     // for sync data storage
1204 #ifdef DISTRIBUTED_FEATURE_ENABLED
1205     if (NeedSyncDataStorage(appAccountInfo) == true) {
1206         auto dataStorageSyncPtr = GetDataStorage(uid, true);
1207         if (dataStorageSyncPtr == nullptr) {
1208             ACCOUNT_LOGE("dataStorageSyncPtr is nullptr");
1209             return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1210         }
1211 
1212         result = RemoveAuthorizedAccountFromDataStorage(bundleName, appAccountInfo, dataStorageSyncPtr);
1213         if (result != ERR_OK) {
1214             ACCOUNT_LOGE("failed to save authorized account, result %{public}d.", result);
1215             return result;
1216         }
1217     }
1218 #else  // DISTRIBUTED_FEATURE_ENABLED
1219     ACCOUNT_LOGI("No distributed feature!");
1220 #endif // DISTRIBUTED_FEATURE_ENABLED
1221 
1222     return ERR_OK;
1223 }
1224 
SaveAuthorizedAccountIntoDataStorage(const std::string & authorizedApp,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)1225 ErrCode AppAccountControlManager::SaveAuthorizedAccountIntoDataStorage(const std::string &authorizedApp,
1226     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1227 {
1228     if (dataStoragePtr == nullptr) {
1229         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1230         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1231     }
1232 
1233     std::string authorizedAccounts;
1234     ErrCode result = dataStoragePtr->GetValueFromKvStore(AUTHORIZED_ACCOUNTS,
1235         authorizedAccounts);
1236     if (result != ERR_OK) {
1237         ACCOUNT_LOGE("failed to get config by id from data storage, result %{public}d.", result);
1238     }
1239 
1240     std::vector<std::string> accessibleAccounts;
1241     auto jsonObject = dataStoragePtr->GetAccessibleAccountsFromAuthorizedAccounts(
1242         authorizedAccounts, authorizedApp, accessibleAccounts);
1243 
1244     auto accountId = appAccountInfo.GetPrimeKey();
1245 
1246     auto it = std::find(accessibleAccounts.begin(), accessibleAccounts.end(), accountId);
1247     if (it == accessibleAccounts.end()) {
1248         accessibleAccounts.emplace_back(accountId);
1249     }
1250 
1251     auto accessibleAccountArray = Json::array();
1252     std::transform(accessibleAccounts.begin(), accessibleAccounts.end(), std::back_inserter(accessibleAccountArray),
1253         [](auto account) { return account; });
1254 
1255     jsonObject[authorizedApp] = accessibleAccountArray;
1256     try {
1257         authorizedAccounts = jsonObject.dump();
1258     } catch (Json::type_error& err) {
1259         ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
1260         return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
1261     }
1262 
1263     result = dataStoragePtr->PutValueToKvStore(AUTHORIZED_ACCOUNTS, authorizedAccounts);
1264     if (result != ERR_OK) {
1265         ACCOUNT_LOGE("PutValueToKvStore failed! result %{public}d.", result);
1266     }
1267     return result;
1268 }
1269 
RemoveAuthorizedAccountFromDataStorage(const std::string & authorizedApp,AppAccountInfo & appAccountInfo,const std::shared_ptr<AppAccountDataStorage> & dataStoragePtr)1270 ErrCode AppAccountControlManager::RemoveAuthorizedAccountFromDataStorage(const std::string &authorizedApp,
1271     AppAccountInfo &appAccountInfo, const std::shared_ptr<AppAccountDataStorage> &dataStoragePtr)
1272 {
1273     if (dataStoragePtr == nullptr) {
1274         ACCOUNT_LOGE("dataStoragePtr is nullptr");
1275         return ERR_APPACCOUNT_SERVICE_DATA_STORAGE_PTR_IS_NULLPTR;
1276     }
1277 
1278     std::string authorizedAccounts;
1279     ErrCode result = dataStoragePtr->GetValueFromKvStore(AUTHORIZED_ACCOUNTS,
1280         authorizedAccounts);
1281     if (result != ERR_OK) {
1282         ACCOUNT_LOGE("failed to get config by id from data storage, result %{public}d.", result);
1283     }
1284 
1285     std::vector<std::string> accessibleAccounts;
1286     auto jsonObject = dataStoragePtr->GetAccessibleAccountsFromAuthorizedAccounts(
1287         authorizedAccounts, authorizedApp, accessibleAccounts);
1288 
1289     auto accountId = appAccountInfo.GetPrimeKey();
1290 
1291     auto it = std::find(accessibleAccounts.begin(), accessibleAccounts.end(), accountId);
1292     if (it != accessibleAccounts.end()) {
1293         accessibleAccounts.erase(it);
1294     }
1295 
1296     auto accessibleAccountArray = Json::array();
1297     std::transform(accessibleAccounts.begin(), accessibleAccounts.end(), std::back_inserter(accessibleAccountArray),
1298         [](auto account) { return account; });
1299 
1300     jsonObject[authorizedApp] = accessibleAccountArray;
1301     try {
1302         authorizedAccounts = jsonObject.dump();
1303     } catch (Json::type_error& err) {
1304         ACCOUNT_LOGE("failed to dump json object, reason: %{public}s", err.what());
1305         return ERR_ACCOUNT_COMMON_DUMP_JSON_ERROR;
1306     }
1307 
1308     result = dataStoragePtr->PutValueToKvStore(AUTHORIZED_ACCOUNTS, authorizedAccounts);
1309     if (result != ERR_OK) {
1310         ACCOUNT_LOGE("failed to save config info, result %{public}d.", result);
1311         return result;
1312     }
1313 
1314     return ERR_OK;
1315 }
1316 }  // namespace AccountSA
1317 }  // namespace OHOS
1318