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