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