1 /*
2  * Copyright (c) 2021-2024 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 #include "os_account_control_file_manager.h"
16 #include <dirent.h>
17 #include <string>
18 #include <pthread.h>
19 #include <securec.h>
20 #include <sstream>
21 #include <sys/types.h>
22 #include <thread>
23 #include <unistd.h>
24 
25 #include "account_log_wrapper.h"
26 #include "account_hisysevent_adapter.h"
27 #ifdef HAS_CONFIG_POLICY_PART
28 #include "config_policy_utils.h"
29 #endif
30 #include "string_ex.h"
31 #include "os_account_constants.h"
32 #include "os_account_interface.h"
33 
34 namespace OHOS {
35 namespace AccountSA {
36 namespace {
37 const std::string DEFAULT_ACTIVATED_ACCOUNT_ID = "DefaultActivatedAccountID";
38 const std::string OS_ACCOUNT_STORE_ID = "os_account_info";
39 constexpr uint32_t ALG_COMMON_SIZE = 32;
40 #ifndef ACCOUNT_TEST
41 const std::string ACCOUNT_CFG_DIR_ROOT_PATH = "/data/service/el1/public/account/";
42 const std::string DEFAULT_OS_ACCOUNT_CONFIG_FILE = "/system/etc/account/os_account_config.json";
43 #else
44 const std::string ACCOUNT_CFG_DIR_ROOT_PATH = "/data/service/el1/public/account/test/";
45 const std::string DEFAULT_OS_ACCOUNT_CONFIG_FILE = ACCOUNT_CFG_DIR_ROOT_PATH + "os_account_config.json";
46 #endif // ACCOUNT_TEST
47 const std::string DISTRIBUTED_ACCOUNT_FILE_NAME = "/account.json";
48 #ifdef HAS_CONFIG_POLICY_PART
49 const std::string OS_ACCOUNT_CONFIG_FILE = "etc/os_account/os_account_config.json";
50 #endif // HAS_CONFIG_POLICY_PART
51 const std::string MAX_OS_ACCOUNT_NUM = "maxOsAccountNum";
52 const std::string MAX_LOGGED_IN_OS_ACCOUNT_NUM = "maxLoggedInOsAccountNum";
53 }
54 
GetValidAccountID(const std::string & dirName,std::int32_t & accountID)55 bool GetValidAccountID(const std::string& dirName, std::int32_t& accountID)
56 {
57     // check length first
58     if (dirName.empty() || dirName.size() > Constants::MAX_USER_ID_LENGTH) {
59         return false;
60     }
61 
62     auto iter = std::any_of(dirName.begin(), dirName.end(),
63         [dirName](char c) {
64             return (c < '0' || c > '9');
65         });
66     if (iter) {
67         return false;
68     }
69 
70     // convert to osaccount id
71     std::stringstream sstream;
72     sstream << dirName;
73     sstream >> accountID;
74     return (accountID >= Constants::ADMIN_LOCAL_ID && accountID <= Constants::MAX_USER_ID);
75 }
76 
GetOsAccountConfig(OsAccountConfig & config)77 ErrCode OsAccountControlFileManager::GetOsAccountConfig(OsAccountConfig &config)
78 {
79     std::string cfgPath = DEFAULT_OS_ACCOUNT_CONFIG_FILE;
80 #ifdef HAS_CONFIG_POLICY_PART
81     CfgFiles *cfgFiles = GetCfgFiles(OS_ACCOUNT_CONFIG_FILE.c_str());
82     if (cfgFiles != nullptr) {
83         if (cfgFiles->paths[0] != nullptr) {
84             cfgPath = cfgFiles->paths[0];
85         }
86         FreeCfgFiles(cfgFiles);
87     }
88 #endif
89     std::string configStr;
90     ErrCode errCode = accountFileOperator_->GetFileContentByPath(cfgPath, configStr);
91     if (errCode != ERR_OK) {
92         ACCOUNT_LOGE("get content from file %{public}s failed!", cfgPath.c_str());
93         return errCode;
94     }
95     Json configJson = Json::parse(configStr, nullptr, false);
96     if (configJson.is_discarded()) {
97         ACCOUNT_LOGE("parse os account info json data failed");
98         return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
99     }
100     auto jsonEnd = configJson.end();
101     int32_t maxOsAccountNum = -1;
102     OHOS::AccountSA::GetDataByType<int32_t>(configJson, jsonEnd, MAX_OS_ACCOUNT_NUM,
103         maxOsAccountNum, OHOS::AccountSA::JsonType::NUMBER);
104     if (maxOsAccountNum > 0) {
105         config.maxOsAccountNum = static_cast<uint32_t>(maxOsAccountNum);
106     }
107     OHOS::AccountSA::GetDataByType<int32_t>(configJson, jsonEnd, MAX_LOGGED_IN_OS_ACCOUNT_NUM,
108         config.maxLoggedInOsAccountNum, OHOS::AccountSA::JsonType::NUMBER);
109     if (config.maxLoggedInOsAccountNum > config.maxOsAccountNum) {
110         config.maxLoggedInOsAccountNum = config.maxOsAccountNum;
111     }
112     return ERR_OK;
113 }
114 
RecoverAccountData(const std::string & fileName,const int32_t id)115 bool OsAccountControlFileManager::RecoverAccountData(const std::string &fileName, const int32_t id)
116 {
117 #ifdef HAS_KV_STORE_PART
118     std::string recoverDataStr;
119     if (fileName == Constants::ACCOUNT_LIST_FILE_JSON_PATH) {
120         Json accountListJson;
121         osAccountDataBaseOperator_->GetAccountListFromStoreID(OS_ACCOUNT_STORE_ID, accountListJson);
122         recoverDataStr = accountListJson.dump();
123     } else if (id >= Constants::START_USER_ID) {
124         OsAccountInfo osAccountInfo;
125         if (GetOsAccountFromDatabase(OS_ACCOUNT_STORE_ID, id, osAccountInfo) != ERR_OK) {
126             ACCOUNT_LOGW("get recover file data failed");
127             return false;
128         }
129         recoverDataStr = osAccountInfo.ToString();
130     } else {
131         ACCOUNT_LOGW("get recover file data failed");
132         return false;
133     }
134     if (recoverDataStr.empty()) {
135         ACCOUNT_LOGW("get recover file data failed");
136         return false;
137     }
138     // recover data
139     ErrCode result = accountFileOperator_->InputFileByPathAndContent(fileName, recoverDataStr);
140     if (result != ERR_OK) {
141         ACCOUNT_LOGE("recover local file data failed, err = %{public}d", result);
142         return false;
143     }
144     // update local digest
145     if (accountFileWatcherMgr_.AddAccountInfoDigest(recoverDataStr, fileName) != ERR_OK) {
146         ACCOUNT_LOGE("failed to update local digest");
147         return false;
148     }
149 #endif
150     return true;
151 }
152 
DealWithFileModifyEvent(const std::string & fileName,const int32_t id)153 bool OsAccountControlFileManager::DealWithFileModifyEvent(const std::string &fileName, const int32_t id)
154 {
155     ACCOUNT_LOGI("enter");
156     {
157         std::unique_lock<std::shared_timed_mutex> lock(accountFileOperator_->fileLock_);
158         if (accountFileOperator_->GetValidModifyFileOperationFlag(fileName)) {
159             ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
160             accountFileOperator_->SetValidModifyFileOperationFlag(fileName, false);
161             return true;
162         }
163     }
164     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
165     std::string fileInfoStr;
166     if (accountFileOperator_->GetFileContentByPath(fileName, fileInfoStr) != ERR_OK) {
167         ACCOUNT_LOGE("get content from file %{public}s failed!", fileName.c_str());
168         return false;
169     }
170     uint8_t localDigestData[ALG_COMMON_SIZE] = {0};
171     accountFileWatcherMgr_.GetAccountInfoDigestFromFile(fileName, localDigestData, ALG_COMMON_SIZE);
172 #ifdef HAS_HUKS_PART
173     uint8_t newDigestData[ALG_COMMON_SIZE] = {0};
174     GenerateAccountInfoDigest(fileInfoStr, newDigestData, ALG_COMMON_SIZE);
175 
176     if (memcmp(localDigestData, newDigestData, ALG_COMMON_SIZE) == EOK) {
177         ACCOUNT_LOGD("No need to recover local file data.");
178         return true;
179     }
180 #endif // HAS_HUKS_PART
181     ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
182     ACCOUNT_LOGW("local file data has been changed");
183     return RecoverAccountData(fileName, id);
184 }
185 
DealWithFileDeleteEvent(const std::string & fileName,const int32_t id)186 bool OsAccountControlFileManager::DealWithFileDeleteEvent(const std::string &fileName, const int32_t id)
187 {
188     ACCOUNT_LOGI("enter");
189     {
190         std::unique_lock<std::shared_timed_mutex> lock(accountFileOperator_->fileLock_);
191         if (accountFileOperator_->GetValidDeleteFileOperationFlag(fileName)) {
192             ACCOUNT_LOGD("this is valid service operate, no need to deal with it.");
193             accountFileOperator_->SetValidDeleteFileOperationFlag(fileName, false);
194             accountFileWatcherMgr_.RemoveFileWatcher(id, fileName);
195             return true;
196         }
197     }
198     ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
199     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
200     if (!RecoverAccountData(fileName, id)) {
201         ACCOUNT_LOGE("recover account data failed.");
202     }
203     accountFileWatcherMgr_.AddFileWatcher(id, eventCallbackFunc_, fileName);
204     return true;
205 }
206 
DealWithFileMoveEvent(const std::string & fileName,const int32_t id)207 bool OsAccountControlFileManager::DealWithFileMoveEvent(const std::string &fileName, const int32_t id)
208 {
209     ACCOUNT_LOGI("enter");
210     // delete old file watcher
211     accountFileWatcherMgr_.RemoveFileWatcher(id, fileName);
212     ReportOsAccountDataTampered(id, fileName, "OS_ACCOUNT_INFO");
213     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
214     if (!RecoverAccountData(fileName, id)) {
215         ACCOUNT_LOGE("recover account data failed.");
216     }
217     accountFileWatcherMgr_.AddFileWatcher(id, eventCallbackFunc_, fileName);
218     return true;
219 }
220 
OsAccountControlFileManager()221 OsAccountControlFileManager::OsAccountControlFileManager()
222     : accountFileWatcherMgr_(AccountFileWatcherMgr::GetInstance())
223 {
224     accountFileOperator_ = accountFileWatcherMgr_.accountFileOperator_;
225 #ifdef HAS_KV_STORE_PART
226     osAccountDataBaseOperator_ = std::make_shared<OsAccountDatabaseOperator>();
227 #endif
228     osAccountFileOperator_ = std::make_shared<OsAccountFileOperator>();
229     osAccountPhotoOperator_ = std::make_shared<OsAccountPhotoOperator>();
230     eventCallbackFunc_ = [this](const std::string &fileName, int32_t id, uint32_t event) {
231         ACCOUNT_LOGI("inotify event = %{public}d, fileName = %{public}s", event, fileName.c_str());
232         switch (event) {
233             case IN_MODIFY: {
234                 return DealWithFileModifyEvent(fileName, id);
235             }
236             case IN_MOVE_SELF: {
237                 return DealWithFileMoveEvent(fileName, id);
238             }
239             case IN_DELETE_SELF: {
240                 return DealWithFileDeleteEvent(fileName, id);
241             }
242             default: {
243                 ACCOUNT_LOGW("get event invalid!");
244                 return false;
245             }
246         }
247     };
248 }
~OsAccountControlFileManager()249 OsAccountControlFileManager::~OsAccountControlFileManager()
250 {}
251 
Init()252 void OsAccountControlFileManager::Init()
253 {
254     osAccountFileOperator_->Init();
255     FileInit();
256     Json accountListJson;
257     ErrCode result = GetAccountListFromFile(accountListJson);
258     if (result != ERR_OK) {
259         return;
260     }
261     auto jsonEnd = accountListJson.end();
262     std::vector<std::string> accountIdList;
263     OHOS::AccountSA::GetDataByType<std::vector<std::string>>(
264         accountListJson, jsonEnd, Constants::ACCOUNT_LIST, accountIdList, OHOS::AccountSA::JsonType::ARRAY);
265     if (!accountIdList.empty()) {
266         InitFileWatcherInfo(accountIdList);
267     }
268     ACCOUNT_LOGI("OsAccountControlFileManager Init end");
269 }
270 
FileInit()271 void OsAccountControlFileManager::FileInit()
272 {
273     if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_LIST_FILE_JSON_PATH)) {
274         ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
275         RecoverAccountListJsonFile();
276     }
277     if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH)) {
278         ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account info digest file, create!");
279         RecoverAccountInfoDigestJsonFile();
280     }
281     // -1 is special refers to conmon account data file.
282     accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::ACCOUNT_LIST_FILE_JSON_PATH);
283     if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INDEX_JSON_PATH)) {
284         ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account index file, create!");
285         BuildAndSaveOsAccountIndexJsonFile();
286     }
287     accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::ACCOUNT_INDEX_JSON_PATH);
288     if (!accountFileOperator_->IsJsonFileReady(Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
289         ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
290         BuildAndSaveBaseOAConstraintsJsonFile();
291     }
292     accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH);
293     if (!accountFileOperator_->IsJsonFileReady(Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
294         ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
295         BuildAndSaveGlobalOAConstraintsJsonFile();
296     }
297     accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH);
298     if (!accountFileOperator_->IsJsonFileReady(Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH)) {
299         ACCOUNT_LOGI("OsAccountControlFileManager there is not have valid account list, create!");
300         BuildAndSaveSpecificOAConstraintsJsonFile();
301     }
302     accountFileWatcherMgr_.AddFileWatcher(-1, eventCallbackFunc_, Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH);
303 }
304 
InitFileWatcherInfo(std::vector<std::string> & accountIdList)305 void OsAccountControlFileManager::InitFileWatcherInfo(std::vector<std::string> &accountIdList)
306 {
307     for (std::string i : accountIdList) {
308         int32_t id = 0;
309         if (!StrToInt(i, id)) {
310             ACCOUNT_LOGE("Convert localId failed");
311             continue;
312         }
313         accountFileWatcherMgr_.AddFileWatcher(id, eventCallbackFunc_);
314     }
315 }
316 
BuildAndSaveAccountListJsonFile(const std::vector<std::string> & accounts)317 void OsAccountControlFileManager::BuildAndSaveAccountListJsonFile(const std::vector<std::string>& accounts)
318 {
319     ACCOUNT_LOGD("enter.");
320     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
321     Json accountList = Json {
322         {Constants::ACCOUNT_LIST, accounts},
323         {Constants::COUNT_ACCOUNT_NUM, accounts.size()},
324         {DEFAULT_ACTIVATED_ACCOUNT_ID, Constants::START_USER_ID},
325         {Constants::MAX_ALLOW_CREATE_ACCOUNT_ID, Constants::MAX_USER_ID},
326         {Constants::SERIAL_NUMBER_NUM, Constants::SERIAL_NUMBER_NUM_START},
327         {Constants::IS_SERIAL_NUMBER_FULL, Constants::IS_SERIAL_NUMBER_FULL_INIT_VALUE},
328         {Constants::NEXT_LOCAL_ID, Constants::START_USER_ID + 1},
329     };
330     SaveAccountListToFile(accountList);
331 }
332 
BuildAndSaveBaseOAConstraintsJsonFile()333 void OsAccountControlFileManager::BuildAndSaveBaseOAConstraintsJsonFile()
334 {
335     ACCOUNT_LOGI("enter.");
336     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
337     std::vector<std::string> baseOAConstraints;
338     if (osAccountFileOperator_->GetConstraintsByType(OsAccountType::ADMIN, baseOAConstraints) != ERR_OK) {
339         ACCOUNT_LOGE("get %{public}d base os account constraints failed.", Constants::START_USER_ID);
340         return;
341     }
342     Json baseOsAccountConstraints = Json {
343         {Constants::START_USER_STRING_ID, baseOAConstraints}
344     };
345     SaveBaseOAConstraintsToFile(baseOsAccountConstraints);
346 }
347 
BuildAndSaveGlobalOAConstraintsJsonFile()348 void OsAccountControlFileManager::BuildAndSaveGlobalOAConstraintsJsonFile()
349 {
350     ACCOUNT_LOGI("enter.");
351     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
352     Json globalOsAccountConstraints = Json {
353         {Constants::DEVICE_OWNER_ID, -1},
354         {Constants::ALL_GLOBAL_CONSTRAINTS, {}}
355     };
356     SaveGlobalOAConstraintsToFile(globalOsAccountConstraints);
357 }
358 
BuildAndSaveSpecificOAConstraintsJsonFile()359 void OsAccountControlFileManager::BuildAndSaveSpecificOAConstraintsJsonFile()
360 {
361     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
362     Json OsAccountConstraintsList = Json {
363         {Constants::ALL_SPECIFIC_CONSTRAINTS, {}},
364     };
365     Json specificOsAccountConstraints = Json {
366         {Constants::START_USER_STRING_ID, OsAccountConstraintsList},
367     };
368     SaveSpecificOAConstraintsToFile(specificOsAccountConstraints);
369 }
370 
BuildAndSaveOsAccountIndexJsonFile()371 void OsAccountControlFileManager::BuildAndSaveOsAccountIndexJsonFile()
372 {
373     std::string accountIndex;
374     ErrCode result = GetAccountIndexInfo(accountIndex);
375     if (result != ERR_OK) {
376         ACCOUNT_LOGE("get account index info error code %{public}d.", result);
377         return;
378     }
379     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
380     result = accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INDEX_JSON_PATH, accountIndex);
381     if (result != ERR_OK) {
382         ACCOUNT_LOGE("failed to input account index info to file!");
383     }
384     return;
385 }
386 
RecoverAccountInfoDigestJsonFile()387 void OsAccountControlFileManager::RecoverAccountInfoDigestJsonFile()
388 {
389     std::string listInfoStr;
390     accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_LIST_FILE_JSON_PATH, listInfoStr);
391 #ifdef HAS_HUKS_PART
392     uint8_t digestOutData[ALG_COMMON_SIZE] = {0};
393     GenerateAccountInfoDigest(listInfoStr, digestOutData, ALG_COMMON_SIZE);
394     Json digestJsonData = Json {
395         {Constants::ACCOUNT_LIST_FILE_JSON_PATH, digestOutData},
396     };
397     accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INFO_DIGEST_FILE_PATH, digestJsonData.dump());
398 #endif // HAS_HUKS_PART
399     return;
400 }
401 
RecoverAccountListJsonFile()402 void OsAccountControlFileManager::RecoverAccountListJsonFile()
403 {
404     // get account list
405     std::vector<std::string> accounts;
406     DIR* rootDir = opendir(Constants::USER_INFO_BASE.c_str());
407     if (rootDir == nullptr) {
408         accounts.push_back(std::to_string(Constants::START_USER_ID));  // account 100 always exists
409         BuildAndSaveAccountListJsonFile(accounts);
410         ACCOUNT_LOGE("cannot open dir %{public}s, err %{public}d.", Constants::USER_INFO_BASE.c_str(), errno);
411         return;
412     }
413 
414     struct dirent* curDir = nullptr;
415     while ((curDir = readdir(rootDir)) != nullptr) {
416         std::string curDirName(curDir->d_name);
417         if (curDirName == "." || curDirName == ".." || curDir->d_type != DT_DIR) {
418             continue;
419         }
420 
421         // get and check os account id
422         std::int32_t accountID = Constants::INVALID_OS_ACCOUNT_ID;
423         if (!GetValidAccountID(curDirName, accountID)) {
424             ACCOUNT_LOGE("invalid account id %{public}s detected in %{public}s.", curDirName.c_str(),
425                 Constants::USER_INFO_BASE.c_str());
426             continue;
427         }
428 
429         // check repeat
430         bool sameAccountID = false;
431         std::string curAccountIDStr = std::to_string(accountID);
432         for (size_t i = 0; i < accounts.size(); ++i) {
433             if (accounts[i] == curAccountIDStr) {
434                 ACCOUNT_LOGE("repeated account id %{public}s detected in %{public}s.", curAccountIDStr.c_str(),
435                     Constants::USER_INFO_BASE.c_str());
436                 sameAccountID = true;
437                 break;
438             }
439         }
440 
441         if (!sameAccountID && accountID >= Constants::START_USER_ID) {
442             accounts.push_back(curAccountIDStr);
443         }
444     }
445 
446     (void)closedir(rootDir);
447     BuildAndSaveAccountListJsonFile(accounts);
448 }
449 
GetOsAccountIdList(std::vector<int32_t> & idList)450 ErrCode OsAccountControlFileManager::GetOsAccountIdList(std::vector<int32_t> &idList)
451 {
452     idList.clear();
453     Json accountListJson;
454     ErrCode errCode = GetAccountListFromFile(accountListJson);
455     if (errCode != ERR_OK) {
456         return errCode;
457     }
458     std::vector<std::string> idStrList;
459     OHOS::AccountSA::GetDataByType<std::vector<std::string>>(accountListJson, accountListJson.end(),
460         Constants::ACCOUNT_LIST, idStrList, OHOS::AccountSA::JsonType::ARRAY);
461     for (const auto &idStr : idStrList) {
462         int32_t id = 0;
463         if (!StrToInt(idStr, id)) {
464             ACCOUNT_LOGE("Convert localId failed");
465             continue;
466         }
467         idList.emplace_back(id);
468     }
469     return errCode;
470 }
471 
GetOsAccountList(std::vector<OsAccountInfo> & osAccountList)472 ErrCode OsAccountControlFileManager::GetOsAccountList(std::vector<OsAccountInfo> &osAccountList)
473 {
474     osAccountList.clear();
475     Json accountListJson;
476     ErrCode result = GetAccountListFromFile(accountListJson);
477     if (result != ERR_OK) {
478         ACCOUNT_LOGE("GetAccountListFromFile failed!");
479 #ifdef HAS_KV_STORE_PART
480         if (osAccountDataBaseOperator_->GetAccountListFromStoreID("", accountListJson) == ERR_OK) {
481             SaveAccountListToFile(accountListJson);
482         } else {
483             return result;
484         }
485 #else
486         return result;
487 #endif
488     }
489     const auto &jsonObjectEnd = accountListJson.end();
490     std::vector<std::string> idList;
491     OHOS::AccountSA::GetDataByType<std::vector<std::string>>(
492         accountListJson, jsonObjectEnd, Constants::ACCOUNT_LIST, idList, OHOS::AccountSA::JsonType::ARRAY);
493 
494     for (const auto& it : idList) {
495         OsAccountInfo osAccountInfo;
496         int32_t id = 0;
497         if (!StrToInt(it, id)) {
498             ACCOUNT_LOGE("Convert localId failed");
499             continue;
500         }
501         if (GetOsAccountInfoById(id, osAccountInfo) == ERR_OK) {
502             if (osAccountInfo.GetPhoto() != "") {
503                 std::string photo = osAccountInfo.GetPhoto();
504                 GetPhotoById(osAccountInfo.GetLocalId(), photo);
505                 osAccountInfo.SetPhoto(photo);
506             }
507             osAccountList.push_back(osAccountInfo);
508         }
509     }
510     return ERR_OK;
511 }
512 
GetOsAccountInfoById(const int id,OsAccountInfo & osAccountInfo)513 ErrCode OsAccountControlFileManager::GetOsAccountInfoById(const int id, OsAccountInfo &osAccountInfo)
514 {
515     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) +
516                        Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
517     if (!accountFileOperator_->IsExistFile(path)) {
518         ACCOUNT_LOGE("file %{public}s does not exist err", path.c_str());
519         if (GetOsAccountFromDatabase("", id, osAccountInfo) == ERR_OK) {
520             InsertOsAccount(osAccountInfo);
521             return ERR_OK;
522         }
523         return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
524     }
525     std::string accountInfoStr;
526     if (accountFileOperator_->GetFileContentByPath(path, accountInfoStr) != ERR_OK) {
527         ACCOUNT_LOGE("get content from file %{public}s failed!", path.c_str());
528         return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
529     }
530     Json osAccountInfoJson = Json::parse(accountInfoStr, nullptr, false);
531     if (osAccountInfoJson.is_discarded() || !osAccountInfo.FromJson(osAccountInfoJson)) {
532         ACCOUNT_LOGE("parse os account info json for %{public}d failed", id);
533         if (GetOsAccountFromDatabase("", id, osAccountInfo) != ERR_OK) {
534             ACCOUNT_LOGE("GetOsAccountFromDatabase failed id=%{public}d", id);
535             return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
536         }
537     }
538     return ERR_OK;
539 }
540 
GetConstraintsByType(const OsAccountType type,std::vector<std::string> & constraints)541 ErrCode OsAccountControlFileManager::GetConstraintsByType(
542     const OsAccountType type, std::vector<std::string> &constraints)
543 {
544     int typeInit = static_cast<int>(type);
545     return osAccountFileOperator_->GetConstraintsByType(typeInit, constraints);
546 }
547 
UpdateBaseOAConstraints(const std::string & idStr,const std::vector<std::string> & ConstraintStr,bool isAdd)548 ErrCode OsAccountControlFileManager::UpdateBaseOAConstraints(const std::string& idStr,
549     const std::vector<std::string>& ConstraintStr, bool isAdd)
550 {
551     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
552     Json baseOAConstraintsJson;
553     ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson);
554     if (result != ERR_OK) {
555         ACCOUNT_LOGE("get baseOAConstraints from json file failed!");
556         return result;
557     }
558 
559     if (baseOAConstraintsJson.find(idStr) == baseOAConstraintsJson.end()) {
560         if (!isAdd) {
561             return ERR_OK;
562         }
563         baseOAConstraintsJson.emplace(idStr, ConstraintStr);
564     } else {
565         std::vector<std::string> baseOAConstraints;
566         auto jsonEnd = baseOAConstraintsJson.end();
567         OHOS::AccountSA::GetDataByType<std::vector<std::string>>(
568             baseOAConstraintsJson, jsonEnd, idStr, baseOAConstraints, OHOS::AccountSA::JsonType::ARRAY);
569         for (auto it = ConstraintStr.begin(); it != ConstraintStr.end(); it++) {
570             if (!isAdd) {
571                 baseOAConstraints.erase(std::remove(baseOAConstraints.begin(), baseOAConstraints.end(), *it),
572                     baseOAConstraints.end());
573                 continue;
574             }
575             if (std::find(baseOAConstraints.begin(), baseOAConstraints.end(), *it) == baseOAConstraints.end()) {
576                 baseOAConstraints.emplace_back(*it);
577             }
578         }
579         baseOAConstraintsJson[idStr] = baseOAConstraints;
580     }
581     return SaveBaseOAConstraintsToFile(baseOAConstraintsJson);
582 }
583 
UpdateGlobalOAConstraints(const std::string & idStr,const std::vector<std::string> & ConstraintStr,bool isAdd)584 ErrCode OsAccountControlFileManager::UpdateGlobalOAConstraints(
585     const std::string& idStr, const std::vector<std::string>& ConstraintStr, bool isAdd)
586 {
587     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
588     Json globalOAConstraintsJson;
589     ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
590     if (result != ERR_OK) {
591         ACCOUNT_LOGE("get globalOAConstraints from file failed!");
592         return result;
593     }
594     GlobalConstraintsDataOperate(idStr, ConstraintStr, isAdd, globalOAConstraintsJson);
595     return SaveGlobalOAConstraintsToFile(globalOAConstraintsJson);
596 }
597 
GlobalConstraintsDataOperate(const std::string & idStr,const std::vector<std::string> & ConstraintStr,bool isAdd,Json & globalOAConstraintsJson)598 void OsAccountControlFileManager::GlobalConstraintsDataOperate(const std::string& idStr,
599     const std::vector<std::string>& ConstraintStr, bool isAdd, Json &globalOAConstraintsJson)
600 {
601     std::vector<std::string> globalOAConstraintsList;
602     OHOS::AccountSA::GetDataByType<std::vector<std::string>>(globalOAConstraintsJson, globalOAConstraintsJson.end(),
603         Constants::ALL_GLOBAL_CONSTRAINTS, globalOAConstraintsList, OHOS::AccountSA::JsonType::ARRAY);
604     std::vector<std::string> waitForErase;
605     for (auto it = ConstraintStr.begin(); it != ConstraintStr.end(); it++) {
606         if (!isAdd) {
607             if (std::find(globalOAConstraintsList.begin(),
608             globalOAConstraintsList.end(), *it) == globalOAConstraintsList.end()) {
609                 continue;
610             }
611             std::vector<std::string> constraintSourceList;
612             OHOS::AccountSA::GetDataByType<std::vector<std::string>>(globalOAConstraintsJson,
613                 globalOAConstraintsJson.end(), *it, constraintSourceList, OHOS::AccountSA::JsonType::ARRAY);
614             constraintSourceList.erase(std::remove(constraintSourceList.begin(), constraintSourceList.end(), idStr),
615                 constraintSourceList.end());
616             if (constraintSourceList.size() == 0) {
617                 globalOAConstraintsList.erase(std::remove(globalOAConstraintsList.begin(),
618                     globalOAConstraintsList.end(), *it), globalOAConstraintsList.end());
619                 globalOAConstraintsJson[Constants::ALL_GLOBAL_CONSTRAINTS] = globalOAConstraintsList;
620                 waitForErase.push_back(*it);
621             } else {
622                 globalOAConstraintsJson[*it] = constraintSourceList;
623             }
624             continue;
625         }
626         if (std::find(globalOAConstraintsList.begin(),
627             globalOAConstraintsList.end(), *it) != globalOAConstraintsList.end()) {
628             std::vector<std::string> constraintSourceList;
629             OHOS::AccountSA::GetDataByType<std::vector<std::string>>(globalOAConstraintsJson,
630                 globalOAConstraintsJson.end(), *it, constraintSourceList, OHOS::AccountSA::JsonType::ARRAY);
631             if (std::find(constraintSourceList.begin(),
632                 constraintSourceList.end(), idStr) == constraintSourceList.end()) {
633                 constraintSourceList.emplace_back(idStr);
634                 globalOAConstraintsJson[*it] = constraintSourceList;
635             }
636             continue;
637         }
638         std::vector<std::string> constraintSourceList;
639         constraintSourceList.emplace_back(idStr);
640         globalOAConstraintsList.emplace_back(*it);
641         globalOAConstraintsJson.emplace(*it, constraintSourceList);
642         globalOAConstraintsJson[Constants::ALL_GLOBAL_CONSTRAINTS] = globalOAConstraintsList;
643     }
644     for (auto keyStr : waitForErase) {
645         globalOAConstraintsJson.erase(keyStr);
646     }
647 }
648 
UpdateSpecificOAConstraints(const std::string & idStr,const std::string & targetIdStr,const std::vector<std::string> & ConstraintStr,bool isAdd)649 ErrCode OsAccountControlFileManager::UpdateSpecificOAConstraints(
650     const std::string& idStr, const std::string& targetIdStr, const std::vector<std::string>& ConstraintStr, bool isAdd)
651 {
652     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
653     Json specificOAConstraintsJson;
654     ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson);
655     if (result != ERR_OK) {
656         ACCOUNT_LOGE("get specificOAConstraints from file failed!");
657         return result;
658     }
659     if (specificOAConstraintsJson.find(targetIdStr) == specificOAConstraintsJson.end()) {
660         if (!isAdd) {
661             return ERR_OK;
662         }
663         Json osAccountConstraintsList = Json {
664             {Constants::ALL_SPECIFIC_CONSTRAINTS, {}},
665         };
666         specificOAConstraintsJson.emplace(targetIdStr, osAccountConstraintsList);
667     }
668     Json userPrivateConstraintsDataJson = specificOAConstraintsJson[targetIdStr];
669     SpecificConstraintsDataOperate(idStr, targetIdStr, ConstraintStr, isAdd, userPrivateConstraintsDataJson);
670     specificOAConstraintsJson[targetIdStr] = userPrivateConstraintsDataJson;
671     return SaveSpecificOAConstraintsToFile(specificOAConstraintsJson);
672 }
673 
SpecificConstraintsDataOperate(const std::string & idStr,const std::string & targetIdStr,const std::vector<std::string> & ConstraintStr,bool isAdd,Json & userPrivateConstraintsDataJson)674 void OsAccountControlFileManager::SpecificConstraintsDataOperate(
675     const std::string& idStr, const std::string& targetIdStr, const std::vector<std::string>& ConstraintStr,
676     bool isAdd, Json& userPrivateConstraintsDataJson)
677 {
678     std::vector<std::string> specificOAConstraintsList;
679     OHOS::AccountSA::GetDataByType<std::vector<std::string>>(userPrivateConstraintsDataJson,
680         userPrivateConstraintsDataJson.end(), Constants::ALL_SPECIFIC_CONSTRAINTS,
681         specificOAConstraintsList, OHOS::AccountSA::JsonType::ARRAY);
682     std::vector<std::string> waitForErase;
683     for (auto it = ConstraintStr.begin(); it != ConstraintStr.end(); it++) {
684         if (!isAdd) {
685             if (userPrivateConstraintsDataJson.find(*it) == userPrivateConstraintsDataJson.end()) {
686                 continue;
687             }
688             std::vector<std::string> constraintSourceList;
689             OHOS::AccountSA::GetDataByType<std::vector<std::string>>(userPrivateConstraintsDataJson,
690                 userPrivateConstraintsDataJson.end(), *it, constraintSourceList, OHOS::AccountSA::JsonType::ARRAY);
691             constraintSourceList.erase(std::remove(constraintSourceList.begin(), constraintSourceList.end(), idStr),
692                 constraintSourceList.end());
693             if (constraintSourceList.size() == 0) {
694                 specificOAConstraintsList.erase(std::remove(specificOAConstraintsList.begin(),
695                     specificOAConstraintsList.end(), *it), specificOAConstraintsList.end());
696                 userPrivateConstraintsDataJson[Constants::ALL_SPECIFIC_CONSTRAINTS] = specificOAConstraintsList;
697                 waitForErase.push_back(*it);
698             } else {
699                 userPrivateConstraintsDataJson[*it] = constraintSourceList;
700             }
701             continue;
702         }
703         if (std::find(specificOAConstraintsList.begin(),
704             specificOAConstraintsList.end(), *it) != specificOAConstraintsList.end()) {
705             std::vector<std::string> constraintSourceList;
706             OHOS::AccountSA::GetDataByType<std::vector<std::string>>(userPrivateConstraintsDataJson,
707             userPrivateConstraintsDataJson.end(), *it, constraintSourceList, OHOS::AccountSA::JsonType::ARRAY);
708             if (std::find(constraintSourceList.begin(),
709                 constraintSourceList.end(), idStr) == constraintSourceList.end()) {
710                 constraintSourceList.emplace_back(idStr);
711                 userPrivateConstraintsDataJson[*it] = constraintSourceList;
712             }
713             continue;
714         }
715         std::vector<std::string> constraintSourceList;
716         constraintSourceList.emplace_back(idStr);
717         specificOAConstraintsList.emplace_back(*it);
718         userPrivateConstraintsDataJson.emplace(*it, constraintSourceList);
719         userPrivateConstraintsDataJson[Constants::ALL_SPECIFIC_CONSTRAINTS] = specificOAConstraintsList;
720     }
721     for (auto keyStr : waitForErase) {
722         userPrivateConstraintsDataJson.erase(keyStr);
723     }
724 }
725 
RemoveOAConstraintsInfo(const int32_t id)726 ErrCode OsAccountControlFileManager::RemoveOAConstraintsInfo(const int32_t id)
727 {
728     ErrCode errCode = RemoveOABaseConstraintsInfo(id);
729     if (errCode != ERR_OK) {
730         ACCOUNT_LOGE("remove os account %{public}d base constraints info failed!", id);
731         return errCode;
732     }
733     errCode = RemoveOAGlobalConstraintsInfo(id);
734     if (errCode != ERR_OK) {
735         ACCOUNT_LOGE("remove os account %{public}d global constraints info failed!", id);
736         return errCode;
737     }
738     errCode = RemoveOASpecificConstraintsInfo(id);
739     if (errCode != ERR_OK) {
740         ACCOUNT_LOGE("remove os account %{public}d specific constraints info failed!", id);
741         return errCode;
742     }
743     return ERR_OK;
744 }
745 
RemoveOABaseConstraintsInfo(const int32_t id)746 ErrCode OsAccountControlFileManager::RemoveOABaseConstraintsInfo(const int32_t id)
747 {
748     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
749     Json baseOAConstraintsJson;
750     ErrCode result = GetBaseOAConstraintsFromFile(baseOAConstraintsJson);
751     if (result != ERR_OK) {
752         ACCOUNT_LOGE("get baseOAConstraints from file failed!");
753         return result;
754     }
755     baseOAConstraintsJson.erase(std::to_string(id));
756     result = SaveBaseOAConstraintsToFile(baseOAConstraintsJson);
757     if (result != ERR_OK) {
758         ACCOUNT_LOGE("SaveBaseOAConstraintsToFile failed!");
759         return result;
760     }
761     return ERR_OK;
762 }
763 
RemoveOAGlobalConstraintsInfo(const int32_t id)764 ErrCode OsAccountControlFileManager::RemoveOAGlobalConstraintsInfo(const int32_t id)
765 {
766     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
767     Json globalOAConstraintsJson;
768     ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
769     if (result != ERR_OK) {
770         ACCOUNT_LOGE("get globalOAConstraints from file failed!");
771         return result;
772     }
773     std::vector<std::string> waitForErase;
774     for (auto it = globalOAConstraintsJson.begin(); it != globalOAConstraintsJson.end(); it++) {
775         if (it.key() != Constants::ALL_GLOBAL_CONSTRAINTS && it.key() != Constants::DEVICE_OWNER_ID) {
776             std::vector<std::string> sourceList;
777             OHOS::AccountSA::GetDataByType<std::vector<std::string>>(globalOAConstraintsJson,
778                 globalOAConstraintsJson.end(),
779                 it.key(),
780                 sourceList,
781                 OHOS::AccountSA::JsonType::ARRAY);
782             sourceList.erase(std::remove(sourceList.begin(), sourceList.end(), std::to_string(id)), sourceList.end());
783             if (sourceList.size() == 0) {
784                 std::vector<std::string> allGlobalConstraints;
785                 OHOS::AccountSA::GetDataByType<std::vector<std::string>>(globalOAConstraintsJson,
786                     globalOAConstraintsJson.end(),
787                     Constants::ALL_GLOBAL_CONSTRAINTS,
788                     allGlobalConstraints,
789                     OHOS::AccountSA::JsonType::ARRAY);
790                 allGlobalConstraints.erase(std::remove(allGlobalConstraints.begin(),
791                     allGlobalConstraints.end(), it.key()), allGlobalConstraints.end());
792                 globalOAConstraintsJson[Constants::ALL_GLOBAL_CONSTRAINTS] = allGlobalConstraints;
793                 waitForErase.push_back(it.key());
794             } else {
795                 globalOAConstraintsJson[it.key()] = sourceList;
796             }
797         }
798     }
799     for (auto keyStr : waitForErase) {
800         globalOAConstraintsJson.erase(keyStr);
801     }
802     return SaveGlobalOAConstraintsToFile(globalOAConstraintsJson);
803 }
804 
RemoveOASpecificConstraintsInfo(const int32_t id)805 ErrCode OsAccountControlFileManager::RemoveOASpecificConstraintsInfo(const int32_t id)
806 {
807     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
808     Json specificOAConstraintsJson;
809     ErrCode result = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson);
810     if (result != ERR_OK) {
811         ACCOUNT_LOGE("get specificOAConstraints from file failed!");
812         return result;
813     }
814     if (specificOAConstraintsJson.find(std::to_string(id)) != specificOAConstraintsJson.end()) {
815         specificOAConstraintsJson.erase(std::to_string(id));
816     }
817     for (auto it = specificOAConstraintsJson.begin(); it != specificOAConstraintsJson.end(); it++) {
818         std::vector<std::string> waitForErase;
819         Json userPrivateConstraintsJson;
820         OHOS::AccountSA::GetDataByType<Json>(specificOAConstraintsJson, specificOAConstraintsJson.end(),
821             it.key(), userPrivateConstraintsJson, OHOS::AccountSA::JsonType::OBJECT);
822         std::vector<std::string> allSpecificConstraints;
823         OHOS::AccountSA::GetDataByType<std::vector<std::string>>(userPrivateConstraintsJson,
824             userPrivateConstraintsJson.end(), Constants::ALL_SPECIFIC_CONSTRAINTS,
825             allSpecificConstraints, OHOS::AccountSA::JsonType::ARRAY);
826         if (allSpecificConstraints.size() == 0) {
827             continue;
828         }
829         for (auto item = userPrivateConstraintsJson.begin(); item != userPrivateConstraintsJson.end(); item++) {
830             if (item.key() == Constants::ALL_SPECIFIC_CONSTRAINTS) {
831                 continue;
832             }
833             std::vector<std::string> sourceList;
834             OHOS::AccountSA::GetDataByType<std::vector<std::string>>(userPrivateConstraintsJson,
835                 userPrivateConstraintsJson.end(), item.key(), sourceList, OHOS::AccountSA::JsonType::ARRAY);
836             sourceList.erase(std::remove(sourceList.begin(),
837                 sourceList.end(), std::to_string(id)), sourceList.end());
838             if (sourceList.size() == 0) {
839                 allSpecificConstraints.erase(std::remove(allSpecificConstraints.begin(),
840                     allSpecificConstraints.end(), item.key()), allSpecificConstraints.end());
841                 userPrivateConstraintsJson[Constants::ALL_SPECIFIC_CONSTRAINTS] = allSpecificConstraints;
842                 waitForErase.push_back(item.key());
843             } else {
844                 userPrivateConstraintsJson[item.key()] = sourceList;
845             }
846         }
847         for (auto keyStr : waitForErase) {
848             userPrivateConstraintsJson.erase(keyStr);
849         }
850         specificOAConstraintsJson[it.key()] = userPrivateConstraintsJson;
851     }
852     return SaveSpecificOAConstraintsToFile(specificOAConstraintsJson);
853 }
854 
UpdateAccountList(const std::string & idStr,bool isAdd)855 ErrCode OsAccountControlFileManager::UpdateAccountList(const std::string& idStr, bool isAdd)
856 {
857     Json accountListJson;
858     ErrCode result = GetAccountListFromFile(accountListJson);
859     if (result != ERR_OK) {
860         ACCOUNT_LOGE("get account list failed!");
861         return result;
862     }
863 
864     std::vector<std::string> accountIdList;
865     auto jsonEnd = accountListJson.end();
866     OHOS::AccountSA::GetDataByType<std::vector<std::string>>(
867         accountListJson, jsonEnd, Constants::ACCOUNT_LIST, accountIdList, OHOS::AccountSA::JsonType::ARRAY);
868 
869     if (isAdd) {
870         // check repeat
871         if (std::find(accountIdList.begin(), accountIdList.end(), idStr) != accountIdList.end()) {
872             return ERR_OK;  // already exist, no need to add.
873         }
874         accountIdList.emplace_back(idStr);
875     } else {
876         accountIdList.erase(std::remove(accountIdList.begin(), accountIdList.end(), idStr), accountIdList.end());
877     }
878     accountListJson[Constants::ACCOUNT_LIST] = accountIdList;
879     accountListJson[Constants::COUNT_ACCOUNT_NUM] = accountIdList.size();
880     return SaveAccountListToFileAndDataBase(accountListJson);
881 }
882 
UpdateAccountIndex(const OsAccountInfo & osAccountInfo,const bool isDelete)883 ErrCode OsAccountControlFileManager::UpdateAccountIndex(const OsAccountInfo &osAccountInfo, const bool isDelete)
884 {
885     // private type account not write index to index file, don't check name in ValidateOsAccount
886     if (osAccountInfo.GetType() == OsAccountType::PRIVATE) {
887         return ERR_OK;
888     }
889     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
890     Json accountIndexJson;
891     ErrCode result = GetAccountIndexFromFile(accountIndexJson);
892     if (result != ERR_OK) {
893         ACCOUNT_LOGE("get account index failed!");
894         return result;
895     }
896     std::string localIdStr = std::to_string(osAccountInfo.GetLocalId());
897     if (isDelete) {
898         accountIndexJson.erase(localIdStr);
899     } else {
900         Json accountBaseInfo;
901         accountBaseInfo[Constants::LOCAL_NAME] = osAccountInfo.GetLocalName();
902         accountBaseInfo[Constants::SHORT_NAME] = osAccountInfo.GetShortName();
903         accountIndexJson[localIdStr] = accountBaseInfo;
904     }
905     std::string lastAccountIndexStr = accountIndexJson.dump();
906     result = accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INDEX_JSON_PATH, lastAccountIndexStr);
907     if (result != ERR_OK) {
908         ACCOUNT_LOGE("failed to input account index info to file!");
909         return result;
910     }
911     accountFileWatcherMgr_.AddAccountInfoDigest(lastAccountIndexStr, Constants::ACCOUNT_INDEX_JSON_PATH);
912     return ERR_OK;
913 }
914 
SetNextLocalId(const int32_t & nextLocalId)915 ErrCode OsAccountControlFileManager::SetNextLocalId(const int32_t &nextLocalId)
916 {
917     std::lock_guard<std::mutex> lock(operatingIdMutex_);
918     Json accountListJson;
919     ErrCode result = GetAccountListFromFile(accountListJson);
920     if (result != ERR_OK) {
921         ACCOUNT_LOGE("SetNextLocalId get accountList error.");
922         return result;
923     }
924     int32_t nextLocalIdJson = -1;
925     auto jsonEnd = accountListJson.end();
926     if (!GetDataByType<std::int32_t>(accountListJson, jsonEnd,
927         Constants::NEXT_LOCAL_ID, nextLocalIdJson, JsonType::NUMBER)) {
928         ACCOUNT_LOGW("SetNextLocalId get next localId failed");
929         nextLocalIdJson = Constants::START_USER_ID + 1;
930     }
931     accountListJson[Constants::NEXT_LOCAL_ID] = std::max(nextLocalId, nextLocalIdJson);
932     result = SaveAccountListToFileAndDataBase(accountListJson);
933     if (result != ERR_OK) {
934         ACCOUNT_LOGE("SetNextLocalId save accountListJson error.");
935     }
936     return result;
937 }
938 
RemoveAccountIndex(const int32_t id)939 ErrCode OsAccountControlFileManager::RemoveAccountIndex(const int32_t id)
940 {
941     Json accountIndexJson;
942     ErrCode result = GetAccountIndexFromFile(accountIndexJson);
943     if (result != ERR_OK) {
944         ACCOUNT_LOGE("get account index failed!");
945         return result;
946     }
947     std::string localIdStr = std::to_string(id);
948     accountIndexJson.erase(localIdStr);
949     std::string lastAccountIndexStr = accountIndexJson.dump();
950     result = accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_INDEX_JSON_PATH, lastAccountIndexStr);
951     if (result != ERR_OK) {
952         ACCOUNT_LOGE("failed to input account index info to file!");
953         return result;
954     }
955     accountFileWatcherMgr_.AddAccountInfoDigest(lastAccountIndexStr, Constants::ACCOUNT_INDEX_JSON_PATH);
956     return ERR_OK;
957 }
958 
InsertOsAccount(OsAccountInfo & osAccountInfo)959 ErrCode OsAccountControlFileManager::InsertOsAccount(OsAccountInfo &osAccountInfo)
960 {
961     ACCOUNT_LOGI("enter");
962     if (osAccountInfo.GetLocalId() < Constants::ADMIN_LOCAL_ID) {
963         ACCOUNT_LOGE("error id %{public}d cannot insert", osAccountInfo.GetLocalId());
964         return ERR_OSACCOUNT_SERVICE_CONTROL_ID_CANNOT_CREATE_ERROR;
965     }
966 
967     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + osAccountInfo.GetPrimeKey() +
968                        Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
969     if (accountFileOperator_->IsExistFile(path) && accountFileOperator_->IsJsonFormat(path)) {
970         ACCOUNT_LOGE("Account %{public}d already exists", osAccountInfo.GetLocalId());
971         return ERR_OSACCOUNT_SERVICE_CONTROL_INSERT_FILE_EXISTS_ERROR;
972     }
973 
974     std::string accountInfoStr = osAccountInfo.ToString();
975     if (accountInfoStr.empty()) {
976         ACCOUNT_LOGE("os account info is empty! maybe some illegal characters caused exception!");
977         return ERR_OSACCOUNT_SERVICE_ACCOUNT_INFO_EMPTY_ERROR;
978     }
979     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
980     if (osAccountInfo.GetLocalId() >= Constants::START_USER_ID) {
981         ErrCode updateRet = UpdateAccountList(osAccountInfo.GetPrimeKey(), true);
982         if (updateRet != ERR_OK) {
983             ACCOUNT_LOGE("Update account list failed, errCode: %{public}d", updateRet);
984             return updateRet;
985         }
986     }
987     ErrCode result = accountFileOperator_->InputFileByPathAndContent(path, accountInfoStr);
988     if (result != ERR_OK) {
989         ACCOUNT_LOGE("InputFileByPathAndContent failed! path %{public}s.", path.c_str());
990         return result;
991     }
992 #ifdef HAS_KV_STORE_PART
993     osAccountDataBaseOperator_->InsertOsAccountIntoDataBase(osAccountInfo);
994 #endif
995 
996     if (osAccountInfo.GetLocalId() >= Constants::START_USER_ID) {
997         accountFileWatcherMgr_.AddAccountInfoDigest(accountInfoStr, path);
998         accountFileWatcherMgr_.AddFileWatcher(osAccountInfo.GetLocalId(), eventCallbackFunc_);
999     }
1000     ACCOUNT_LOGI("end");
1001     return ERR_OK;
1002 }
1003 
DelOsAccount(const int id)1004 ErrCode OsAccountControlFileManager::DelOsAccount(const int id)
1005 {
1006     ACCOUNT_LOGD("enter");
1007     if (id <= Constants::START_USER_ID || id > Constants::MAX_USER_ID) {
1008         ACCOUNT_LOGE("invalid input id %{public}d to delete!", id);
1009         return ERR_OSACCOUNT_SERVICE_CONTROL_CANNOT_DELETE_ID_ERROR;
1010     }
1011     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
1012     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id);
1013     ErrCode result = accountFileOperator_->DeleteDirOrFile(path);
1014     if (result != ERR_OK) {
1015         ACCOUNT_LOGE("DeleteDirOrFile failed! path %{public}s.", path.c_str());
1016         return result;
1017     }
1018 #ifdef HAS_KV_STORE_PART
1019     osAccountDataBaseOperator_->DelOsAccountFromDatabase(id);
1020 #endif
1021     path += Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
1022     accountFileWatcherMgr_.DeleteAccountInfoDigest(path);
1023     std::string distributedDataPath =
1024         Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) + DISTRIBUTED_ACCOUNT_FILE_NAME;
1025     accountFileWatcherMgr_.DeleteAccountInfoDigest(distributedDataPath);
1026     RemoveAccountIndex(id);
1027     return UpdateAccountList(std::to_string(id), false);
1028 }
1029 
1030 
UpdateOsAccount(OsAccountInfo & osAccountInfo)1031 ErrCode OsAccountControlFileManager::UpdateOsAccount(OsAccountInfo &osAccountInfo)
1032 {
1033     ACCOUNT_LOGD("start");
1034     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + osAccountInfo.GetPrimeKey() +
1035                        Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
1036     if (!accountFileOperator_->IsExistFile(path)) {
1037         ACCOUNT_LOGE("path %{public}s does not exist!", path.c_str());
1038         return ERR_OSACCOUNT_SERVICE_CONTROL_UPDATE_FILE_NOT_EXISTS_ERROR;
1039     }
1040 
1041     std::string accountInfoStr = osAccountInfo.ToString();
1042     if (accountInfoStr.empty()) {
1043         ACCOUNT_LOGE("account info str is empty!");
1044         return ERR_OSACCOUNT_SERVICE_ACCOUNT_INFO_EMPTY_ERROR;
1045     }
1046     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
1047     ErrCode result = accountFileOperator_->InputFileByPathAndContent(path, accountInfoStr);
1048     if (result != ERR_OK) {
1049         return result;
1050     }
1051 
1052 #if defined(HAS_KV_STORE_PART) && defined(DISTRIBUTED_FEATURE_ENABLED)
1053     // update in database
1054     if (osAccountInfo.GetLocalId() >= Constants::START_USER_ID) {
1055         osAccountDataBaseOperator_->UpdateOsAccountInDatabase(osAccountInfo);
1056     }
1057 #else  // DISTRIBUTED_FEATURE_ENABLED
1058     ACCOUNT_LOGI("No distributed feature!");
1059 #endif // DISTRIBUTED_FEATURE_ENABLED
1060 
1061     accountFileWatcherMgr_.AddAccountInfoDigest(accountInfoStr, path);
1062     ACCOUNT_LOGD("end");
1063     return ERR_OK;
1064 }
1065 
AccountExistsWithSerialNumber(const std::vector<OsAccountInfo> & osAccountInfos,int serialNumber)1066 bool AccountExistsWithSerialNumber(const std::vector<OsAccountInfo>& osAccountInfos, int serialNumber)
1067 {
1068     const auto targetSerialNumber = Constants::SERIAL_NUMBER_NUM_START_FOR_ADMIN * Constants::CARRY_NUM + serialNumber;
1069     return std::any_of(osAccountInfos.begin(), osAccountInfos.end(),
1070         [&targetSerialNumber](const OsAccountInfo& accountInfo) {
1071         return accountInfo.GetSerialNumber() == targetSerialNumber;
1072     });
1073 }
1074 
GetSerialNumber(int64_t & serialNumber)1075 ErrCode OsAccountControlFileManager::GetSerialNumber(int64_t &serialNumber)
1076 {
1077     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
1078     Json accountListJson;
1079     ErrCode result = GetAccountListFromFile(accountListJson);
1080     if (result != ERR_OK) {
1081         ACCOUNT_LOGE("GetSerialNumber get accountList error");
1082         return result;
1083     }
1084     OHOS::AccountSA::GetDataByType<int64_t>(accountListJson, accountListJson.end(), Constants::SERIAL_NUMBER_NUM,
1085         serialNumber, OHOS::AccountSA::JsonType::NUMBER);
1086     if (serialNumber == Constants::CARRY_NUM) {
1087         accountListJson[Constants::IS_SERIAL_NUMBER_FULL] = true;
1088         serialNumber = Constants::SERIAL_NUMBER_NUM_START;
1089     }
1090     bool isSerialNumberFull = false;
1091     OHOS::AccountSA::GetDataByType<bool>(accountListJson, accountListJson.end(), Constants::IS_SERIAL_NUMBER_FULL,
1092         isSerialNumberFull, OHOS::AccountSA::JsonType::BOOLEAN);
1093     if (isSerialNumberFull) {
1094         std::vector<OsAccountInfo> osAccountInfos;
1095         result = GetOsAccountList(osAccountInfos);
1096         if (result != ERR_OK) {
1097             ACCOUNT_LOGE("GetSerialNumber get accountList error");
1098             return result;
1099         }
1100         while (serialNumber < Constants::CARRY_NUM) {
1101             bool exists = false;
1102             exists = AccountExistsWithSerialNumber(osAccountInfos, serialNumber);
1103             if (!exists) {
1104                 break;
1105             }
1106             serialNumber++;
1107             serialNumber = (serialNumber == Constants::CARRY_NUM) ? Constants::SERIAL_NUMBER_NUM_START : serialNumber;
1108         }
1109     }
1110     accountListJson[Constants::SERIAL_NUMBER_NUM] = serialNumber + 1;
1111     result = SaveAccountListToFileAndDataBase(accountListJson);
1112     if (result != ERR_OK) {
1113         return result;
1114     }
1115     serialNumber = serialNumber + Constants::SERIAL_NUMBER_NUM_START_FOR_ADMIN * Constants::CARRY_NUM;
1116     return ERR_OK;
1117 }
1118 
GetNextLocalId(const std::vector<std::string> & accountIdList,int32_t startId)1119 int32_t OsAccountControlFileManager::GetNextLocalId(const std::vector<std::string> &accountIdList, int32_t startId)
1120 {
1121     do {
1122         if ((startId <= Constants::START_USER_ID) || (startId > Constants::MAX_USER_ID)) {
1123             startId = Constants::START_USER_ID + 1;
1124         }
1125         if (std::find(accountIdList.begin(), accountIdList.end(), std::to_string(startId)) ==
1126             accountIdList.end()) {
1127             break;
1128         }
1129         ++startId;
1130     } while (true);
1131     return startId;
1132 }
1133 
GetAllowCreateId(int & id)1134 ErrCode OsAccountControlFileManager::GetAllowCreateId(int &id)
1135 {
1136     std::lock_guard<std::mutex> lock(operatingIdMutex_);
1137     Json accountListJson;
1138     ErrCode result = GetAccountListFromFile(accountListJson);
1139     if (result != ERR_OK) {
1140         ACCOUNT_LOGE("GetAllowCreateId get accountList error.");
1141         return result;
1142     }
1143     auto jsonEnd = accountListJson.end();
1144     std::vector<std::string> accountIdList;
1145     int32_t nextLocalId = -1;
1146     if (!GetDataByType<std::vector<std::string>>(accountListJson, jsonEnd,
1147         Constants::ACCOUNT_LIST, accountIdList, JsonType::ARRAY)) {
1148         ACCOUNT_LOGE("GetAllowCreateId get accountIdList error");
1149         return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
1150     }
1151     if (!GetDataByType<std::int32_t>(accountListJson, jsonEnd,
1152         Constants::NEXT_LOCAL_ID, nextLocalId, JsonType::NUMBER)) {
1153         ACCOUNT_LOGW("Get next localId failed");
1154         int32_t lastLocalId = -1;
1155         if (!accountIdList.empty() && StrToInt(accountIdList[accountIdList.size() - 1], lastLocalId)) {
1156             nextLocalId = lastLocalId + 1;
1157         } else {
1158             nextLocalId = Constants::START_USER_ID + 1;
1159             ACCOUNT_LOGW("Convert last item in accountIdList to string failed.");
1160         }
1161     }
1162 
1163     id = GetNextLocalId(accountIdList, nextLocalId);
1164     accountListJson[Constants::NEXT_LOCAL_ID] = id + 1;
1165     result = SaveAccountListToFileAndDataBase(accountListJson);
1166     if (result != ERR_OK) {
1167         ACCOUNT_LOGE("GetAllowCreateId save accountListJson error, errCode %{public}d.", result);
1168     }
1169     return result;
1170 }
1171 
GetAccountListFromFile(Json & accountListJson)1172 ErrCode OsAccountControlFileManager::GetAccountListFromFile(Json &accountListJson)
1173 {
1174     ACCOUNT_LOGD("enter");
1175     accountListJson.clear();
1176     std::string accountList;
1177     std::lock_guard<std::mutex> lock(accountListFileLock_);
1178     ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_LIST_FILE_JSON_PATH,
1179         accountList);
1180     if (errCode != ERR_OK) {
1181         ACCOUNT_LOGE("GetFileContentByPath failed! error code %{public}d.", errCode);
1182         return errCode;
1183     }
1184     accountListJson = Json::parse(accountList, nullptr, false);
1185     if (accountListJson.is_discarded()) {
1186 #ifdef HAS_KV_STORE_PART
1187         return osAccountDataBaseOperator_->GetAccountListFromStoreID(OS_ACCOUNT_STORE_ID, accountListJson);
1188 #else
1189         return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
1190 #endif
1191     }
1192     ACCOUNT_LOGD("end");
1193     return ERR_OK;
1194 }
1195 
GetAccountIndexFromFile(Json & accountIndexJson)1196 ErrCode OsAccountControlFileManager::GetAccountIndexFromFile(Json &accountIndexJson)
1197 {
1198     accountIndexJson.clear();
1199     std::string accountIndex;
1200     if (!accountFileOperator_->IsJsonFileReady(Constants::ACCOUNT_INDEX_JSON_PATH)) {
1201         ErrCode result = GetAccountIndexInfo(accountIndex);
1202         if (result != ERR_OK) {
1203             ACCOUNT_LOGE("GetAccountIndexInfo error code %{public}d.", result);
1204             return result;
1205         }
1206     } else {
1207         ErrCode errCode = accountFileOperator_->GetFileContentByPath(Constants::ACCOUNT_INDEX_JSON_PATH, accountIndex);
1208         if (errCode != ERR_OK) {
1209             ACCOUNT_LOGE("GetFileContentByPath failed! error code %{public}d.", errCode);
1210             return errCode;
1211         }
1212     }
1213     accountIndexJson = Json::parse(accountIndex, nullptr, false);
1214     if (accountIndexJson.is_discarded()) {
1215         ACCOUNT_LOGE("parse os account info json data failed");
1216         return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
1217     }
1218     return ERR_OK;
1219 }
1220 
GetAccountIndexInfo(std::string & accountIndexInfo)1221 ErrCode OsAccountControlFileManager::GetAccountIndexInfo(std::string &accountIndexInfo)
1222 {
1223     std::vector<OsAccountInfo> osAccountInfos;
1224     ErrCode result = GetOsAccountList(osAccountInfos);
1225     if (result != ERR_OK) {
1226         return result;
1227     }
1228     Json accountIndexJson;
1229     for (auto account = osAccountInfos.begin(); account != osAccountInfos.end(); account++) {
1230         // private account don't check name
1231         if (account->GetType() == OsAccountType::PRIVATE) {
1232             continue;
1233         }
1234         std::string localIdStr = std::to_string(account->GetLocalId());
1235         Json accountIndexElement;
1236         accountIndexElement[Constants::LOCAL_NAME] = account->GetLocalName();
1237         accountIndexElement[Constants::SHORT_NAME] = account->GetShortName();
1238         accountIndexJson[localIdStr] = accountIndexElement;
1239     }
1240     accountIndexInfo = accountIndexJson.dump();
1241     return ERR_OK;
1242 }
1243 
GetBaseOAConstraintsFromFile(Json & baseOAConstraintsJson)1244 ErrCode OsAccountControlFileManager::GetBaseOAConstraintsFromFile(Json &baseOAConstraintsJson)
1245 {
1246     baseOAConstraintsJson.clear();
1247     std::string baseOAConstraints;
1248     std::lock_guard<std::mutex> lock(baseOAConstraintsFileLock_);
1249     ErrCode errCode = accountFileOperator_->GetFileContentByPath(
1250         Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH, baseOAConstraints);
1251     if (errCode != ERR_OK) {
1252         ACCOUNT_LOGE("GetFileContentByPath failed! error code %{public}d.", errCode);
1253         return errCode;
1254     }
1255     baseOAConstraintsJson = Json::parse(baseOAConstraints, nullptr, false);
1256     if (baseOAConstraintsJson.is_discarded() || !baseOAConstraintsJson.is_object()) {
1257         ACCOUNT_LOGE("base constraints json data parse failed code.");
1258         return errCode;
1259     }
1260 
1261     return ERR_OK;
1262 }
1263 
GetGlobalOAConstraintsFromFile(Json & globalOAConstraintsJson)1264 ErrCode OsAccountControlFileManager::GetGlobalOAConstraintsFromFile(Json &globalOAConstraintsJson)
1265 {
1266     globalOAConstraintsJson.clear();
1267     std::string globalOAConstraints;
1268     std::lock_guard<std::mutex> lock(globalOAConstraintsFileLock_);
1269     ErrCode errCode = accountFileOperator_->GetFileContentByPath(
1270         Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH, globalOAConstraints);
1271     if (errCode != ERR_OK) {
1272         ACCOUNT_LOGE("GetFileContentByPath failed! error code %{public}d.", errCode);
1273         return errCode;
1274     }
1275     globalOAConstraintsJson = Json::parse(globalOAConstraints, nullptr, false);
1276     if (globalOAConstraintsJson.is_discarded() || !globalOAConstraintsJson.is_object()) {
1277         ACCOUNT_LOGE("global constraints json data parse failed code.");
1278         return errCode;
1279     }
1280 
1281     return ERR_OK;
1282 }
1283 
GetSpecificOAConstraintsFromFile(Json & specificOAConstraintsJson)1284 ErrCode OsAccountControlFileManager::GetSpecificOAConstraintsFromFile(Json &specificOAConstraintsJson)
1285 {
1286     specificOAConstraintsJson.clear();
1287     std::string specificOAConstraints;
1288     std::lock_guard<std::mutex> lock(specificOAConstraintsFileLock_);
1289     ErrCode errCode = accountFileOperator_->GetFileContentByPath(
1290         Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH, specificOAConstraints);
1291     if (errCode != ERR_OK) {
1292         ACCOUNT_LOGE("GetFileContentByPath failed! error code %{public}d.", errCode);
1293         return errCode;
1294     }
1295     specificOAConstraintsJson = Json::parse(specificOAConstraints, nullptr, false);
1296     if (specificOAConstraintsJson.is_discarded() || !specificOAConstraintsJson.is_object()) {
1297         ACCOUNT_LOGE("specific constraints json data parse failed code.");
1298         return errCode;
1299     }
1300 
1301     return ERR_OK;
1302 }
1303 
IsFromBaseOAConstraintsList(const int32_t id,const std::string constraint,bool & isExist)1304 ErrCode OsAccountControlFileManager::IsFromBaseOAConstraintsList(
1305     const int32_t id, const std::string constraint, bool &isExist)
1306 {
1307     isExist = false;
1308     std::vector<std::string> constraintsList;
1309     std::lock_guard<std::mutex> lock(baseOAConstraintsFileLock_);
1310     ErrCode errCode = osAccountFileOperator_->GetBaseOAConstraintsList(id, constraintsList);
1311     if (errCode != ERR_OK) {
1312         ACCOUNT_LOGE("GetBaseOAConstraintsList failed! error code %{public}d.", errCode);
1313         return errCode;
1314     }
1315 
1316     if (std::find(constraintsList.begin(), constraintsList.end(), constraint) != constraintsList.end()) {
1317         isExist = true;
1318     }
1319 
1320     return ERR_OK;
1321 }
1322 
IsFromGlobalOAConstraintsList(const int32_t id,const int32_t deviceOwnerId,const std::string constraint,std::vector<ConstraintSourceTypeInfo> & globalSourceList)1323 ErrCode OsAccountControlFileManager::IsFromGlobalOAConstraintsList(const int32_t id, const int32_t deviceOwnerId,
1324     const std::string constraint, std::vector<ConstraintSourceTypeInfo> &globalSourceList)
1325 {
1326     globalSourceList.clear();
1327     std::vector<std::string> constraintsList;
1328     ErrCode errCode = ERR_OK;
1329     {
1330         std::lock_guard<std::mutex> lock(globalOAConstraintsFileLock_);
1331         errCode = osAccountFileOperator_->GetGlobalOAConstraintsList(constraintsList);
1332     }
1333     if (errCode != ERR_OK) {
1334         ACCOUNT_LOGE("GetGlobalOAConstraintsList failed! error code %{public}d.", errCode);
1335         return errCode;
1336     }
1337     if (constraintsList.size() == 0) {
1338         return ERR_OK;
1339     }
1340     if (std::find(constraintsList.begin(), constraintsList.end(), constraint) != constraintsList.end()) {
1341         Json globalOAConstraintsJson;
1342         errCode = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
1343         if (errCode != ERR_OK) {
1344             ACCOUNT_LOGE("get globalOAConstraints from file failed!");
1345             return errCode;
1346         }
1347         std::vector<std::string> globalOAConstraintsList;
1348         OHOS::AccountSA::GetDataByType<std::vector<std::string>>(
1349             globalOAConstraintsJson,
1350             globalOAConstraintsJson.end(),
1351             constraint,
1352             globalOAConstraintsList,
1353             OHOS::AccountSA::JsonType::ARRAY);
1354         ConstraintSourceTypeInfo constraintSourceTypeInfo;
1355         for (auto it = globalOAConstraintsList.begin(); it != globalOAConstraintsList.end(); it++) {
1356             int32_t localId = 0;
1357             if (!StrToInt(*it, localId)) {
1358                 ACCOUNT_LOGE("Convert localId failed");
1359                 continue;
1360             }
1361             if (localId == deviceOwnerId) {
1362                 constraintSourceTypeInfo.localId = localId;
1363                 constraintSourceTypeInfo.typeInfo = ConstraintSourceType::CONSTRAINT_TYPE_DEVICE_OWNER;
1364                 globalSourceList.push_back(constraintSourceTypeInfo);
1365             } else {
1366                 constraintSourceTypeInfo.localId = localId;
1367                 constraintSourceTypeInfo.typeInfo = ConstraintSourceType::CONSTRAINT_TYPE_PROFILE_OWNER;
1368                 globalSourceList.push_back(constraintSourceTypeInfo);
1369             }
1370         }
1371     }
1372     return ERR_OK;
1373 }
1374 
IsFromSpecificOAConstraintsList(const int32_t id,const int32_t deviceOwnerId,const std::string constraint,std::vector<ConstraintSourceTypeInfo> & specificSourceList)1375 ErrCode OsAccountControlFileManager::IsFromSpecificOAConstraintsList(const int32_t id, const int32_t deviceOwnerId,
1376     const std::string constraint, std::vector<ConstraintSourceTypeInfo> &specificSourceList)
1377 {
1378     specificSourceList.clear();
1379     std::vector<std::string> constraintsList;
1380     ErrCode errCode = ERR_OK;
1381     {
1382         std::lock_guard<std::mutex> lock(specificOAConstraintsFileLock_);
1383         errCode = osAccountFileOperator_->GetSpecificOAConstraintsList(id, constraintsList);
1384     }
1385     if (errCode != ERR_OK) {
1386         ACCOUNT_LOGE("GetSpecificOAConstraintsList failed! error code %{public}d.", errCode);
1387         return errCode;
1388     }
1389 
1390     if (std::find(constraintsList.begin(), constraintsList.end(), constraint) != constraintsList.end()) {
1391         Json specificOAConstraintsJson;
1392         errCode = GetSpecificOAConstraintsFromFile(specificOAConstraintsJson);
1393         if (errCode != ERR_OK) {
1394             ACCOUNT_LOGE("get specificOAConstraints from file failed!");
1395             return errCode;
1396         }
1397         Json specificOAConstraintsInfo;
1398         OHOS::AccountSA::GetDataByType<Json>(specificOAConstraintsJson, specificOAConstraintsJson.end(),
1399             std::to_string(id), specificOAConstraintsInfo, OHOS::AccountSA::JsonType::OBJECT);
1400         std::vector<std::string> specificConstraintSource;
1401         OHOS::AccountSA::GetDataByType<std::vector<std::string>>(specificOAConstraintsInfo,
1402             specificOAConstraintsInfo.end(), constraint,
1403             specificConstraintSource, OHOS::AccountSA::JsonType::ARRAY);
1404         ConstraintSourceTypeInfo constraintSourceTypeInfo;
1405         for (auto it = specificConstraintSource.begin(); it != specificConstraintSource.end(); it++) {
1406             int32_t localId = 0;
1407             if (!StrToInt(*it, localId)) {
1408                 ACCOUNT_LOGE("Convert localId failed");
1409                 continue;
1410             }
1411             if (localId == deviceOwnerId) {
1412                 constraintSourceTypeInfo.localId = localId;
1413                 constraintSourceTypeInfo.typeInfo = ConstraintSourceType::CONSTRAINT_TYPE_DEVICE_OWNER;
1414                 specificSourceList.push_back(constraintSourceTypeInfo);
1415             } else {
1416                 constraintSourceTypeInfo.localId = localId;
1417                 constraintSourceTypeInfo.typeInfo = ConstraintSourceType::CONSTRAINT_TYPE_PROFILE_OWNER;
1418                 specificSourceList.push_back(constraintSourceTypeInfo);
1419             }
1420         }
1421     }
1422     return ERR_OK;
1423 }
1424 
SaveAccountListToFile(const Json & accountListJson)1425 ErrCode OsAccountControlFileManager::SaveAccountListToFile(const Json &accountListJson)
1426 {
1427     std::lock_guard<std::mutex> lock(accountListFileLock_);
1428     ErrCode result =
1429         accountFileOperator_->InputFileByPathAndContent(Constants::ACCOUNT_LIST_FILE_JSON_PATH, accountListJson.dump());
1430     if (result != ERR_OK) {
1431         ACCOUNT_LOGE("cannot save save account list file content!");
1432         return result;
1433     }
1434     accountFileWatcherMgr_.AddAccountInfoDigest(accountListJson.dump(), Constants::ACCOUNT_LIST_FILE_JSON_PATH);
1435     ACCOUNT_LOGD("save account list file succeed!");
1436     return ERR_OK;
1437 }
1438 
SaveBaseOAConstraintsToFile(const Json & baseOAConstraints)1439 ErrCode OsAccountControlFileManager::SaveBaseOAConstraintsToFile(const Json &baseOAConstraints)
1440 {
1441     std::lock_guard<std::mutex> lock(baseOAConstraintsFileLock_);
1442     ErrCode result = accountFileOperator_->InputFileByPathAndContent(
1443         Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH, baseOAConstraints.dump());
1444     if (result != ERR_OK) {
1445         ACCOUNT_LOGE("cannot save base osaccount constraints file content!");
1446         return result;
1447     }
1448     accountFileWatcherMgr_.AddAccountInfoDigest(
1449         baseOAConstraints.dump(), Constants::BASE_OSACCOUNT_CONSTRAINTS_JSON_PATH);
1450     return ERR_OK;
1451 }
1452 
SaveGlobalOAConstraintsToFile(const Json & globalOAConstraints)1453 ErrCode OsAccountControlFileManager::SaveGlobalOAConstraintsToFile(const Json &globalOAConstraints)
1454 {
1455     std::lock_guard<std::mutex> lock(globalOAConstraintsFileLock_);
1456     ErrCode result = accountFileOperator_->InputFileByPathAndContent(
1457         Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH, globalOAConstraints.dump());
1458     if (result != ERR_OK) {
1459         ACCOUNT_LOGE("cannot save global osAccount constraints file content!");
1460         return result;
1461     }
1462     accountFileWatcherMgr_.AddAccountInfoDigest(
1463         globalOAConstraints.dump(), Constants::GLOBAL_OSACCOUNT_CONSTRAINTS_JSON_PATH);
1464     return ERR_OK;
1465 }
1466 
SaveSpecificOAConstraintsToFile(const Json & specificOAConstraints)1467 ErrCode OsAccountControlFileManager::SaveSpecificOAConstraintsToFile(const Json &specificOAConstraints)
1468 {
1469     std::lock_guard<std::mutex> lock(specificOAConstraintsFileLock_);
1470     ErrCode result = accountFileOperator_->InputFileByPathAndContent(
1471         Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH, specificOAConstraints.dump());
1472     if (result != ERR_OK) {
1473         ACCOUNT_LOGE("cannot save specific osAccount constraints file content!");
1474         return result;
1475     }
1476     accountFileWatcherMgr_.AddAccountInfoDigest(
1477         specificOAConstraints.dump(), Constants::SPECIFIC_OSACCOUNT_CONSTRAINTS_JSON_PATH);
1478     return ERR_OK;
1479 }
1480 
GetDeviceOwnerId(int & deviceOwnerId)1481 ErrCode OsAccountControlFileManager::GetDeviceOwnerId(int &deviceOwnerId)
1482 {
1483     Json globalOAConstraintsJson;
1484     ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
1485     if (result != ERR_OK) {
1486         ACCOUNT_LOGE("get global json data from file failed!");
1487         return result;
1488     }
1489     OHOS::AccountSA::GetDataByType<int>(
1490         globalOAConstraintsJson,
1491         globalOAConstraintsJson.end(),
1492         Constants::DEVICE_OWNER_ID,
1493         deviceOwnerId,
1494         OHOS::AccountSA::JsonType::NUMBER);
1495     return ERR_OK;
1496 }
1497 
UpdateDeviceOwnerId(const int deviceOwnerId)1498 ErrCode OsAccountControlFileManager::UpdateDeviceOwnerId(const int deviceOwnerId)
1499 {
1500     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
1501     Json globalOAConstraintsJson;
1502     ErrCode result = GetGlobalOAConstraintsFromFile(globalOAConstraintsJson);
1503     if (result != ERR_OK) {
1504         ACCOUNT_LOGE("get global json data from file failed!");
1505         return result;
1506     }
1507     globalOAConstraintsJson[Constants::DEVICE_OWNER_ID] = deviceOwnerId;
1508     return SaveGlobalOAConstraintsToFile(globalOAConstraintsJson);
1509 }
1510 
SetDefaultActivatedOsAccount(const int32_t id)1511 ErrCode OsAccountControlFileManager::SetDefaultActivatedOsAccount(const int32_t id)
1512 {
1513     std::lock_guard<std::mutex> lock(accountInfoFileLock_);
1514     Json accountListJson;
1515     ErrCode result = GetAccountListFromFile(accountListJson);
1516     if (result != ERR_OK) {
1517         ACCOUNT_LOGE("get account list failed!");
1518         return result;
1519     }
1520 
1521     accountListJson[DEFAULT_ACTIVATED_ACCOUNT_ID] = id;
1522     return SaveAccountListToFileAndDataBase(accountListJson);
1523 }
1524 
GetDefaultActivatedOsAccount(int32_t & id)1525 ErrCode OsAccountControlFileManager::GetDefaultActivatedOsAccount(int32_t &id)
1526 {
1527     Json accountListJsonData;
1528     ErrCode result = GetAccountListFromFile(accountListJsonData);
1529     if (result != ERR_OK) {
1530         return result;
1531     }
1532     OHOS::AccountSA::GetDataByType<int>(accountListJsonData,
1533         accountListJsonData.end(),
1534         DEFAULT_ACTIVATED_ACCOUNT_ID,
1535         id,
1536         OHOS::AccountSA::JsonType::NUMBER);
1537     return ERR_OK;
1538 }
1539 
SaveAccountListToFileAndDataBase(const Json & accountListJson)1540 ErrCode OsAccountControlFileManager::SaveAccountListToFileAndDataBase(const Json &accountListJson)
1541 {
1542 #ifdef HAS_KV_STORE_PART
1543     osAccountDataBaseOperator_->UpdateOsAccountIDListInDatabase(accountListJson);
1544 #endif
1545     return SaveAccountListToFile(accountListJson);
1546 }
1547 
IsOsAccountExists(const int id,bool & isExists)1548 ErrCode OsAccountControlFileManager::IsOsAccountExists(const int id, bool &isExists)
1549 {
1550     isExists = false;
1551     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) +
1552                        Constants::PATH_SEPARATOR + Constants::USER_INFO_FILE_NAME;
1553     // check exist
1554     if (!accountFileOperator_->IsExistFile(path)) {
1555         ACCOUNT_LOGI("IsOsAccountExists path %{public}s does not exist!", path.c_str());
1556         return ERR_OK;
1557     }
1558 
1559     // check format
1560     if (!accountFileOperator_->IsJsonFormat(path)) {
1561         ACCOUNT_LOGI("IsOsAccountExists path %{public}s wrong format!", path.c_str());
1562         return ERR_OK;
1563     }
1564 
1565     isExists = true;
1566     return ERR_OK;
1567 }
1568 
GetPhotoById(const int id,std::string & photo)1569 ErrCode OsAccountControlFileManager::GetPhotoById(const int id, std::string &photo)
1570 {
1571     if ((photo != Constants::USER_PHOTO_FILE_JPG_NAME) && (photo != Constants::USER_PHOTO_FILE_PNG_NAME)
1572         && (photo != Constants::USER_PHOTO_FILE_TXT_NAME)) {
1573         return ERR_OK;
1574     }
1575     std::string path =
1576         Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id) + Constants::PATH_SEPARATOR + photo;
1577     std::string byteStr = "";
1578     ErrCode errCode = accountFileOperator_->GetFileContentByPath(path, byteStr);
1579     if (errCode != ERR_OK) {
1580         ACCOUNT_LOGE("GetPhotoById cannot find photo file error");
1581         return errCode;
1582     }
1583     if (photo == Constants::USER_PHOTO_FILE_TXT_NAME) {
1584         photo = byteStr;
1585         return ERR_OK;
1586     }
1587     // USER_PHOTO_FILE_JPG_NAME and USER_PHOTO_FILE_PNG_NAME are compatible with previous data
1588     if (photo == Constants::USER_PHOTO_FILE_JPG_NAME) {
1589         photo =
1590             Constants::USER_PHOTO_BASE_JPG_HEAD + osAccountPhotoOperator_->EnCode(byteStr.c_str(), byteStr.length());
1591     } else {
1592         photo =
1593             Constants::USER_PHOTO_BASE_PNG_HEAD + osAccountPhotoOperator_->EnCode(byteStr.c_str(), byteStr.length());
1594     }
1595     std::string substr = "\r\n";
1596     while (photo.find(substr) != std::string::npos) {
1597         photo.erase(photo.find(substr), substr.length());
1598     }
1599     return ERR_OK;
1600 }
1601 
SetPhotoById(const int id,const std::string & photo)1602 ErrCode OsAccountControlFileManager::SetPhotoById(const int id, const std::string &photo)
1603 {
1604     std::string path = Constants::USER_INFO_BASE + Constants::PATH_SEPARATOR + std::to_string(id)
1605         + Constants::PATH_SEPARATOR + Constants::USER_PHOTO_FILE_TXT_NAME;
1606     ErrCode errCode = accountFileOperator_->InputFileByPathAndContent(path, photo);
1607     if (errCode != ERR_OK) {
1608         return errCode;
1609     }
1610     return ERR_OK;
1611 }
1612 
GetGlobalOAConstraintsList(std::vector<std::string> & constraintsList)1613 ErrCode OsAccountControlFileManager::GetGlobalOAConstraintsList(std::vector<std::string> &constraintsList)
1614 {
1615     std::lock_guard<std::mutex> lock(globalOAConstraintsFileLock_);
1616     return osAccountFileOperator_->GetGlobalOAConstraintsList(constraintsList);
1617 }
1618 
GetSpecificOAConstraintsList(const int32_t id,std::vector<std::string> & constraintsList)1619 ErrCode OsAccountControlFileManager::GetSpecificOAConstraintsList(
1620     const int32_t id, std::vector<std::string> &constraintsList)
1621 {
1622     std::lock_guard<std::mutex> lock(specificOAConstraintsFileLock_);
1623     return osAccountFileOperator_->GetSpecificOAConstraintsList(id, constraintsList);
1624 }
1625 
GetIsMultiOsAccountEnable(bool & isMultiOsAccountEnable)1626 ErrCode OsAccountControlFileManager::GetIsMultiOsAccountEnable(bool &isMultiOsAccountEnable)
1627 {
1628     return osAccountFileOperator_->GetIsMultiOsAccountEnable(isMultiOsAccountEnable);
1629 }
CheckConstraintsList(const std::vector<std::string> & constraints,bool & isExists,bool & isOverSize)1630 ErrCode OsAccountControlFileManager::CheckConstraintsList(
1631     const std::vector<std::string> &constraints, bool &isExists, bool &isOverSize)
1632 {
1633     return osAccountFileOperator_->CheckConstraintsList(constraints, isExists, isOverSize);
1634 }
1635 
IsAllowedCreateAdmin(bool & isAllowedCreateAdmin)1636 ErrCode OsAccountControlFileManager::IsAllowedCreateAdmin(bool &isAllowedCreateAdmin)
1637 {
1638     return osAccountFileOperator_->IsAllowedCreateAdmin(isAllowedCreateAdmin);
1639 }
1640 
GetCreatedOsAccountNumFromDatabase(const std::string & storeID,int & createdOsAccountNum)1641 ErrCode OsAccountControlFileManager::GetCreatedOsAccountNumFromDatabase(const std::string& storeID,
1642     int &createdOsAccountNum)
1643 {
1644 #ifdef HAS_KV_STORE_PART
1645     return osAccountDataBaseOperator_->GetCreatedOsAccountNumFromDatabase(storeID, createdOsAccountNum);
1646 #else
1647     return ERR_ACCOUNT_COMMON_INTERFACE_NOT_SUPPORT_ERROR;
1648 #endif
1649 }
1650 
GetSerialNumberFromDatabase(const std::string & storeID,int64_t & serialNumber)1651 ErrCode OsAccountControlFileManager::GetSerialNumberFromDatabase(const std::string& storeID,
1652     int64_t &serialNumber)
1653 {
1654 #ifdef HAS_KV_STORE_PART
1655     return osAccountDataBaseOperator_->GetSerialNumberFromDatabase(storeID, serialNumber);
1656 #else
1657     return ERR_ACCOUNT_COMMON_INTERFACE_NOT_SUPPORT_ERROR;
1658 #endif
1659 }
1660 
GetMaxAllowCreateIdFromDatabase(const std::string & storeID,int & id)1661 ErrCode OsAccountControlFileManager::GetMaxAllowCreateIdFromDatabase(const std::string& storeID,
1662     int &id)
1663 {
1664 #ifdef HAS_KV_STORE_PART
1665     return osAccountDataBaseOperator_->GetMaxAllowCreateIdFromDatabase(storeID, id);
1666 #else
1667     return ERR_ACCOUNT_COMMON_INTERFACE_NOT_SUPPORT_ERROR;
1668 #endif
1669 }
1670 
GetOsAccountFromDatabase(const std::string & storeID,const int id,OsAccountInfo & osAccountInfo)1671 ErrCode OsAccountControlFileManager::GetOsAccountFromDatabase(const std::string& storeID,
1672     const int id, OsAccountInfo &osAccountInfo)
1673 {
1674 #ifdef HAS_KV_STORE_PART
1675     return osAccountDataBaseOperator_->GetOsAccountFromDatabase(storeID, id, osAccountInfo);
1676 #else
1677     return ERR_ACCOUNT_COMMON_INTERFACE_NOT_SUPPORT_ERROR;
1678 #endif
1679 }
1680 
GetOsAccountListFromDatabase(const std::string & storeID,std::vector<OsAccountInfo> & osAccountList)1681 ErrCode OsAccountControlFileManager::GetOsAccountListFromDatabase(const std::string& storeID,
1682     std::vector<OsAccountInfo> &osAccountList)
1683 {
1684 #ifdef HAS_KV_STORE_PART
1685     return osAccountDataBaseOperator_->GetOsAccountListFromDatabase(storeID, osAccountList);
1686 #else
1687     return ERR_ACCOUNT_COMMON_INTERFACE_NOT_SUPPORT_ERROR;
1688 #endif
1689 }
1690 }  // namespace AccountSA
1691 }  // namespace OHOS