1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "sqlite_storage.h"
17
18 #include "accesstoken_log.h"
19
20 namespace OHOS {
21 namespace Security {
22 namespace AccessToken {
23 namespace {
24 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "SqliteStorage"};
25 static const std::string INTEGER_STR = " integer not null,";
26 static const std::string TEXT_STR = " text not null,";
27 }
28
GetInstance()29 SqliteStorage& SqliteStorage::GetInstance()
30 {
31 static SqliteStorage instance;
32 return instance;
33 }
34
~SqliteStorage()35 SqliteStorage::~SqliteStorage()
36 {
37 Close();
38 }
39
OnCreate()40 void SqliteStorage::OnCreate()
41 {
42 ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__);
43 CreateHapTokenInfoTable();
44 CreateNativeTokenInfoTable();
45 CreatePermissionDefinitionTable();
46 CreatePermissionStateTable();
47 }
48
OnUpdate()49 void SqliteStorage::OnUpdate()
50 {
51 ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__);
52 }
53
SqliteStorage()54 SqliteStorage::SqliteStorage() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION)
55 {
56 SqliteTable hapTokenInfoTable;
57 hapTokenInfoTable.tableName_ = HAP_TOKEN_INFO_TABLE;
58 hapTokenInfoTable.tableColumnNames_ = {
59 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_USER_ID,
60 TokenFiledConst::FIELD_BUNDLE_NAME, TokenFiledConst::FIELD_INST_INDEX, TokenFiledConst::FIELD_DLP_TYPE,
61 TokenFiledConst::FIELD_APP_ID, TokenFiledConst::FIELD_DEVICE_ID,
62 TokenFiledConst::FIELD_APL, TokenFiledConst::FIELD_TOKEN_VERSION,
63 TokenFiledConst::FIELD_TOKEN_ATTR, TokenFiledConst::FIELD_API_VERSION
64 };
65
66 SqliteTable nativeTokenInfoTable;
67 nativeTokenInfoTable.tableName_ = NATIVE_TOKEN_INFO_TABLE;
68 nativeTokenInfoTable.tableColumnNames_ = {
69 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PROCESS_NAME,
70 TokenFiledConst::FIELD_TOKEN_VERSION, TokenFiledConst::FIELD_TOKEN_ATTR,
71 TokenFiledConst::FIELD_DCAP, TokenFiledConst::FIELD_NATIVE_ACLS, TokenFiledConst::FIELD_APL
72 };
73
74 SqliteTable permissionDefTable;
75 permissionDefTable.tableName_ = PERMISSION_DEF_TABLE;
76 permissionDefTable.tableColumnNames_ = {
77 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PERMISSION_NAME,
78 TokenFiledConst::FIELD_BUNDLE_NAME, TokenFiledConst::FIELD_GRANT_MODE,
79 TokenFiledConst::FIELD_AVAILABLE_LEVEL, TokenFiledConst::FIELD_PROVISION_ENABLE,
80 TokenFiledConst::FIELD_DISTRIBUTED_SCENE_ENABLE, TokenFiledConst::FIELD_LABEL,
81 TokenFiledConst::FIELD_LABEL_ID, TokenFiledConst::FIELD_DESCRIPTION,
82 TokenFiledConst::FIELD_DESCRIPTION_ID
83 };
84
85 SqliteTable permissionStateTable;
86 permissionStateTable.tableName_ = PERMISSION_STATE_TABLE;
87 permissionStateTable.tableColumnNames_ = {
88 TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PERMISSION_NAME,
89 TokenFiledConst::FIELD_DEVICE_ID, TokenFiledConst::FIELD_GRANT_IS_GENERAL,
90 TokenFiledConst::FIELD_GRANT_STATE, TokenFiledConst::FIELD_GRANT_FLAG
91 };
92
93 dataTypeToSqlTable_ = {
94 {ACCESSTOKEN_HAP_INFO, hapTokenInfoTable},
95 {ACCESSTOKEN_NATIVE_INFO, nativeTokenInfoTable},
96 {ACCESSTOKEN_PERMISSION_DEF, permissionDefTable},
97 {ACCESSTOKEN_PERMISSION_STATE, permissionStateTable},
98 };
99
100 Open();
101 }
102
Add(const DataType type,const std::vector<GenericValues> & values)103 int SqliteStorage::Add(const DataType type, const std::vector<GenericValues>& values)
104 {
105 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
106 std::string prepareSql = CreateInsertPrepareSqlCmd(type);
107 auto statement = Prepare(prepareSql);
108 BeginTransaction();
109 bool isExecuteSuccessfully = true;
110 for (const auto& value : values) {
111 std::vector<std::string> columnNames = value.GetAllKeys();
112 for (const auto& columnName : columnNames) {
113 statement.Bind(columnName, value.Get(columnName));
114 }
115 int ret = statement.Step();
116 if (ret != Statement::State::DONE) {
117 ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", SpitError().c_str());
118 isExecuteSuccessfully = false;
119 }
120 statement.Reset();
121 }
122 if (!isExecuteSuccessfully) {
123 ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction.");
124 RollbackTransaction();
125 return FAILURE;
126 }
127 ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction.");
128 CommitTransaction();
129 return SUCCESS;
130 }
131
Remove(const DataType type,const GenericValues & conditions)132 int SqliteStorage::Remove(const DataType type, const GenericValues& conditions)
133 {
134 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
135 std::vector<std::string> columnNames = conditions.GetAllKeys();
136 std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames);
137 auto statement = Prepare(prepareSql);
138 for (const auto& columnName : columnNames) {
139 statement.Bind(columnName, conditions.Get(columnName));
140 }
141 int ret = statement.Step();
142 return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
143 }
144
Modify(const DataType type,const GenericValues & modifyValues,const GenericValues & conditions)145 int SqliteStorage::Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions)
146 {
147 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
148 std::vector<std::string> modifyColumns = modifyValues.GetAllKeys();
149 std::vector<std::string> conditionColumns = conditions.GetAllKeys();
150 std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyColumns, conditionColumns);
151 auto statement = Prepare(prepareSql);
152 for (const auto& columnName : modifyColumns) {
153 statement.Bind(columnName, modifyValues.Get(columnName));
154 }
155 for (const auto& columnName : conditionColumns) {
156 statement.Bind(columnName, conditions.Get(columnName));
157 }
158 int ret = statement.Step();
159 return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
160 }
161
Find(const DataType type,std::vector<GenericValues> & results)162 int SqliteStorage::Find(const DataType type, std::vector<GenericValues>& results)
163 {
164 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
165 std::string prepareSql = CreateSelectPrepareSqlCmd(type);
166 auto statement = Prepare(prepareSql);
167 while (statement.Step() == Statement::State::ROW) {
168 int columnCount = statement.GetColumnCount();
169 GenericValues value;
170 for (int i = 0; i < columnCount; i++) {
171 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
172 }
173 results.emplace_back(value);
174 }
175 return SUCCESS;
176 }
177
RefreshAll(const DataType type,const std::vector<GenericValues> & values)178 int SqliteStorage::RefreshAll(const DataType type, const std::vector<GenericValues>& values)
179 {
180 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
181 std::string deleteSql = CreateDeletePrepareSqlCmd(type);
182 std::string insertSql = CreateInsertPrepareSqlCmd(type);
183 auto deleteStatement = Prepare(deleteSql);
184 auto insertStatement = Prepare(insertSql);
185 BeginTransaction();
186 bool canCommit = deleteStatement.Step() == Statement::State::DONE;
187 for (const auto& value : values) {
188 std::vector<std::string> columnNames = value.GetAllKeys();
189 for (const auto& columnName : columnNames) {
190 insertStatement.Bind(columnName, value.Get(columnName));
191 }
192 int ret = insertStatement.Step();
193 if (ret != Statement::State::DONE) {
194 ACCESSTOKEN_LOG_ERROR(
195 LABEL, "insert failed, errorMsg: %{public}s", SpitError().c_str());
196 canCommit = false;
197 }
198 insertStatement.Reset();
199 }
200 if (!canCommit) {
201 ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction.");
202 RollbackTransaction();
203 return FAILURE;
204 }
205 ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction.");
206 CommitTransaction();
207 return SUCCESS;
208 }
209
CreateInsertPrepareSqlCmd(const DataType type) const210 std::string SqliteStorage::CreateInsertPrepareSqlCmd(const DataType type) const
211 {
212 auto it = dataTypeToSqlTable_.find(type);
213 if (it == dataTypeToSqlTable_.end()) {
214 return std::string();
215 }
216 std::string sql = "insert into " + it->second.tableName_ + " values(";
217 int i = 1;
218 for (const auto& columnName : it->second.tableColumnNames_) {
219 sql.append(":" + columnName);
220 if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
221 sql.append(",");
222 }
223 i += 1;
224 }
225 sql.append(")");
226 return sql;
227 }
228
CreateDeletePrepareSqlCmd(const DataType type,const std::vector<std::string> & columnNames) const229 std::string SqliteStorage::CreateDeletePrepareSqlCmd(
230 const DataType type, const std::vector<std::string>& columnNames) const
231 {
232 auto it = dataTypeToSqlTable_.find(type);
233 if (it == dataTypeToSqlTable_.end()) {
234 return std::string();
235 }
236 std::string sql = "delete from " + it->second.tableName_ + " where 1 = 1";
237 for (const auto& columnName : columnNames) {
238 sql.append(" and ");
239 sql.append(columnName + "=:" + columnName);
240 }
241 return sql;
242 }
243
CreateUpdatePrepareSqlCmd(const DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const244 std::string SqliteStorage::CreateUpdatePrepareSqlCmd(const DataType type, const std::vector<std::string>& modifyColumns,
245 const std::vector<std::string>& conditionColumns) const
246 {
247 if (modifyColumns.empty()) {
248 return std::string();
249 }
250
251 auto it = dataTypeToSqlTable_.find(type);
252 if (it == dataTypeToSqlTable_.end()) {
253 return std::string();
254 }
255
256 std::string sql = "update " + it->second.tableName_ + " set ";
257 int i = 1;
258 for (const auto& columnName : modifyColumns) {
259 sql.append(columnName + "=:" + columnName);
260 if (i < static_cast<int32_t>(modifyColumns.size())) {
261 sql.append(",");
262 }
263 i += 1;
264 }
265
266 if (!conditionColumns.empty()) {
267 sql.append(" where 1 = 1");
268 for (const auto& columnName : conditionColumns) {
269 sql.append(" and ");
270 sql.append(columnName + "=:" + columnName);
271 }
272 }
273 return sql;
274 }
275
CreateSelectPrepareSqlCmd(const DataType type) const276 std::string SqliteStorage::CreateSelectPrepareSqlCmd(const DataType type) const
277 {
278 auto it = dataTypeToSqlTable_.find(type);
279 if (it == dataTypeToSqlTable_.end()) {
280 return std::string();
281 }
282 std::string sql = "select * from " + it->second.tableName_;
283 return sql;
284 }
285
CreateHapTokenInfoTable() const286 int SqliteStorage::CreateHapTokenInfoTable() const
287 {
288 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_HAP_INFO);
289 if (it == dataTypeToSqlTable_.end()) {
290 return FAILURE;
291 }
292 std::string sql = "create table if not exists ";
293 sql.append(it->second.tableName_ + " (")
294 .append(TokenFiledConst::FIELD_TOKEN_ID)
295 .append(INTEGER_STR)
296 .append(TokenFiledConst::FIELD_USER_ID)
297 .append(INTEGER_STR)
298 .append(TokenFiledConst::FIELD_BUNDLE_NAME)
299 .append(TEXT_STR)
300 .append(TokenFiledConst::FIELD_INST_INDEX)
301 .append(INTEGER_STR)
302 .append(TokenFiledConst::FIELD_DLP_TYPE)
303 .append(INTEGER_STR)
304 .append(TokenFiledConst::FIELD_APP_ID)
305 .append(TEXT_STR)
306 .append(TokenFiledConst::FIELD_DEVICE_ID)
307 .append(TEXT_STR)
308 .append(TokenFiledConst::FIELD_APL)
309 .append(INTEGER_STR)
310 .append(TokenFiledConst::FIELD_TOKEN_VERSION)
311 .append(INTEGER_STR)
312 .append(TokenFiledConst::FIELD_TOKEN_ATTR)
313 .append(INTEGER_STR)
314 .append(TokenFiledConst::FIELD_API_VERSION)
315 .append(INTEGER_STR)
316 .append("primary key(")
317 .append(TokenFiledConst::FIELD_TOKEN_ID)
318 .append("))");
319 return ExecuteSql(sql);
320 }
321
CreateNativeTokenInfoTable() const322 int SqliteStorage::CreateNativeTokenInfoTable() const
323 {
324 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_NATIVE_INFO);
325 if (it == dataTypeToSqlTable_.end()) {
326 return FAILURE;
327 }
328 std::string sql = "create table if not exists ";
329 sql.append(it->second.tableName_ + " (")
330 .append(TokenFiledConst::FIELD_TOKEN_ID)
331 .append(INTEGER_STR)
332 .append(TokenFiledConst::FIELD_PROCESS_NAME)
333 .append(TEXT_STR)
334 .append(TokenFiledConst::FIELD_TOKEN_VERSION)
335 .append(INTEGER_STR)
336 .append(TokenFiledConst::FIELD_TOKEN_ATTR)
337 .append(INTEGER_STR)
338 .append(TokenFiledConst::FIELD_DCAP)
339 .append(TEXT_STR)
340 .append(TokenFiledConst::FIELD_NATIVE_ACLS)
341 .append(TEXT_STR)
342 .append(TokenFiledConst::FIELD_APL)
343 .append(INTEGER_STR)
344 .append("primary key(")
345 .append(TokenFiledConst::FIELD_TOKEN_ID)
346 .append("))");
347 return ExecuteSql(sql);
348 }
349
CreatePermissionDefinitionTable() const350 int SqliteStorage::CreatePermissionDefinitionTable() const
351 {
352 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_DEF);
353 if (it == dataTypeToSqlTable_.end()) {
354 return FAILURE;
355 }
356 std::string sql = "create table if not exists ";
357 sql.append(it->second.tableName_ + " (")
358 .append(TokenFiledConst::FIELD_TOKEN_ID)
359 .append(INTEGER_STR)
360 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
361 .append(TEXT_STR)
362 .append(TokenFiledConst::FIELD_BUNDLE_NAME)
363 .append(TEXT_STR)
364 .append(TokenFiledConst::FIELD_GRANT_MODE)
365 .append(INTEGER_STR)
366 .append(TokenFiledConst::FIELD_AVAILABLE_LEVEL)
367 .append(INTEGER_STR)
368 .append(TokenFiledConst::FIELD_PROVISION_ENABLE)
369 .append(INTEGER_STR)
370 .append(TokenFiledConst::FIELD_DISTRIBUTED_SCENE_ENABLE)
371 .append(INTEGER_STR)
372 .append(TokenFiledConst::FIELD_LABEL)
373 .append(TEXT_STR)
374 .append(TokenFiledConst::FIELD_LABEL_ID)
375 .append(INTEGER_STR)
376 .append(TokenFiledConst::FIELD_DESCRIPTION)
377 .append(TEXT_STR)
378 .append(TokenFiledConst::FIELD_DESCRIPTION_ID)
379 .append(INTEGER_STR)
380 .append("primary key(")
381 .append(TokenFiledConst::FIELD_TOKEN_ID)
382 .append(",")
383 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
384 .append("))");
385 return ExecuteSql(sql);
386 }
387
CreatePermissionStateTable() const388 int SqliteStorage::CreatePermissionStateTable() const
389 {
390 auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_STATE);
391 if (it == dataTypeToSqlTable_.end()) {
392 return FAILURE;
393 }
394 std::string sql = "create table if not exists ";
395 sql.append(it->second.tableName_ + " (")
396 .append(TokenFiledConst::FIELD_TOKEN_ID)
397 .append(INTEGER_STR)
398 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
399 .append(TEXT_STR)
400 .append(TokenFiledConst::FIELD_DEVICE_ID)
401 .append(TEXT_STR)
402 .append(TokenFiledConst::FIELD_GRANT_IS_GENERAL)
403 .append(INTEGER_STR)
404 .append(TokenFiledConst::FIELD_GRANT_STATE)
405 .append(INTEGER_STR)
406 .append(TokenFiledConst::FIELD_GRANT_FLAG)
407 .append(INTEGER_STR)
408 .append("primary key(")
409 .append(TokenFiledConst::FIELD_TOKEN_ID)
410 .append(",")
411 .append(TokenFiledConst::FIELD_PERMISSION_NAME)
412 .append(",")
413 .append(TokenFiledConst::FIELD_DEVICE_ID)
414 .append("))");
415 return ExecuteSql(sql);
416 }
417 } // namespace AccessToken
418 } // namespace Security
419 } // namespace OHOS
420