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