• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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