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 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 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
295 BeginTransaction();
296 for (const auto& type : dateTypes) {
297 std::string deleteHistorySql = CreateDeleteHistoryRecordsPrepareSqlCmd(type, tokenIDList);
298 auto deleteHistoryStatement = Prepare(deleteHistorySql);
299 if (deleteHistoryStatement.Step() != Statement::State::DONE) {
300 LOGE(PRI_DOMAIN, PRI_TAG, "Rollback transaction.");
301 RollbackTransaction();
302 return FAILURE;
303 }
304 }
305
306 LOGD(PRI_DOMAIN, PRI_TAG, "Commit transaction.");
307 CommitTransaction();
308
309 return SUCCESS;
310 }
311
DeleteExcessiveRecords(DataType type,uint32_t excessiveSize)312 int32_t PermissionUsedRecordDb::DeleteExcessiveRecords(DataType type, uint32_t excessiveSize)
313 {
314 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
315
316 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
317 std::string deleteExcessiveSql = CreateDeleteExcessiveRecordsPrepareSqlCmd(type, excessiveSize);
318 LOGD(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords sql is %{public}s.", deleteExcessiveSql.c_str());
319 auto deleteExcessiveStatement = Prepare(deleteExcessiveSql);
320 if (deleteExcessiveStatement.Step() != Statement::State::DONE) {
321 return FAILURE;
322 }
323
324 int64_t endTime = TimeUtil::GetCurrentTimestamp();
325 LOGI(PRI_DOMAIN, PRI_TAG, "DeleteExcessiveRecords cost %{public}" PRId64 ".", endTime - beginTime);
326
327 return SUCCESS;
328 }
329
Update(DataType type,const GenericValues & modifyValue,const GenericValues & conditionValue)330 int32_t PermissionUsedRecordDb::Update(DataType type, const GenericValues& modifyValue,
331 const GenericValues& conditionValue)
332 {
333 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
334
335 std::vector<std::string> modifyNames = modifyValue.GetAllKeys();
336 std::vector<std::string> conditionNames = conditionValue.GetAllKeys();
337
338 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
339 std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyNames, conditionNames);
340 if (prepareSql.empty()) {
341 LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid", type);
342 return FAILURE;
343 }
344 LOGD(PRI_DOMAIN, PRI_TAG, "Update sql is %{public}s.", prepareSql.c_str());
345
346 auto statement = Prepare(prepareSql);
347
348 for (const auto& modifyName : modifyNames) {
349 statement.Bind(modifyName, modifyValue.Get(modifyName));
350 }
351
352 for (const auto& conditionName : conditionNames) {
353 statement.Bind(conditionName, conditionValue.Get(conditionName));
354 }
355
356 int32_t ret = statement.Step();
357 if (ret != Statement::State::DONE) {
358 LOGE(PRI_DOMAIN, PRI_TAG,
359 "Update table Type %{public}u failed, errCode is %{public}d, errMsg is %{public}s.", type, ret,
360 SpitError().c_str());
361 return FAILURE;
362 }
363
364 int64_t endTime = TimeUtil::GetCurrentTimestamp();
365 LOGI(PRI_DOMAIN, PRI_TAG, "Update cost %{public}" PRId64 ".", endTime - beginTime);
366
367 return SUCCESS;
368 }
369
Query(DataType type,const GenericValues & conditionValue,std::vector<GenericValues> & results)370 int32_t PermissionUsedRecordDb::Query(DataType type, const GenericValues& conditionValue,
371 std::vector<GenericValues>& results)
372 {
373 int64_t beginTime = TimeUtil::GetCurrentTimestamp();
374
375 std::vector<std::string> conditionColumns = conditionValue.GetAllKeys();
376
377 OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
378 std::string prepareSql = CreateQueryPrepareSqlCmd(type, conditionColumns);
379 if (prepareSql.empty()) {
380 LOGE(PRI_DOMAIN, PRI_TAG, "Type %{public}u invalid.", type);
381 return FAILURE;
382 }
383 LOGD(PRI_DOMAIN, PRI_TAG, "Query sql is %{public}s.", prepareSql.c_str());
384
385 auto statement = Prepare(prepareSql);
386 for (const auto& conditionColumn : conditionColumns) {
387 statement.Bind(conditionColumn, conditionValue.Get(conditionColumn));
388 }
389
390 while (statement.Step() == Statement::State::ROW) {
391 int32_t columnCount = statement.GetColumnCount();
392 GenericValues value;
393
394 for (int32_t i = 0; i < columnCount; i++) {
395 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
396 }
397
398 results.emplace_back(value);
399 }
400
401 int64_t endTime = TimeUtil::GetCurrentTimestamp();
402 LOGI(PRI_DOMAIN, PRI_TAG, "Query cost %{public}" PRId64 ".", endTime - beginTime);
403
404 return SUCCESS;
405 }
406
CreateInsertPrepareSqlCmd(DataType type) const407 std::string PermissionUsedRecordDb::CreateInsertPrepareSqlCmd(DataType type) const
408 {
409 auto it = dataTypeToSqlTable_.find(type);
410 if (it == dataTypeToSqlTable_.end()) {
411 return std::string();
412 }
413 std::string sql = "insert into " + it->second.tableName_ + " values(";
414 int32_t i = 1;
415 for (const auto& name : it->second.tableColumnNames_) {
416 sql.append(":" + name);
417 if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
418 sql.append(",");
419 }
420 i += 1;
421 }
422 sql.append(")");
423 return sql;
424 }
425
CreateQueryPrepareSqlCmd(DataType type,const std::vector<std::string> & conditionColumns) const426 std::string PermissionUsedRecordDb::CreateQueryPrepareSqlCmd(DataType type,
427 const std::vector<std::string>& conditionColumns) const
428 {
429 auto it = dataTypeToSqlTable_.find(type);
430 if (it == dataTypeToSqlTable_.end()) {
431 return std::string();
432 }
433 std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
434
435 for (const auto& andColumn : conditionColumns) {
436 sql.append(" and ");
437 sql.append(andColumn + "=:" + andColumn);
438 }
439
440 return sql;
441 }
442
CreateDeletePrepareSqlCmd(DataType type,const std::vector<std::string> & columnNames) const443 std::string PermissionUsedRecordDb::CreateDeletePrepareSqlCmd(
444 DataType type, const std::vector<std::string>& columnNames) const
445 {
446 auto it = dataTypeToSqlTable_.find(type);
447 if (it == dataTypeToSqlTable_.end()) {
448 return std::string();
449 }
450 std::string sql = "delete from " + it->second.tableName_ + WHERE_1_STR;
451 for (const auto& name : columnNames) {
452 sql.append(" and ");
453 sql.append(name + "=:" + name);
454 }
455 return sql;
456 }
457
CreateUpdatePrepareSqlCmd(DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const458 std::string PermissionUsedRecordDb::CreateUpdatePrepareSqlCmd(DataType type,
459 const std::vector<std::string>& modifyColumns, const std::vector<std::string>& conditionColumns) const
460 {
461 if (modifyColumns.empty()) {
462 return std::string();
463 }
464
465 auto it = dataTypeToSqlTable_.find(type);
466 if (it == dataTypeToSqlTable_.end()) {
467 return std::string();
468 }
469
470 std::string sql = "update " + it->second.tableName_ + " set ";
471 int32_t i = 1;
472 for (const auto& name : modifyColumns) {
473 sql.append(name + "=:" + name);
474 if (i < static_cast<int32_t>(modifyColumns.size())) {
475 sql.append(",");
476 }
477 i += 1;
478 }
479
480 if (!conditionColumns.empty()) {
481 sql.append(WHERE_1_STR);
482 for (const auto& columnName : conditionColumns) {
483 sql.append(" and ");
484 sql.append(columnName + "=:" + columnName);
485 }
486 }
487 return sql;
488 }
489
CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId,DataType type,const std::set<int32_t> & opCodeList,const std::vector<std::string> & andColumns,int32_t databaseQueryCount) const490 std::string PermissionUsedRecordDb::CreateSelectByConditionPrepareSqlCmd(const int32_t tokenId, DataType type,
491 const std::set<int32_t>& opCodeList, const std::vector<std::string>& andColumns, int32_t databaseQueryCount) const
492 {
493 auto it = dataTypeToSqlTable_.find(type);
494 if (it == dataTypeToSqlTable_.end()) {
495 return std::string();
496 }
497
498 std::string sql = "select * from " + it->second.tableName_ + WHERE_1_STR;
499
500 for (const auto& andColName : andColumns) {
501 if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
502 sql.append(" and ");
503 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
504 sql.append(" >=:" + andColName);
505 } else if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
506 sql.append(" and ");
507 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
508 sql.append(" <=:" + andColName);
509 } else if (andColName == PrivacyFiledConst::FIELD_TOKEN_ID) {
510 if (tokenId != 0) {
511 sql.append(" and ");
512 sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
513 sql.append(" =:" + andColName);
514 }
515 } else {
516 sql.append(" and ");
517 sql.append(andColName + "=:" + andColName);
518 }
519 }
520 if (!opCodeList.empty()) {
521 sql.append(" and (");
522 for (const auto& opCode : opCodeList) {
523 if (opCode != Constant::OP_INVALID) {
524 sql.append(PrivacyFiledConst::FIELD_OP_CODE);
525 sql.append(+ " = " + std::to_string(opCode));
526 sql.append(" or ");
527 }
528 }
529 sql.append("0)");
530 }
531 sql.append(" order by timestamp desc");
532 sql.append(" limit " + std::to_string(databaseQueryCount));
533 return sql;
534 }
535
CreateCountPrepareSqlCmd(DataType type) const536 std::string PermissionUsedRecordDb::CreateCountPrepareSqlCmd(DataType type) const
537 {
538 auto it = dataTypeToSqlTable_.find(type);
539 if (it == dataTypeToSqlTable_.end()) {
540 return std::string();
541 }
542 std::string sql = "select count(*) from " + it->second.tableName_;
543 return sql;
544 }
545
CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,const std::vector<std::string> & andColumns) const546 std::string PermissionUsedRecordDb::CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,
547 const std::vector<std::string>& andColumns) const
548 {
549 auto it = dataTypeToSqlTable_.find(type);
550 if (it == dataTypeToSqlTable_.end()) {
551 return std::string();
552 }
553 std::string sql = "delete from " + it->second.tableName_ + " where ";
554 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
555 sql.append(" in (select ");
556 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
557 sql.append(" from " + it->second.tableName_ + WHERE_1_STR);
558 for (const auto& name : andColumns) {
559 if (name == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
560 sql.append(" and ");
561 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
562 sql.append(" >=:" + name);
563 } else if (name == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
564 sql.append(" and ");
565 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
566 sql.append(" <=:" + name);
567 } else {
568 sql.append(" and ");
569 sql.append(name + "=:" + name);
570 }
571 }
572 sql.append(" )");
573 return sql;
574 }
575
CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,const std::unordered_set<AccessTokenID> & tokenIDList) const576 std::string PermissionUsedRecordDb::CreateDeleteHistoryRecordsPrepareSqlCmd(DataType type,
577 const std::unordered_set<AccessTokenID>& tokenIDList) const
578 {
579 auto it = dataTypeToSqlTable_.find(type);
580 if (it == dataTypeToSqlTable_.end()) {
581 return std::string();
582 }
583 std::string sql = "delete from " + it->second.tableName_ + " where ";
584 sql.append(PrivacyFiledConst::FIELD_TOKEN_ID);
585 sql.append(" in ( ");
586
587 size_t sqlLen = sql.size();
588 sqlLen += TOKEN_ID_LENGTH * tokenIDList.size();
589 sql.reserve(sqlLen);
590
591 for (auto token = tokenIDList.begin(); token != tokenIDList.end(); ++token) {
592 sql.append(std::to_string(*token));
593 if (std::next(token) != tokenIDList.end()) {
594 sql.append(", ");
595 }
596 }
597 sql.append(" )");
598 return sql;
599 }
600
CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,uint32_t excessiveSize) const601 std::string PermissionUsedRecordDb::CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,
602 uint32_t excessiveSize) const
603 {
604 auto it = dataTypeToSqlTable_.find(type);
605 if (it == dataTypeToSqlTable_.end()) {
606 return std::string();
607 }
608 std::string sql = "delete from " + it->second.tableName_ + " where ";
609 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
610 sql.append(" in (select ");
611 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
612 sql.append(" from " + it->second.tableName_ + " order by ");
613 sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
614 sql.append(" limit ");
615 sql.append(std::to_string(excessiveSize) + " )");
616 return sql;
617 }
618
CreatePermissionRecordTable() const619 int32_t PermissionUsedRecordDb::CreatePermissionRecordTable() const
620 {
621 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
622 if (it == dataTypeToSqlTable_.end()) {
623 return FAILURE;
624 }
625 std::string sql = CREATE_TABLE_STR;
626 sql.append(it->second.tableName_ + " (")
627 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
628 .append(INTEGER_STR)
629 .append(PrivacyFiledConst::FIELD_OP_CODE)
630 .append(INTEGER_STR)
631 .append(PrivacyFiledConst::FIELD_STATUS)
632 .append(INTEGER_STR)
633 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
634 .append(INTEGER_STR)
635 .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
636 .append(INTEGER_STR)
637 .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
638 .append(INTEGER_STR)
639 .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
640 .append(INTEGER_STR)
641 .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
642 .append(INTEGER_STR)
643 .append(PrivacyFiledConst::FIELD_USED_TYPE)
644 .append(INTEGER_STR)
645 .append("primary key(")
646 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
647 .append(",")
648 .append(PrivacyFiledConst::FIELD_OP_CODE)
649 .append(",")
650 .append(PrivacyFiledConst::FIELD_STATUS)
651 .append(",")
652 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
653 .append(",")
654 .append(PrivacyFiledConst::FIELD_USED_TYPE)
655 .append("))");
656 return ExecuteSql(sql);
657 }
658
CreatePermissionUsedTypeTable() const659 int32_t PermissionUsedRecordDb::CreatePermissionUsedTypeTable() const
660 {
661 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_TYPE);
662 if (it == dataTypeToSqlTable_.end()) {
663 return FAILURE;
664 }
665 std::string sql = CREATE_TABLE_STR;
666 sql.append(it->second.tableName_ + " (")
667 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
668 .append(INTEGER_STR)
669 .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
670 .append(INTEGER_STR)
671 .append(PrivacyFiledConst::FIELD_USED_TYPE)
672 .append(INTEGER_STR)
673 .append("primary key(")
674 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
675 .append(",")
676 .append(PrivacyFiledConst::FIELD_PERMISSION_CODE)
677 .append("))");
678 return ExecuteSql(sql);
679 }
680
CreatePermissionUsedRecordToggleStatusTable() const681 int32_t PermissionUsedRecordDb::CreatePermissionUsedRecordToggleStatusTable() const
682 {
683 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_USED_RECORD_TOGGLE_STATUS);
684 if (it == dataTypeToSqlTable_.end()) {
685 return FAILURE;
686 }
687 std::string sql = CREATE_TABLE_STR;
688 sql.append(it->second.tableName_ + " (")
689 .append(PrivacyFiledConst::FIELD_USER_ID)
690 .append(INTEGER_STR)
691 .append(PrivacyFiledConst::FIELD_STATUS)
692 .append(INTEGER_STR)
693 .append("primary key(")
694 .append(PrivacyFiledConst::FIELD_USER_ID)
695 .append("))");
696 return ExecuteSql(sql);
697 }
698
InsertLockScreenStatusColumn() const699 int32_t PermissionUsedRecordDb::InsertLockScreenStatusColumn() const
700 {
701 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
702 if (it == dataTypeToSqlTable_.end()) {
703 return FAILURE;
704 }
705 std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
706 PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS + "=" +
707 std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED);
708 int32_t checkResult = ExecuteSql(checkSql);
709 LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
710 if (checkResult != -1) {
711 return SUCCESS;
712 }
713
714 std::string sql = "alter table ";
715 sql.append(it->second.tableName_ + " add column ")
716 .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
717 .append(" integer default ")
718 .append(std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED));
719 int32_t insertResult = ExecuteSql(sql);
720 LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
721 return insertResult;
722 }
723
InsertPermissionUsedTypeColumn() const724 int32_t PermissionUsedRecordDb::InsertPermissionUsedTypeColumn() const
725 {
726 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
727 if (it == dataTypeToSqlTable_.end()) {
728 return FAILURE;
729 }
730 std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
731 PrivacyFiledConst::FIELD_USED_TYPE + "=" +
732 std::to_string(PermissionUsedType::NORMAL_TYPE);
733 int32_t checkResult = ExecuteSql(checkSql);
734 LOGI(PRI_DOMAIN, PRI_TAG, "Check result:%{public}d", checkResult);
735 if (checkResult != -1) {
736 return SUCCESS;
737 }
738
739 std::string sql = "alter table ";
740 sql.append(it->second.tableName_ + " add column ")
741 .append(PrivacyFiledConst::FIELD_USED_TYPE)
742 .append(" integer default ")
743 .append(std::to_string(PermissionUsedType::NORMAL_TYPE));
744 int32_t insertResult = ExecuteSql(sql);
745 LOGI(PRI_DOMAIN, PRI_TAG, "Insert column result:%{public}d", insertResult);
746 return insertResult;
747 }
748
CreateNewPermissionRecordTable(std::string & newTableName,std::string & createNewSql)749 static void CreateNewPermissionRecordTable(std::string& newTableName, std::string& createNewSql)
750 {
751 createNewSql = CREATE_TABLE_STR;
752 createNewSql.append(newTableName + " (")
753 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
754 .append(INTEGER_STR)
755 .append(PrivacyFiledConst::FIELD_OP_CODE)
756 .append(INTEGER_STR)
757 .append(PrivacyFiledConst::FIELD_STATUS)
758 .append(INTEGER_STR)
759 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
760 .append(INTEGER_STR)
761 .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
762 .append(INTEGER_STR)
763 .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
764 .append(INTEGER_STR)
765 .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
766 .append(INTEGER_STR)
767 .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
768 .append(INTEGER_STR)
769 .append(PrivacyFiledConst::FIELD_USED_TYPE)
770 .append(INTEGER_STR)
771 .append("primary key(")
772 .append(PrivacyFiledConst::FIELD_TOKEN_ID)
773 .append(",")
774 .append(PrivacyFiledConst::FIELD_OP_CODE)
775 .append(",")
776 .append(PrivacyFiledConst::FIELD_STATUS)
777 .append(",")
778 .append(PrivacyFiledConst::FIELD_TIMESTAMP)
779 .append(",")
780 .append(PrivacyFiledConst::FIELD_USED_TYPE)
781 .append("))");
782 }
783
UpdatePermissionRecordTablePrimaryKey() const784 int32_t PermissionUsedRecordDb::UpdatePermissionRecordTablePrimaryKey() const
785 {
786 auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
787 if (it == dataTypeToSqlTable_.end()) {
788 return FAILURE;
789 }
790
791 std::string tableName = it->second.tableName_;
792 std::string newTableName = it->second.tableName_ + "_new";
793 std::string createNewSql;
794 CreateNewPermissionRecordTable(newTableName, createNewSql);
795
796 BeginTransaction();
797
798 int32_t createNewRes = ExecuteSql(createNewSql); // 1、create new table with new primary key
799 if (createNewRes != 0) {
800 LOGE(PRI_DOMAIN, PRI_TAG, "Create new table failed, errCode is %{public}d, errMsg is %{public}s.",
801 createNewRes, SpitError().c_str());
802 return FAILURE;
803 }
804
805 std::string copyDataSql = "insert into " + newTableName + " select * from " + tableName;
806 int32_t copyDataRes = ExecuteSql(copyDataSql); // 2、copy data from old table to new table
807 if (copyDataRes != 0) {
808 LOGE(PRI_DOMAIN, PRI_TAG, "Copy data from old table failed, errCode is %{public}d, errMsg is %{public}s.",
809 copyDataRes, SpitError().c_str());
810 RollbackTransaction();
811 return FAILURE;
812 }
813
814 std::string dropOldSql = "drop table " + tableName;
815 int32_t dropOldRes = ExecuteSql(dropOldSql); // 3、drop old table
816 if (dropOldRes != 0) {
817 LOGE(PRI_DOMAIN, PRI_TAG, "Drop old table failed, errCode is %{public}d, errMsg is %{public}s.",
818 dropOldRes, SpitError().c_str());
819 RollbackTransaction();
820 return FAILURE;
821 }
822
823 std::string renameSql = "alter table " + newTableName + " rename to " + tableName;
824 int32_t renameRes = ExecuteSql(renameSql); // 4、rename new table to old
825 if (renameRes != 0) {
826 LOGE(PRI_DOMAIN, PRI_TAG, "Rename table failed, errCode is %{public}d, errMsg is %{public}s.",
827 renameRes, SpitError().c_str());
828 RollbackTransaction();
829 return FAILURE;
830 }
831
832 CommitTransaction();
833
834 return SUCCESS;
835 }
836 } // namespace AccessToken
837 } // namespace Security
838 } // namespace OHOS
839