1 /*
2 * Copyright (c) 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 "permission_used_record_db.h"
17
18 #include <cinttypes>
19 #include <mutex>
20
21 #include "accesstoken_common_log.h"
22 #include "active_change_response_info.h"
23 #include "constant.h"
24 #include "permission_used_type.h"
25 #include "privacy_field_const.h"
26 #include "time_util.h"
27
28 namespace OHOS {
29 namespace Security {
30 namespace AccessToken {
31 namespace {
32 constexpr const char* FIELD_COUNT_NUMBER = "count";
33 constexpr const char* INTEGER_STR = " integer not null,";
34 constexpr const char* CREATE_TABLE_STR = "create table if not exists ";
35 constexpr const char* WHERE_1_STR = " where 1 = 1";
36 constexpr const size_t TOKEN_ID_LENGTH = 11;
37
38 std::recursive_mutex g_instanceMutex;
39 }
40
GetInstance()41 PermissionUsedRecordDb& PermissionUsedRecordDb::GetInstance()
42 {
43 static PermissionUsedRecordDb* instance = nullptr;
44 if (instance == nullptr) {
45 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
46 if (instance == nullptr) {
47 PermissionUsedRecordDb* tmp = new (std::nothrow) PermissionUsedRecordDb();
48 instance = std::move(tmp);
49 }
50 }
51 return *instance;
52 }
53
~PermissionUsedRecordDb()54 PermissionUsedRecordDb::~PermissionUsedRecordDb()
55 {
56 Close();
57 }
58
OnCreate()59 void PermissionUsedRecordDb::OnCreate()
60 {
61 LOGI(PRI_DOMAIN, PRI_TAG, "Entry");
62 CreatePermissionRecordTable();
63 CreatePermissionUsedTypeTable();
64 CreatePermissionUsedRecordToggleStatusTable();
65 }
66
OnUpdate(int32_t version)67 void PermissionUsedRecordDb::OnUpdate(int32_t version)
68 {
69 LOGI(PRI_DOMAIN, PRI_TAG, "Entry");
70 if (version == DataBaseVersion::VERISION_1) {
71 InsertLockScreenStatusColumn();
72 InsertPermissionUsedTypeColumn();
73 CreatePermissionUsedTypeTable();
74 UpdatePermissionRecordTablePrimaryKey();
75 CreatePermissionUsedRecordToggleStatusTable();
76 } else if (version == DataBaseVersion::VERISION_2) {
77 InsertPermissionUsedTypeColumn();
78 CreatePermissionUsedTypeTable();
79 UpdatePermissionRecordTablePrimaryKey();
80 CreatePermissionUsedRecordToggleStatusTable();
81 } else if (version == DataBaseVersion::VERISION_3) {
82 UpdatePermissionRecordTablePrimaryKey();
83 CreatePermissionUsedRecordToggleStatusTable();
84 } else if (version == DataBaseVersion::VERISION_4) {
85 CreatePermissionUsedRecordToggleStatusTable();
86 }
87 }
88
PermissionUsedRecordDb()89 PermissionUsedRecordDb::PermissionUsedRecordDb() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION)
90 {
91 SqliteTable permissionRecordTable;
92 permissionRecordTable.tableName_ = PERMISSION_RECORD_TABLE;
93 permissionRecordTable.tableColumnNames_ = {
94 PrivacyFiledConst::FIELD_TOKEN_ID,
95 PrivacyFiledConst::FIELD_OP_CODE,
96 PrivacyFiledConst::FIELD_STATUS,
97 PrivacyFiledConst::FIELD_TIMESTAMP,
98 PrivacyFiledConst::FIELD_ACCESS_DURATION,
99 PrivacyFiledConst::FIELD_ACCESS_COUNT,
100 PrivacyFiledConst::FIELD_REJECT_COUNT,
101 PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS,
102 PrivacyFiledConst::FIELD_USED_TYPE
103 };
104
105 SqliteTable permissionUsedTypeTable;
106 permissionUsedTypeTable.tableName_ = PERMISSION_USED_TYPE_TABLE;
107 permissionUsedTypeTable.tableColumnNames_ = {
108 PrivacyFiledConst::FIELD_TOKEN_ID,
109 PrivacyFiledConst::FIELD_PERMISSION_CODE,
110 /**
111 * bit operation:
112 * 1 -> 001, NORMAL_TYPE
113 * 2 -> 010, PICKER_TYPE
114 * 3 -> 011, NORMAL_TYPE + PICKER_TYPE
115 * 4 -> 100, SECURITY_COMPONENT_TYPE
116 * 5 -> 101, NORMAL_TYPE + SECURITY_COMPONENT_TYPE
117 * 6 -> 110, PICKER_TYPE + SECURITY_COMPONENT_TYPE
118 * 7 -> 111, NORMAL_TYPE + PICKER_TYPE + SECURITY_COMPONENT_TYPE
119 */
120 PrivacyFiledConst::FIELD_USED_TYPE
121 };
122
123 SqliteTable permissionUsedRecordToggleStatusTable;
124 permissionUsedRecordToggleStatusTable.tableName_ = PERMISSION_USED_RECORD_TOGGLE_STATUS_TABLE;
125 permissionUsedRecordToggleStatusTable.tableColumnNames_ = {
126 PrivacyFiledConst::FIELD_USER_ID,
127 PrivacyFiledConst::FIELD_STATUS
128 };
129
130 dataTypeToSqlTable_ = {
131 {PERMISSION_RECORD, permissionRecordTable},
132 {PERMISSION_USED_TYPE, permissionUsedTypeTable},
133 {PERMISSION_USED_RECORD_TOGGLE_STATUS, permissionUsedRecordToggleStatusTable},
134 };
135 Open();
136 }
137
Add(DataType type,const std::vector<GenericValues> & values)138 int32_t PermissionUsedRecordDb::Add(DataType type, const std::vector<GenericValues>& values)
139 {
140 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
141
142 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
143 std::string prepareSql = CreateInsertPrepareSqlCmd(type);
144 if (prepareSql.empty()) {
145 LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
146 return FAILURE;
147 }
148 LOGD(PRI_DOMAIN, PRI_TAG, "Add sql is %{public}s.", prepareSql.c_str());
149
150 auto statement = Prepare(prepareSql);
151 BeginTransaction();
152 bool isAddSuccessfully = true;
153 for (const auto& value : values) {
154 std::vector<std::string> columnNames = value.GetAllKeys();
155 for (const auto& name : columnNames) {
156 statement.Bind(name, value.Get(name));
157 }
158 int32_t ret = statement.Step();
159 if (ret != Statement::State::DONE) {
160 LOGE(PRI_DOMAIN, PRI_TAG, "Failed, errorMsg: %{public}s", SpitError().c_str());
161 isAddSuccessfully = false;
162 }
163 statement.Reset();
164 }
165 if (!isAddSuccessfully) {
166 LOGE(PRI_DOMAIN, PRI_TAG, "Rollback transaction.");
167 RollbackTransaction();
168 return FAILURE;
169 }
170 LOGD(PRI_DOMAIN, PRI_TAG, "Commit transaction.");
171 CommitTransaction();
172
173 int64_t endTime = TimeUtil::GetCurrentTimestamp();
174 LOGI(PRI_DOMAIN, PRI_TAG, "Add cost %{public}" PRId64 ".", endTime - beginTime);
175
176 return SUCCESS;
177 }
178
Remove(DataType type,const GenericValues & conditions)179 int32_t PermissionUsedRecordDb::Remove(DataType type, const GenericValues& conditions)
180 {
181 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
182
183 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
184 std::vector<std::string> columnNames = conditions.GetAllKeys();
185 std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames);
186 if (prepareSql.empty()) {
187 LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
188 return FAILURE;
189 }
190 LOGD(PRI_DOMAIN, PRI_TAG, "Remove sql is %{public}s.", prepareSql.c_str());
191
192 auto statement = Prepare(prepareSql);
193 for (const auto& columnName : columnNames) {
194 statement.Bind(columnName, conditions.Get(columnName));
195 }
196 int32_t ret = statement.Step();
197
198 int64_t endTime = TimeUtil::GetCurrentTimestamp();
199 LOGI(PRI_DOMAIN, PRI_TAG, "Remove cost %{public}" PRId64 ".", endTime - beginTime);
200
201 return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
202 }
203
FindByConditions(DataType type,const std::set<int32_t> & opCodeList,const GenericValues & andConditions,std::vector<GenericValues> & results,int32_t databaseQueryCount)204 int32_t PermissionUsedRecordDb::FindByConditions(DataType type, const std::set<int32_t>& opCodeList,
205 const GenericValues& andConditions, std::vector<GenericValues>& results, int32_t databaseQueryCount)
206 {
207 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
208
209 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
210 std::vector<std::string> andColumns = andConditions.GetAllKeys();
211 int32_t tokenId = andConditions.GetInt(PrivacyFiledConst::FIELD_TOKEN_ID);
212 std::string prepareSql = CreateSelectByConditionPrepareSqlCmd(tokenId, type, opCodeList, andColumns,
213 databaseQueryCount);
214 if (prepareSql.empty()) {
215 LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
216 return FAILURE;
217 }
218 LOGD(PRI_DOMAIN, PRI_TAG, "FindByConditions sql is %{public}s.", prepareSql.c_str());
219
220 auto statement = Prepare(prepareSql);
221
222 for (const auto& columnName : andColumns) {
223 statement.Bind(columnName, andConditions.Get(columnName));
224 }
225
226 while (statement.Step() == Statement::State::ROW) {
227 int32_t columnCount = statement.GetColumnCount();
228 GenericValues value;
229 for (int32_t i = 0; i < columnCount; i++) {
230 if ((statement.GetColumnName(i) == PrivacyFiledConst::FIELD_TIMESTAMP) ||
231 (statement.GetColumnName(i) == PrivacyFiledConst::FIELD_ACCESS_DURATION)) {
232 value.Put(statement.GetColumnName(i), statement.GetValue(i, true));
233 } else {
234 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
235 }
236 }
237 results.emplace_back(value);
238 }
239
240 int64_t endTime = TimeUtil::GetCurrentTimestamp();
241 LOGI(PRI_DOMAIN, PRI_TAG, "FindByConditions cost %{public}" PRId64 ".", endTime - beginTime);
242
243 return SUCCESS;
244 }
245
Count(DataType type)246 int32_t PermissionUsedRecordDb::Count(DataType type)
247 {
248 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
249
250 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
251 GenericValues countValue;
252 std::string countSql = CreateCountPrepareSqlCmd(type);
253 LOGD(PRI_DOMAIN, PRI_TAG, "Count sql is %{public}s.", countSql.c_str());
254 auto countStatement = Prepare(countSql);
255 if (countStatement.Step() == Statement::State::ROW) {
256 int32_t column = 0;
257 countValue.Put(FIELD_COUNT_NUMBER, countStatement.GetValue(column, false));
258 }
259
260 int64_t endTime = TimeUtil::GetCurrentTimestamp();
261 LOGI(PRI_DOMAIN, PRI_TAG, "Count cost %{public}" PRId64 ".", endTime - beginTime);
262
263 return countValue.GetInt(FIELD_COUNT_NUMBER);
264 }
265
DeleteExpireRecords(DataType type,const GenericValues & andConditions)266 int32_t PermissionUsedRecordDb::DeleteExpireRecords(DataType type,
267 const GenericValues& andConditions)
268 {
269 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
270
271 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
272 std::vector<std::string> andColumns = andConditions.GetAllKeys();
273 if (!andColumns.empty()) {
274 std::string deleteExpireSql = CreateDeleteExpireRecordsPrepareSqlCmd(type, andColumns);
275 LOGD(PRI_DOMAIN, PRI_TAG, "DeleteExpireRecords sql is %{public}s.", deleteExpireSql.c_str());
276 auto deleteExpireStatement = Prepare(deleteExpireSql);
277 for (const auto& columnName : andColumns) {
278 deleteExpireStatement.Bind(columnName, andConditions.Get(columnName));
279 }
280 if (deleteExpireStatement.Step() != Statement::State::DONE) {
281 return FAILURE;
282 }
283 }
284
285 int64_t endTime = TimeUtil::GetCurrentTimestamp();
286 LOGI(PRI_DOMAIN, PRI_TAG, "DeleteExpireRecords cost %{public}" PRId64 ".", endTime - beginTime);
287
288 return SUCCESS;
289 }
290
DeleteHistoryRecordsInTables(std::vector<DataType> dateTypes,const std::unordered_set<AccessTokenID> & tokenIDList)291 int32_t PermissionUsedRecordDb::DeleteHistoryRecordsInTables(std::vector<DataType> dateTypes,
292 const std::unordered_set<AccessTokenID>& tokenIDList)
293 {
294 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
295
296 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
297 BeginTransaction();
298 for (const auto& type : dateTypes) {
299 std::string deleteHistorySql = CreateDeleteHistoryRecordsPrepareSqlCmd(type, tokenIDList);
300 LOGD(PRI_DOMAIN, PRI_TAG, "DeleteHistoryRecordsInTables sql is %{public}s.", deleteHistorySql.c_str());
301 auto deleteHistoryStatement = Prepare(deleteHistorySql);
302 if (deleteHistoryStatement.Step() != Statement::State::DONE) {
303 LOGE(PRI_DOMAIN, PRI_TAG, "Rollback transaction.");
304 RollbackTransaction();
305 return FAILURE;
306 }
307 }
308
309 LOGD(PRI_DOMAIN, PRI_TAG, "Commit transaction.");
310 CommitTransaction();
311
312 int64_t endTime = TimeUtil::GetCurrentTimestamp();
313 LOGI(PRI_DOMAIN, PRI_TAG, "DeleteHistoryRecordsInTables cost %{public}" PRId64 ".", endTime - beginTime);
314
315 return SUCCESS;
316 }
317
DeleteExcessiveRecords(DataType type,uint32_t excessiveSize)318 int32_t PermissionUsedRecordDb::DeleteExcessiveRecords(DataType type, uint32_t excessiveSize)
319 {
320 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
321
322 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
323 std::string deleteExcessiveSql = CreateDeleteExcessiveRecordsPrepareSqlCmd(type, excessiveSize);
324 LOGD(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords sql is %{public}s.", deleteExcessiveSql.c_str());
325 auto deleteExcessiveStatement = Prepare(deleteExcessiveSql);
326 if (deleteExcessiveStatement.Step() != Statement::State::DONE) {
327 return FAILURE;
328 }
329
330 int64_t endTime = TimeUtil::GetCurrentTimestamp();
331 LOGI(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords cost %{public}" PRId64 ".", endTime - beginTime);
332
333 return SUCCESS;
334 }
335
Update(DataType type,const GenericValues & modifyValue,const GenericValues & conditionValue)336 int32_t PermissionUsedRecordDb::Update(DataType type, const GenericValues& modifyValue,
337 const GenericValues& conditionValue)
338 {
339 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
340
341 std::vector<std::string> modifyNames = modifyValue.GetAllKeys();
342 std::vector<std::string> conditionNames = conditionValue.GetAllKeys();
343
344 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
345 std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyNames, conditionNames);
346 if (prepareSql.empty()) {
347 LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
348 return FAILURE;
349 }
350 LOGD(PRI_DOMAIN, PRI_TAG, "Update sql is %{public}s.", prepareSql.c_str());
351
352 auto statement = Prepare(prepareSql);
353
354 for (const auto& modifyName : modifyNames) {
355 statement.Bind(modifyName, modifyValue.Get(modifyName));
356 }
357
358 for (const auto& conditionName : conditionNames) {
359 statement.Bind(conditionName, conditionValue.Get(conditionName));
360 }
361
362 int32_t ret = statement.Step();
363 if (ret != Statement::State::DONE) {
364 LOGE(PRI_DOMAIN, PRI_TAG,
365 "Update table Type %{public}u failed, errCode is %{public}d, errMsg is %{public}s.", type, ret,
366 SpitError().c_str());
367 return FAILURE;
368 }
369
370 int64_t endTime = TimeUtil::GetCurrentTimestamp();
371 LOGI(PRI_DOMAIN, PRI_TAG, "Update cost %{public}" PRId64 ".", endTime - beginTime);
372
373 return SUCCESS;
374 }
375
Query(DataType type,const GenericValues & conditionValue,std::vector<GenericValues> & results)376 int32_t PermissionUsedRecordDb::Query(DataType type, const GenericValues& conditionValue,
377 std::vector<GenericValues>& results)
378 {
379 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
380
381 std::vector<std::string> conditionColumns = conditionValue.GetAllKeys();
382
383 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
384 std::string prepareSql = CreateQueryPrepareSqlCmd(type, conditionColumns);
385 if (prepareSql.empty()) {
386 LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid.", type);
387 return FAILURE;
388 }
389 LOGD(PRI_DOMAIN, PRI_TAG, "Query sql is %{public}s.", prepareSql.c_str());
390
391 auto statement = Prepare(prepareSql);
392 for (const auto& conditionColumn : conditionColumns) {
393 statement.Bind(conditionColumn, conditionValue.Get(conditionColumn));
394 }
395
396 while (statement.Step() == Statement::State::ROW) {
397 int32_t columnCount = statement.GetColumnCount();
398 GenericValues value;
399
400 for (int32_t i = 0; i < columnCount; i++) {
401 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
402 }
403
404 results.emplace_back(value);
405 }
406
407 int64_t endTime = TimeUtil::GetCurrentTimestamp();
408 LOGI(PRI_DOMAIN, PRI_TAG, "Query cost %{public}" PRId64 ".", endTime - beginTime);
409
410 return SUCCESS;
411 }
412
CreateInsertPrepareSqlCmd(DataType type) const413 std::string PermissionUsedRecordDb::CreateInsertPrepareSqlCmd(DataType type) const
414 {
415 auto it = dataTypeToSqlTable_.find(type);
416 if (it == dataTypeToSqlTable_.end()) {
417 return std::string();
418 }
419 std::string sql = "insert into " + it->second.tableName_ + " values(";
420 int32_t i = 1;
421 for (const auto& name : it->second.tableColumnNames_) {
422 sql.append(":" + name);
423 if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
424 sql.append(",");
425 }
426 i += 1;
427 }
428 sql.append(")");
429 return sql;
430 }
431
CreateQueryPrepareSqlCmd(DataType type,const std::vector<std::string> & conditionColumns) const432 std::string PermissionUsedRecordDb::CreateQueryPrepareSqlCmd(DataType type,
433 const std::vector<std::string>& conditionColumns) const
434 {
435 auto it = dataTypeToSqlTable_.find(type);
436 if (it == dataTypeToSqlTable_.end()) {
437 return std::string();
438 }
439 std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
440
441 for (const auto& andColumn : conditionColumns) {
442 sql.append(" and ");
443 sql.append(andColumn + "=:" + andColumn);
444 }
445
446 return sql;
447 }
448
CreateDeletePrepareSqlCmd(DataType type,const std::vector<std::string> & columnNames) const449 std::string PermissionUsedRecordDb::CreateDeletePrepareSqlCmd(
450 DataType type, const std::vector<std::string>& columnNames) const
451 {
452 auto it = dataTypeToSqlTable_.find(type);
453 if (it == dataTypeToSqlTable_.end()) {
454 return std::string();
455 }
456 std::string sql = "delete from " + it->second.tableName_ + WHERE_1_STR;
457 for (const auto& name : columnNames) {
458 sql.append(" and ");
459 sql.append(name + "=:" + name);
460 }
461 return sql;
462 }
463
CreateUpdatePrepareSqlCmd(DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const464 std::string PermissionUsedRecordDb::CreateUpdatePrepareSqlCmd(DataType type,
465 const std::vector<std::string>& modifyColumns, const std::vector<std::string>& conditionColumns) const
466 {
467 if (modifyColumns.empty()) {
468 return std::string();
469 }
470
471 auto it = dataTypeToSqlTable_.find(type);
472 if (it == dataTypeToSqlTable_.end()) {
473 return std::string();
474 }
475
476 std::string sql = "update " + it->second.tableName_ + " set ";
477 int32_t i = 1;
478 for (const auto& name : modifyColumns) {
479 sql.append(name + "=:" + name);
480 if (i < static_cast<int32_t>(modifyColumns.size())) {
481 sql.append(",");
482 }
483 i += 1;
484 }
485
486 if (!conditionColumns.empty()) {
487 sql.append(WHERE_1_STR);
488 for (const auto& columnName : conditionColumns) {
489 sql.append(" and ");
490 sql.append(columnName + "=:" + columnName);
491 }
492 }
493 return sql;
494 }
495
CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId,DataType type,const std::set<int32_t> & opCodeList,const std::vector<std::string> & andColumns,int32_t databaseQueryCount) const496 std::string PermissionUsedRecordDb::CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId, DataType type,
497 const std::set<int32_t>& opCodeList, const std::vector<std::string>& andColumns, int32_t databaseQueryCount) const
498 {
499 auto it = dataTypeToSqlTable_.find(type);
500 if (it == dataTypeToSqlTable_.end()) {
501 return std::string();
502 }
503
504 std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
505
506 for (const auto& andColName : andColumns) {
507 if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
508 sql.append(" and ");
509 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
510 sql.append(" >=:" + andColName);
511 } else if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
512 sql.append(" and ");
513 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
514 sql.append(" <=:" + andColName);
515 } else if (andColName == PrivacyFiledConst::FIELD_TOKEN_ID) {
516 if (tokenId != 0) {
517 sql.append(" and ");
518 sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
519 sql.append(" =:" + andColName);
520 }
521 } else {
522 sql.append(" and ");
523 sql.append(andColName + "=:" + andColName);
524 }
525 }
526 if (!opCodeList.empty()) {
527 sql.append(" and (");
528 for (const auto& opCode : opCodeList) {
529 if (opCode != Constant::OP_INVALID) {
530 sql.append(PrivacyFiledConst::FIELD_OP_CODE);
531 sql.append(+ " = " + std::to_string(opCode));
532 sql.append(" or ");
533 }
534 }
535 sql.append("0)");
536 }
537 sql.append(" order by timestamp desc");
538 sql.append(" limit " + std::to_string(databaseQueryCount));
539 return sql;
540 }
541
CreateCountPrepareSqlCmd(DataType type) const542 std::string PermissionUsedRecordDb::CreateCountPrepareSqlCmd(DataType type) const
543 {
544 auto it = dataTypeToSqlTable_.find(type);
545 if (it == dataTypeToSqlTable_.end()) {
546 return std::string();
547 }
548 std::string sql = "select count(*) from " + it->second.tableName_;
549 return sql;
550 }
551
CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,const std::vector<std::string> & andColumns) const552 std::string PermissionUsedRecordDb::CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,
553 const std::vector<std::string>& andColumns) const
554 {
555 auto it = dataTypeToSqlTable_.find(type);
556 if (it == dataTypeToSqlTable_.end()) {
557 return std::string();
558 }
559 std::string sql = "delete from " + it->second.tableName_ + " where ";
560 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
561 sql.append(" in (select ");
562 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
563 sql.append(" from " + it->second.tableName_ + WHERE_1_STR);
564 for (const auto& name : andColumns) {
565 if (name == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
566 sql.append(" and ");
567 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
568 sql.append(" >=:" + name);
569 } else if (name == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
570 sql.append(" and ");
571 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
572 sql.append(" <=:" + name);
573 } else {
574 sql.append(" and ");
575 sql.append(name + "=:" + name);
576 }
577 }
578 sql.append(" )");
579 return sql;
580 }
581
CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,const std::unordered_set<AccessTokenID> & tokenIDList) const582 std::string PermissionUsedRecordDb::CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,
583 const std::unordered_set<AccessTokenID>& tokenIDList) const
584 {
585 auto it = dataTypeToSqlTable_.find(type);
586 if (it == dataTypeToSqlTable_.end()) {
587 return std::string();
588 }
589 std::string sql = "delete from " + it->second.tableName_ + " where ";
590 sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
591 sql.append(" in ( ");
592
593 size_t sqlLen = sql.size();
594 sqlLen += TOKEN_ID_LENGTH * tokenIDList.size();
595 sql.reserve(sqlLen);
596
597 for (auto token = tokenIDList.begin(); token != tokenIDList.end(); ++token) {
598 sql.append(std::to_string(*token));
599 if (std::next(token) != tokenIDList.end()) {
600 sql.append(", ");
601 }
602 }
603 sql.append(" )");
604 return sql;
605 }
606
CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,uint32_t excessiveSize) const607 std::string PermissionUsedRecordDb::CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,
608 uint32_t excessiveSize) const
609 {
610 auto it = dataTypeToSqlTable_.find(type);
611 if (it == dataTypeToSqlTable_.end()) {
612 return std::string();
613 }
614 std::string sql = "delete from " + it->second.tableName_ + " where ";
615 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
616 sql.append(" in (select ");
617 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
618 sql.append(" from " + it->second.tableName_ + " order by ");
619 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
620 sql.append(" limit ");
621 sql.append(std::to_string(excessiveSize) + " )");
622 return sql;
623 }
624
CreatePermissionRecordTable() const625 int32_t PermissionUsedRecordDb::CreatePermissionRecordTable() const
626 {
627 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
628 if (it == dataTypeToSqlTable_.end()) {
629 return FAILURE;
630 }
631 std::string sql = CREATE_TABLE_STR;
632 sql.append(it->second.tableName_ + " (")
633 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
634 .append(INTEGER_STR)
635 .append(PrivacyFiledConst::FIELD_OP_CODE)
636 .append(INTEGER_STR)
637 .append(PrivacyFiledConst::FIELD_STATUS)
638 .append(INTEGER_STR)
639 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
640 .append(INTEGER_STR)
641 .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
642 .append(INTEGER_STR)
643 .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
644 .append(INTEGER_STR)
645 .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
646 .append(INTEGER_STR)
647 .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
648 .append(INTEGER_STR)
649 .append(PrivacyFiledConst::FIELD_USED_TYPE)
650 .append(INTEGER_STR)
651 .append("primary key(")
652 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
653 .append(",")
654 .append(PrivacyFiledConst::FIELD_OP_CODE)
655 .append(",")
656 .append(PrivacyFiledConst::FIELD_STATUS)
657 .append(",")
658 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
659 .append(",")
660 .append(PrivacyFiledConst::FIELD_USED_TYPE)
661 .append("))");
662 return ExecuteSql(sql);
663 }
664
CreatePermissionUsedTypeTable() const665 int32_t PermissionUsedRecordDb::CreatePermissionUsedTypeTable() const
666 {
667 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_TYPE);
668 if (it == dataTypeToSqlTable_.end()) {
669 return FAILURE;
670 }
671 std::string sql = CREATE_TABLE_STR;
672 sql.append(it->second.tableName_ + " (")
673 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
674 .append(INTEGER_STR)
675 .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
676 .append(INTEGER_STR)
677 .append(PrivacyFiledConst::FIELD_USED_TYPE)
678 .append(INTEGER_STR)
679 .append("primary key(")
680 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
681 .append(",")
682 .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
683 .append("))");
684 return ExecuteSql(sql);
685 }
686
CreatePermissionUsedRecordToggleStatusTable() const687 int32_t PermissionUsedRecordDb::CreatePermissionUsedRecordToggleStatusTable() const
688 {
689 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_RECORD_TOGGLE_STATUS);
690 if (it == dataTypeToSqlTable_.end()) {
691 return FAILURE;
692 }
693 std::string sql = CREATE_TABLE_STR;
694 sql.append(it->second.tableName_ + " (")
695 .append(PrivacyFiledConst::FIELD_USER_ID)
696 .append(INTEGER_STR)
697 .append(PrivacyFiledConst::FIELD_STATUS)
698 .append(INTEGER_STR)
699 .append("primary key(")
700 .append(PrivacyFiledConst::FIELD_USER_ID)
701 .append("))");
702 return ExecuteSql(sql);
703 }
704
InsertLockScreenStatusColumn() const705 int32_t PermissionUsedRecordDb::InsertLockScreenStatusColumn() const
706 {
707 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
708 if (it == dataTypeToSqlTable_.end()) {
709 return FAILURE;
710 }
711 std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
712 PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS + "=" +
713 std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED);
714 int32_t checkResult = ExecuteSql(checkSql);
715 LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
716 if (checkResult != -1) {
717 return SUCCESS;
718 }
719
720 std::string sql = "alter table ";
721 sql.append(it->second.tableName_ + " add column ")
722 .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
723 .append(" integer default ")
724 .append(std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED));
725 int32_t insertResult = ExecuteSql(sql);
726 LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
727 return insertResult;
728 }
729
InsertPermissionUsedTypeColumn() const730 int32_t PermissionUsedRecordDb::InsertPermissionUsedTypeColumn() const
731 {
732 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
733 if (it == dataTypeToSqlTable_.end()) {
734 return FAILURE;
735 }
736 std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
737 PrivacyFiledConst::FIELD_USED_TYPE + "=" +
738 std::to_string(PermissionUsedType::NORMAL_TYPE);
739 int32_t checkResult = ExecuteSql(checkSql);
740 LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
741 if (checkResult != -1) {
742 return SUCCESS;
743 }
744
745 std::string sql = "alter table ";
746 sql.append(it->second.tableName_ + " add column ")
747 .append(PrivacyFiledConst::FIELD_USED_TYPE)
748 .append(" integer default ")
749 .append(std::to_string(PermissionUsedType::NORMAL_TYPE));
750 int32_t insertResult = ExecuteSql(sql);
751 LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
752 return insertResult;
753 }
754
CreateNewPermissionRecordTable(std::string & newTableName,std::string & createNewSql)755 static void CreateNewPermissionRecordTable(std::string& newTableName, std::string& createNewSql)
756 {
757 createNewSql = CREATE_TABLE_STR;
758 createNewSql.append(newTableName + " (")
759 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
760 .append(INTEGER_STR)
761 .append(PrivacyFiledConst::FIELD_OP_CODE)
762 .append(INTEGER_STR)
763 .append(PrivacyFiledConst::FIELD_STATUS)
764 .append(INTEGER_STR)
765 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
766 .append(INTEGER_STR)
767 .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
768 .append(INTEGER_STR)
769 .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
770 .append(INTEGER_STR)
771 .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
772 .append(INTEGER_STR)
773 .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
774 .append(INTEGER_STR)
775 .append(PrivacyFiledConst::FIELD_USED_TYPE)
776 .append(INTEGER_STR)
777 .append("primary key(")
778 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
779 .append(",")
780 .append(PrivacyFiledConst::FIELD_OP_CODE)
781 .append(",")
782 .append(PrivacyFiledConst::FIELD_STATUS)
783 .append(",")
784 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
785 .append(",")
786 .append(PrivacyFiledConst::FIELD_USED_TYPE)
787 .append("))");
788 }
789
UpdatePermissionRecordTablePrimaryKey() const790 int32_t PermissionUsedRecordDb::UpdatePermissionRecordTablePrimaryKey() const
791 {
792 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
793 if (it == dataTypeToSqlTable_.end()) {
794 return FAILURE;
795 }
796
797 std::string tableName = it->second.tableName_;
798 std::string newTableName = it->second.tableName_ + "_new";
799 std::string createNewSql;
800 CreateNewPermissionRecordTable(newTableName, createNewSql);
801
802 BeginTransaction();
803
804 int32_t createNewRes = ExecuteSql(createNewSql); // 1、create new table with new primary key
805 if (createNewRes != 0) {
806 LOGE(PRI_DOMAIN, PRI_TAG, "Create new table failed, errCode is %{public}d, errMsg is %{public}s.",
807 createNewRes, SpitError().c_str());
808 return FAILURE;
809 }
810
811 std::string copyDataSql = "insert into " + newTableName + " select * from " + tableName;
812 int32_t copyDataRes = ExecuteSql(copyDataSql); // 2、copy data from old table to new table
813 if (copyDataRes != 0) {
814 LOGE(PRI_DOMAIN, PRI_TAG, "Copy data from old table failed, errCode is %{public}d, errMsg is %{public}s.",
815 copyDataRes, SpitError().c_str());
816 RollbackTransaction();
817 return FAILURE;
818 }
819
820 std::string dropOldSql = "drop table " + tableName;
821 int32_t dropOldRes = ExecuteSql(dropOldSql); // 3、drop old table
822 if (dropOldRes != 0) {
823 LOGE(PRI_DOMAIN, PRI_TAG, "Drop old table failed, errCode is %{public}d, errMsg is %{public}s.",
824 dropOldRes, SpitError().c_str());
825 RollbackTransaction();
826 return FAILURE;
827 }
828
829 std::string renameSql = "alter table " + newTableName + " rename to " + tableName;
830 int32_t renameRes = ExecuteSql(renameSql); // 4、rename new table to old
831 if (renameRes != 0) {
832 LOGE(PRI_DOMAIN, PRI_TAG, "Rename table failed, errCode is %{public}d, errMsg is %{public}s.",
833 renameRes, SpitError().c_str());
834 RollbackTransaction();
835 return FAILURE;
836 }
837
838 CommitTransaction();
839
840 return SUCCESS;
841 }
842 } // namespace AccessToken
843 } // namespace Security
844 } // namespace OHOS
845