• 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 "accesstoken_log.h"
19 #include "constant.h"
20 #include "privacy_field_const.h"
21 #include "active_change_response_info.h"
22 
23 namespace OHOS {
24 namespace Security {
25 namespace AccessToken {
26 namespace {
27 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
28     LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PermissionUsedRecordDb"
29 };
30 static const std::string FIELD_COUNT_NUMBER = "count";
31 static const std::string INTEGER_STR = " integer not null,";
32 }
33 
GetInstance()34 PermissionUsedRecordDb& PermissionUsedRecordDb::GetInstance()
35 {
36     static PermissionUsedRecordDb instance;
37     return instance;
38 }
39 
~PermissionUsedRecordDb()40 PermissionUsedRecordDb::~PermissionUsedRecordDb()
41 {
42     Close();
43 }
44 
OnCreate()45 void PermissionUsedRecordDb::OnCreate()
46 {
47     ACCESSTOKEN_LOG_INFO(LABEL, "Entry");
48     CreatePermissionRecordTable();
49 }
50 
OnUpdate()51 void PermissionUsedRecordDb::OnUpdate()
52 {
53     ACCESSTOKEN_LOG_INFO(LABEL, "Entry");
54     InsertLockScreenStatusColumn();
55 }
56 
PermissionUsedRecordDb()57 PermissionUsedRecordDb::PermissionUsedRecordDb() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION)
58 {
59     SqliteTable permissionRecordTable;
60     permissionRecordTable.tableName_ = PERMISSION_RECORD_TABLE;
61     permissionRecordTable.tableColumnNames_ = {
62         PrivacyFiledConst::FIELD_TOKEN_ID,
63         PrivacyFiledConst::FIELD_OP_CODE,
64         PrivacyFiledConst::FIELD_STATUS,
65         PrivacyFiledConst::FIELD_TIMESTAMP,
66         PrivacyFiledConst::FIELD_ACCESS_DURATION,
67         PrivacyFiledConst::FIELD_ACCESS_COUNT,
68         PrivacyFiledConst::FIELD_REJECT_COUNT,
69         PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS
70     };
71 
72     dataTypeToSqlTable_ = {
73         {PERMISSION_RECORD, permissionRecordTable},
74     };
75     Open();
76 }
77 
Add(DataType type,const std::vector<GenericValues> & values)78 int32_t PermissionUsedRecordDb::Add(DataType type, const std::vector<GenericValues>& values)
79 {
80     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
81     std::string prepareSql = CreateInsertPrepareSqlCmd(type);
82     auto statement = Prepare(prepareSql);
83     BeginTransaction();
84     bool isAddSuccessfully = true;
85     for (const auto& value : values) {
86         std::vector<std::string> columnNames = value.GetAllKeys();
87         for (const auto& name : columnNames) {
88             statement.Bind(name, value.Get(name));
89         }
90         int32_t ret = statement.Step();
91         if (ret != Statement::State::DONE) {
92             ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", SpitError().c_str());
93             isAddSuccessfully = false;
94         }
95         statement.Reset();
96     }
97     if (!isAddSuccessfully) {
98         ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction.");
99         RollbackTransaction();
100         return FAILURE;
101     }
102     ACCESSTOKEN_LOG_DEBUG(LABEL, "commit transaction.");
103     CommitTransaction();
104     return SUCCESS;
105 }
106 
Remove(DataType type,const GenericValues & conditions)107 int32_t PermissionUsedRecordDb::Remove(DataType type, const GenericValues& conditions)
108 {
109     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
110     std::vector<std::string> columnNames = conditions.GetAllKeys();
111     std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames);
112     auto statement = Prepare(prepareSql);
113     for (const auto& columnName : columnNames) {
114         statement.Bind(columnName, conditions.Get(columnName));
115     }
116     int32_t ret = statement.Step();
117     return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
118 }
119 
FindByConditions(DataType type,const std::set<int32_t> & opCodeList,const GenericValues & andConditions,std::vector<GenericValues> & results,int32_t databaseQueryCount)120 int32_t PermissionUsedRecordDb::FindByConditions(DataType type, const std::set<int32_t>& opCodeList,
121     const GenericValues& andConditions, std::vector<GenericValues>& results, int32_t databaseQueryCount)
122 {
123     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
124     std::vector<std::string> andColumns = andConditions.GetAllKeys();
125     std::string prepareSql = CreateSelectByConditionPrepareSqlCmd(type, opCodeList, andColumns, databaseQueryCount);
126 
127     auto statement = Prepare(prepareSql);
128 
129     for (const auto& columnName : andColumns) {
130         statement.Bind(columnName, andConditions.Get(columnName));
131     }
132 
133     while (statement.Step() == Statement::State::ROW) {
134         int32_t columnCount = statement.GetColumnCount();
135         GenericValues value;
136         for (int32_t i = 0; i < columnCount; i++) {
137             if ((statement.GetColumnName(i) == PrivacyFiledConst::FIELD_TIMESTAMP) ||
138                 (statement.GetColumnName(i) == PrivacyFiledConst::FIELD_ACCESS_DURATION)) {
139                 value.Put(statement.GetColumnName(i), statement.GetValue(i, true));
140             } else {
141                 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
142             }
143         }
144         results.emplace_back(value);
145     }
146     return SUCCESS;
147 }
148 
GetDistinctValue(DataType type,const std::string & condition,std::vector<GenericValues> & results)149 int32_t PermissionUsedRecordDb::GetDistinctValue(DataType type,
150     const std::string& condition, std::vector<GenericValues>& results)
151 {
152     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
153     std::string getDistinctValueSql = CreateGetDistinctValue(type, condition);
154     auto statement = Prepare(getDistinctValueSql);
155     while (statement.Step() == Statement::State::ROW) {
156         int32_t columnCount = statement.GetColumnCount();
157         GenericValues value;
158         for (int32_t i = 0; i < columnCount; i++) {
159             if (statement.GetColumnName(i) == PrivacyFiledConst::FIELD_TOKEN_ID) {
160                 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
161             } else if (statement.GetColumnName(i) == PrivacyFiledConst::FIELD_DEVICE_ID) {
162                 value.Put(statement.GetColumnName(i), statement.GetColumnString(i));
163             }
164         }
165         results.emplace_back(value);
166     }
167     return SUCCESS;
168 }
169 
Count(DataType type,GenericValues & result)170 void PermissionUsedRecordDb::Count(DataType type, GenericValues& result)
171 {
172     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
173     std::string countSql = CreateCountPrepareSqlCmd(type);
174     auto countStatement = Prepare(countSql);
175     if (countStatement.Step() == Statement::State::ROW) {
176         int32_t column = 0;
177         result.Put(FIELD_COUNT_NUMBER, countStatement.GetValue(column, true));
178     }
179 }
180 
DeleteExpireRecords(DataType type,const GenericValues & andConditions)181 int32_t PermissionUsedRecordDb::DeleteExpireRecords(DataType type,
182     const GenericValues& andConditions)
183 {
184     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
185     std::vector<std::string> andColumns = andConditions.GetAllKeys();
186     if (!andColumns.empty()) {
187         std::string deleteExpireSql = CreateDeleteExpireRecordsPrepareSqlCmd(type, andColumns);
188         auto deleteExpireStatement = Prepare(deleteExpireSql);
189         for (const auto& columnName : andColumns) {
190             deleteExpireStatement.Bind(columnName, andConditions.Get(columnName));
191         }
192         if (deleteExpireStatement.Step() != Statement::State::DONE) {
193             return FAILURE;
194         }
195     }
196     return SUCCESS;
197 }
198 
DeleteExcessiveRecords(DataType type,uint32_t excessiveSize)199 int32_t PermissionUsedRecordDb::DeleteExcessiveRecords(DataType type, uint32_t excessiveSize)
200 {
201     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
202     std::string deleteExcessiveSql = CreateDeleteExcessiveRecordsPrepareSqlCmd(type, excessiveSize);
203     auto deleteExcessiveStatement = Prepare(deleteExcessiveSql);
204     if (deleteExcessiveStatement.Step() != Statement::State::DONE) {
205         return FAILURE;
206     }
207     return SUCCESS;
208 }
209 
CreateInsertPrepareSqlCmd(DataType type) const210 std::string PermissionUsedRecordDb::CreateInsertPrepareSqlCmd(DataType type) const
211 {
212     auto it = dataTypeToSqlTable_.find(type);
213     if (it == dataTypeToSqlTable_.end()) {
214         return std::string();
215     }
216     std::string sql = "insert into " + it->second.tableName_ + " values(";
217     int32_t i = 1;
218     for (const auto& name : it->second.tableColumnNames_) {
219         sql.append(":" + name);
220         if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
221             sql.append(",");
222         }
223         i += 1;
224     }
225     sql.append(")");
226     return sql;
227 }
228 
CreateDeletePrepareSqlCmd(DataType type,const std::vector<std::string> & columnNames) const229 std::string PermissionUsedRecordDb::CreateDeletePrepareSqlCmd(
230     DataType type, const std::vector<std::string>& columnNames) const
231 {
232     auto it = dataTypeToSqlTable_.find(type);
233     if (it == dataTypeToSqlTable_.end()) {
234         return std::string();
235     }
236     std::string sql = "delete from " + it->second.tableName_ + " where 1 = 1";
237     for (const auto& name : columnNames) {
238         sql.append(" and ");
239         sql.append(name + "=:" + name);
240     }
241     return sql;
242 }
243 
CreateUpdatePrepareSqlCmd(DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const244 std::string PermissionUsedRecordDb::CreateUpdatePrepareSqlCmd(DataType type,
245     const std::vector<std::string>& modifyColumns, const std::vector<std::string>& conditionColumns) const
246 {
247     if (modifyColumns.empty()) {
248         return std::string();
249     }
250 
251     auto it = dataTypeToSqlTable_.find(type);
252     if (it == dataTypeToSqlTable_.end()) {
253         return std::string();
254     }
255 
256     std::string sql = "update " + it->second.tableName_ + " set ";
257     int32_t i = 1;
258     for (const auto& name : modifyColumns) {
259         sql.append(name + "=:" + name);
260         if (i < static_cast<int32_t>(modifyColumns.size())) {
261             sql.append(",");
262         }
263         i += 1;
264     }
265 
266     if (!conditionColumns.empty()) {
267         sql.append(" where 1 = 1");
268         for (const auto& columnName : conditionColumns) {
269             sql.append(" and ");
270             sql.append(columnName + "=:" + columnName);
271         }
272     }
273     return sql;
274 }
275 
CreateSelectByConditionPrepareSqlCmd(DataType type,const std::set<int32_t> & opCodeList,const std::vector<std::string> & andColumns,int32_t databaseQueryCount) const276 std::string PermissionUsedRecordDb::CreateSelectByConditionPrepareSqlCmd(DataType type,
277     const std::set<int32_t>& opCodeList, const std::vector<std::string>& andColumns, int32_t databaseQueryCount) const
278 {
279     auto it = dataTypeToSqlTable_.find(type);
280     if (it == dataTypeToSqlTable_.end()) {
281         return std::string();
282     }
283 
284     std::string sql = "select * from " + it->second.tableName_ + " where 1 = 1";
285 
286     for (const auto& andColName : andColumns) {
287         if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
288             sql.append(" and ");
289             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
290             sql.append(" >=:" + andColName);
291         } else if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
292             sql.append(" and ");
293             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
294             sql.append(" <=:" + andColName);
295         } else {
296             sql.append(" and ");
297             sql.append(andColName + "=:" + andColName);
298         }
299     }
300     if (!opCodeList.empty()) {
301         sql.append(" and (");
302         for (const auto& opCode : opCodeList) {
303             if (opCode != Constant::OP_INVALID) {
304                 sql.append(PrivacyFiledConst::FIELD_OP_CODE);
305                 sql.append(+ " = " + std::to_string(opCode));
306                 sql.append(" or ");
307             }
308         }
309         sql.append("0)");
310     }
311     sql.append(" limit " + std::to_string(databaseQueryCount));
312     return sql;
313 }
314 
CreateCountPrepareSqlCmd(DataType type) const315 std::string PermissionUsedRecordDb::CreateCountPrepareSqlCmd(DataType type) const
316 {
317     auto it = dataTypeToSqlTable_.find(type);
318     if (it == dataTypeToSqlTable_.end()) {
319         return std::string();
320     }
321     std::string sql = "select count(*) from " + it->second.tableName_;
322     return sql;
323 }
324 
CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,const std::vector<std::string> & andColumns) const325 std::string PermissionUsedRecordDb::CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,
326     const std::vector<std::string>& andColumns) const
327 {
328     auto it = dataTypeToSqlTable_.find(type);
329     if (it == dataTypeToSqlTable_.end()) {
330         return std::string();
331     }
332     std::string sql = "delete from " + it->second.tableName_ + " where ";
333     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
334     sql.append(" in (select ");
335     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
336     sql.append(" from " + it->second.tableName_ + " where 1 = 1");
337     for (const auto& name : andColumns) {
338         if (name == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
339             sql.append(" and ");
340             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
341             sql.append(" >=:" + name);
342         } else if (name == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
343             sql.append(" and ");
344             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
345             sql.append(" <=:" + name);
346         } else {
347             sql.append(" and ");
348             sql.append(name + "=:" + name);
349         }
350     }
351     sql.append(" )");
352     return sql;
353 }
354 
CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,uint32_t excessiveSize) const355 std::string PermissionUsedRecordDb::CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,
356     uint32_t excessiveSize) const
357 {
358     auto it = dataTypeToSqlTable_.find(type);
359     if (it == dataTypeToSqlTable_.end()) {
360         return std::string();
361     }
362     std::string sql = "delete from " + it->second.tableName_ + " where ";
363     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
364     sql.append(" in (select ");
365     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
366     sql.append(" from " + it->second.tableName_ + " order by ");
367     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
368     sql.append(" limit ");
369     sql.append(std::to_string(excessiveSize) + " )");
370     return sql;
371 }
372 
CreateGetDistinctValue(DataType type,const std::string conditionColumns) const373 std::string PermissionUsedRecordDb::CreateGetDistinctValue(DataType type,
374     const std::string conditionColumns) const
375 {
376     auto it = dataTypeToSqlTable_.find(type);
377     if (it == dataTypeToSqlTable_.end()) {
378         return std::string();
379     }
380     std::string sql = "select distinct ";
381     sql.append(conditionColumns + " from "+ it->second.tableName_);
382     return sql;
383 }
384 
CreatePermissionRecordTable() const385 int32_t PermissionUsedRecordDb::CreatePermissionRecordTable() const
386 {
387     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
388     if (it == dataTypeToSqlTable_.end()) {
389         return FAILURE;
390     }
391     std::string sql = "create table if not exists ";
392     sql.append(it->second.tableName_ + " (")
393         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
394         .append(" integer not null,")
395         .append(PrivacyFiledConst::FIELD_OP_CODE)
396         .append(" integer not null,")
397         .append(PrivacyFiledConst::FIELD_STATUS)
398         .append(" integer not null,")
399         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
400         .append(" integer not null,")
401         .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
402         .append(" integer not null,")
403         .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
404         .append(" integer not null,")
405         .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
406         .append(" integer not null,")
407         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
408         .append(" integer not null,")
409         .append("primary key(")
410         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
411         .append(",")
412         .append(PrivacyFiledConst::FIELD_OP_CODE)
413         .append(",")
414         .append(PrivacyFiledConst::FIELD_STATUS)
415         .append(",")
416         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
417         .append("))");
418     return ExecuteSql(sql);
419 }
420 
InsertLockScreenStatusColumn() const421 int32_t PermissionUsedRecordDb::InsertLockScreenStatusColumn() const
422 {
423     ACCESSTOKEN_LOG_INFO(LABEL, "Entry");
424     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
425     if (it == dataTypeToSqlTable_.end()) {
426         return FAILURE;
427     }
428     std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
429         PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS + "=" +
430         std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED);
431     int32_t checkResult = ExecuteSql(checkSql);
432     ACCESSTOKEN_LOG_INFO(LABEL, "check result:%{public}d", checkResult);
433     if (checkResult != -1) {
434         return SUCCESS;
435     }
436 
437     std::string sql = "alter table ";
438     sql.append(it->second.tableName_ + " add column ")
439         .append(PrivacyFiledConst::FIELD_LOCKSCREEN_STATUS)
440         .append(" integer default ")
441         .append(std::to_string(LockScreenStatusChangeType::PERM_ACTIVE_IN_UNLOCKED));
442     int32_t insertResult = ExecuteSql(sql);
443     ACCESSTOKEN_LOG_INFO(LABEL, "insert column result:%{public}d", insertResult);
444     return insertResult;
445 }
446 } // namespace AccessToken
447 } // namespace Security
448 } // namespace OHOS
449