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 #include "os_account_database_operator.h"
16 #include "account_log_wrapper.h"
17 #include "os_account_constants.h"
18 #include "os_account_data_storage.h"
19 
20 namespace OHOS {
21 namespace AccountSA {
22 namespace {
23 const std::string OS_ACCOUNT_STORE_ID = "os_account_info";
24 }
25 
OsAccountDatabaseOperator()26 OsAccountDatabaseOperator::OsAccountDatabaseOperator()
27 {}
28 
~OsAccountDatabaseOperator()29 OsAccountDatabaseOperator::~OsAccountDatabaseOperator()
30 {}
31 
InnerInit()32 bool OsAccountDatabaseOperator::InnerInit()
33 {
34     if (accountDataStorage_ == nullptr) {
35         ACCOUNT_LOGI("database operator inner init, enter!");
36         accountDataStorage_ = std::make_shared<OsAccountDataStorage>(
37             Constants::APP_ID, OS_ACCOUNT_STORE_ID, Constants::SYNC_OS_ACCOUNT_DATABASE);
38         if (accountDataStorage_ == nullptr) {
39             ACCOUNT_LOGE("accountDataStorage_ is still nullptr.");
40             return false;
41         }
42 
43         if (!accountDataStorage_->IsKeyExists(Constants::ACCOUNT_LIST)) {
44             ACCOUNT_LOGI("database operator inner init, create account list.");
45             std::vector<std::string> accountListVec;
46             Json accountList = Json {
47                 {Constants::ACCOUNT_LIST, accountListVec},
48                 {Constants::COUNT_ACCOUNT_NUM, 0},
49                 {Constants::MAX_ALLOW_CREATE_ACCOUNT_ID, Constants::MAX_USER_ID},
50                 {Constants::SERIAL_NUMBER_NUM, Constants::SERIAL_NUMBER_NUM_START},
51             };
52             SaveAccountListToDatabase(accountList);
53         }
54     }
55     return true;
56 }
57 
GetOsAccountListFromDatabase(const std::string & storeID,std::vector<OsAccountInfo> & osAccountList)58 ErrCode OsAccountDatabaseOperator::GetOsAccountListFromDatabase(const std::string& storeID,
59                                                                 std::vector<OsAccountInfo> &osAccountList)
60 {
61     osAccountList.clear();
62     if (!InnerInit()) {
63         ACCOUNT_LOGE("InnerInit failed!");
64         return ERR_ACCOUNT_COMMON_NOT_INIT_ERROR;
65     }
66 
67     std::map<std::string, std::shared_ptr<IAccountInfo>> osAccountMapInfos;
68     ErrCode errCode = ERR_OK;
69     if (storeID.empty()) {
70         errCode = accountDataStorage_->LoadAllData(osAccountMapInfos);
71     } else {
72         std::shared_ptr<AccountDataStorage> storagePtr = std::make_shared<OsAccountDataStorage>(
73             Constants::APP_ID, storeID, Constants::SYNC_OS_ACCOUNT_DATABASE);
74         if (storagePtr == nullptr) {
75             ACCOUNT_LOGE("storagePtr is still nullptr, storeID %{public}s.", storeID.c_str());
76             return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
77         }
78         errCode = storagePtr->LoadAllData(osAccountMapInfos);
79     }
80 
81     if (errCode != ERR_OK) {
82         ACCOUNT_LOGE("LoadAllData failed! storeID %{public}s.", storeID.c_str());
83         return errCode;
84     }
85 
86     for (auto it = osAccountMapInfos.begin(); it != osAccountMapInfos.end(); it++) {
87         OsAccountInfo curOsInfo = *(std::static_pointer_cast<OsAccountInfo>(it->second));
88         if (curOsInfo.GetLocalId() >= Constants::START_USER_ID) {
89             osAccountList.push_back(curOsInfo);
90         }
91     }
92     return ERR_OK;
93 }
94 
InsertOsAccountIntoDataBase(const OsAccountInfo & osAccountInfo)95 void OsAccountDatabaseOperator::InsertOsAccountIntoDataBase(const OsAccountInfo &osAccountInfo)
96 {
97     if (!InnerInit()) {
98         ACCOUNT_LOGE("InnerInit failed! target localID %{public}d!", osAccountInfo.GetLocalId());
99         return;
100     }
101 
102     if (osAccountInfo.GetLocalId() < Constants::START_USER_ID) {
103         ACCOUNT_LOGI("target os account id %{public}d will not be saved in database!", osAccountInfo.GetLocalId());
104         return;
105     }
106 
107     ErrCode errCode = accountDataStorage_->AddAccountInfo(osAccountInfo);
108     if (errCode != ERR_OK) {
109         ACCOUNT_LOGE("AddAccountInfo failed, error code %{public}d, target id %{public}d.",
110             errCode, osAccountInfo.GetLocalId());
111         return;
112     }
113     ACCOUNT_LOGI("insert account %{public}d to database succeed.", osAccountInfo.GetLocalId());
114 }
115 
DelOsAccountFromDatabase(const int id)116 void OsAccountDatabaseOperator::DelOsAccountFromDatabase(const int id)
117 {
118     if (!InnerInit()) {
119         ACCOUNT_LOGE("InnerInit failed! id %{public}d!", id);
120         return;
121     }
122 
123     ErrCode errCode = accountDataStorage_->RemoveValueFromKvStore(std::to_string(id));
124     if (errCode != ERR_OK) {
125         ACCOUNT_LOGE("delete os account %{public}d from database failed! error code %{public}d.", id, errCode);
126     } else {
127         ACCOUNT_LOGI("delete os account %{public}d from database succeed!", id);
128     }
129 }
130 
UpdateOsAccountInDatabase(const OsAccountInfo & osAccountInfo)131 void OsAccountDatabaseOperator::UpdateOsAccountInDatabase(const OsAccountInfo &osAccountInfo)
132 {
133     if (!InnerInit()) {
134         ACCOUNT_LOGE("InnerInit failed! local id %{public}d!", osAccountInfo.GetLocalId());
135         return;
136     }
137 
138     ErrCode errCode = accountDataStorage_->SaveAccountInfo(osAccountInfo);
139     if (errCode != ERR_OK) {
140         ACCOUNT_LOGE("update os account info in database for account %{public}d failed! errCode = %{public}d.",
141             osAccountInfo.GetLocalId(), errCode);
142     } else {
143         ACCOUNT_LOGI("update os account info in database for account %{public}d succeed!", osAccountInfo.GetLocalId());
144     }
145 }
146 
GetOsAccountFromDatabase(const std::string & storeID,const int id,OsAccountInfo & osAccountInfo)147 ErrCode OsAccountDatabaseOperator::GetOsAccountFromDatabase(const std::string& storeID,
148                                                             const int id,
149                                                             OsAccountInfo &osAccountInfo)
150 {
151     if (!InnerInit()) {
152         ACCOUNT_LOGE("InnerInit failed! storeID %{public}s id %{public}d!", storeID.c_str(), id);
153         return ERR_ACCOUNT_COMMON_NOT_INIT_ERROR;
154     }
155 
156     if (storeID.empty()) {
157         return accountDataStorage_->GetAccountInfoById(std::to_string(id), osAccountInfo);
158     }
159 
160     std::shared_ptr<AccountDataStorage> storagePtr = std::make_shared<OsAccountDataStorage>(
161         Constants::APP_ID, storeID, Constants::SYNC_OS_ACCOUNT_DATABASE);
162     if (storagePtr == nullptr) {
163         ACCOUNT_LOGE("storagePtr is nullptr, for other storeID %{public}s, id %{public}d.", storeID.c_str(), id);
164         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
165     }
166     return storagePtr->GetAccountInfoById(std::to_string(id), osAccountInfo);
167 }
168 
GetCreatedOsAccountNumFromDatabase(const std::string & storeID,int & createdOsAccountNum)169 ErrCode OsAccountDatabaseOperator::GetCreatedOsAccountNumFromDatabase(
170     const std::string& storeID, int &createdOsAccountNum)
171 {
172     Json accountListJson;
173     ErrCode ret = GetAccountListFromStoreID(storeID, accountListJson);
174     if (ret != ERR_OK) {
175         ACCOUNT_LOGE("get account list from database failed, storeID %{public}s.", storeID.c_str());
176         return ret;
177     }
178     OHOS::AccountSA::GetDataByType<int>(accountListJson, accountListJson.end(),
179         Constants::COUNT_ACCOUNT_NUM, createdOsAccountNum, OHOS::AccountSA::JsonType::NUMBER);
180     return ERR_OK;
181 }
182 
UpdateOsAccountIDListInDatabase(const Json & accountListJson)183 void OsAccountDatabaseOperator::UpdateOsAccountIDListInDatabase(const Json &accountListJson)
184 {
185     if (SaveAccountListToDatabase(accountListJson) != ERR_OK) {
186         ACCOUNT_LOGE("update os account id list to database failed.");
187         return;
188     }
189     ACCOUNT_LOGD("update os account id list to database succeed.");
190 }
191 
GetSerialNumberFromDatabase(const std::string & storeID,int64_t & serialNumber)192 ErrCode OsAccountDatabaseOperator::GetSerialNumberFromDatabase(
193     const std::string& storeID, int64_t &serialNumber)
194 {
195     Json accountListJson;
196     ErrCode ret = GetAccountListFromStoreID(storeID, accountListJson);
197     if (ret != ERR_OK) {
198         ACCOUNT_LOGE("get serial number from database failed! err %{public}d, storeID %{public}s.",
199             ret, storeID.c_str());
200         return ret;
201     }
202     OHOS::AccountSA::GetDataByType<int>(accountListJson, accountListJson.end(),
203         Constants::SERIAL_NUMBER_NUM, serialNumber, OHOS::AccountSA::JsonType::NUMBER);
204     return ERR_OK;
205 }
206 
GetMaxAllowCreateIdFromDatabase(const std::string & storeID,int & id)207 ErrCode OsAccountDatabaseOperator::GetMaxAllowCreateIdFromDatabase(const std::string& storeID, int &id)
208 {
209     Json accountListJson;
210     ErrCode ret = GetAccountListFromStoreID(storeID, accountListJson);
211     if (ret != ERR_OK) {
212         ACCOUNT_LOGE("get max allow created id from database failed. err %{public}d, storeID %{public}s.",
213             ret, storeID.c_str());
214         return ret;
215     }
216     OHOS::AccountSA::GetDataByType<int>(accountListJson, accountListJson.end(),
217         Constants::MAX_ALLOW_CREATE_ACCOUNT_ID, id, OHOS::AccountSA::JsonType::NUMBER);
218     return ERR_OK;
219 }
220 
GetAccountListFromStoreID(const std::string & storeID,Json & accountListJson)221 ErrCode OsAccountDatabaseOperator::GetAccountListFromStoreID(
222     const std::string& storeID, Json &accountListJson)
223 {
224     accountListJson.clear();
225     if (!InnerInit()) {
226         ACCOUNT_LOGE("InnerInit failed! storeID %{public}s!", storeID.c_str());
227         return ERR_ACCOUNT_COMMON_NOT_INIT_ERROR;
228     }
229 
230     std::string accountList;
231     ErrCode errCode = ERR_OK;
232     if (storeID.empty()) {
233         errCode = accountDataStorage_->GetValueFromKvStore(Constants::ACCOUNT_LIST, accountList);
234     } else {
235         std::shared_ptr<AccountDataStorage> storagePtr = std::make_shared<OsAccountDataStorage>(
236             Constants::APP_ID, storeID, Constants::SYNC_OS_ACCOUNT_DATABASE);
237         if (storagePtr == nullptr) {
238             ACCOUNT_LOGE("storagePtr is nullptr, for other storeID %{public}s.", storeID.c_str());
239             return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
240         }
241         errCode = storagePtr->GetValueFromKvStore(Constants::ACCOUNT_LIST, accountList);
242     }
243 
244     if (errCode != ERR_OK) {
245         ACCOUNT_LOGE("Get account list info from database failed! storeID %{public}s.", storeID.c_str());
246         return errCode;
247     }
248     accountListJson = Json::parse(accountList, nullptr, false);
249     if (accountListJson.is_discarded()) {
250         return ERR_ACCOUNT_COMMON_BAD_JSON_FORMAT_ERROR;
251     }
252     return ERR_OK;
253 }
254 
SaveAccountListToDatabase(const Json & accountListJson)255 ErrCode OsAccountDatabaseOperator::SaveAccountListToDatabase(const Json &accountListJson)
256 {
257     if (!InnerInit()) {
258         ACCOUNT_LOGE("InnerInit failed!");
259         return ERR_ACCOUNT_COMMON_NOT_INIT_ERROR;
260     }
261     ErrCode errCode = accountDataStorage_->PutValueToKvStore(Constants::ACCOUNT_LIST, accountListJson.dump());
262     if (errCode != ERR_OK) {
263         ACCOUNT_LOGE("Save or Add config info to database failed! errCode %{public}d.", errCode);
264         return errCode;
265     }
266     ACCOUNT_LOGD("save or add account list info to database succeed!");
267     return ERR_OK;
268 }
269 }  // namespace AccountSA
270 }  // namespace OHOS