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