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