• 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 
FindByConditions(DataType type,const std::set<int32_t> & opCodeList,const GenericValues & andConditions,std::vector<GenericValues> & results)118 int32_t PermissionUsedRecordDb::FindByConditions(DataType type, const std::set<int32_t>& opCodeList,
119     const GenericValues& andConditions, std::vector<GenericValues>& results)
120 {
121     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
122     std::vector<std::string> andColumns = andConditions.GetAllKeys();
123     std::string prepareSql = CreateSelectByConditionPrepareSqlCmd(type, opCodeList, andColumns);
124     auto statement = Prepare(prepareSql);
125 
126     for (const auto& columnName : andColumns) {
127         statement.Bind(columnName, andConditions.Get(columnName));
128     }
129 
130     while (statement.Step() == Statement::State::ROW) {
131         int32_t columnCount = statement.GetColumnCount();
132         GenericValues value;
133         for (int32_t i = 0; i < columnCount; i++) {
134             if ((statement.GetColumnName(i) == PrivacyFiledConst::FIELD_TIMESTAMP) ||
135                 (statement.GetColumnName(i) == PrivacyFiledConst::FIELD_ACCESS_DURATION)) {
136                 value.Put(statement.GetColumnName(i), statement.GetValue(i, true));
137             } else {
138                 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
139             }
140         }
141         results.emplace_back(value);
142     }
143     return SUCCESS;
144 }
145 
GetDistinctValue(DataType type,const std::string & condition,std::vector<GenericValues> & results)146 int32_t PermissionUsedRecordDb::GetDistinctValue(DataType type,
147     const std::string& condition, std::vector<GenericValues>& results)
148 {
149     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
150     std::string getDistinctValueSql = CreateGetDistinctValue(type, condition);
151     auto statement = Prepare(getDistinctValueSql);
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_TOKEN_ID) {
157                 value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
158             } else if (statement.GetColumnName(i) == PrivacyFiledConst::FIELD_DEVICE_ID) {
159                 value.Put(statement.GetColumnName(i), statement.GetColumnString(i));
160             }
161         }
162         results.emplace_back(value);
163     }
164     return SUCCESS;
165 }
166 
Count(DataType type,GenericValues & result)167 void PermissionUsedRecordDb::Count(DataType type, GenericValues& result)
168 {
169     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
170     std::string countSql = CreateCountPrepareSqlCmd(type);
171     auto countStatement = Prepare(countSql);
172     if (countStatement.Step() == Statement::State::ROW) {
173         int32_t column = 0;
174         result.Put(FIELD_COUNT_NUMBER, countStatement.GetValue(column, true));
175     }
176 }
177 
DeleteExpireRecords(DataType type,const GenericValues & andConditions)178 int32_t PermissionUsedRecordDb::DeleteExpireRecords(DataType type,
179     const GenericValues& andConditions)
180 {
181     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
182     std::vector<std::string> andColumns = andConditions.GetAllKeys();
183     if (!andColumns.empty()) {
184         std::string deleteExpireSql = CreateDeleteExpireRecordsPrepareSqlCmd(type, andColumns);
185         auto deleteExpireStatement = Prepare(deleteExpireSql);
186         for (const auto& columnName : andColumns) {
187             deleteExpireStatement.Bind(columnName, andConditions.Get(columnName));
188         }
189         if (deleteExpireStatement.Step() != Statement::State::DONE) {
190             return FAILURE;
191         }
192     }
193     return SUCCESS;
194 }
195 
DeleteExcessiveRecords(DataType type,uint32_t excessiveSize)196 int32_t PermissionUsedRecordDb::DeleteExcessiveRecords(DataType type, uint32_t excessiveSize)
197 {
198     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
199     std::string deleteExcessiveSql = CreateDeleteExcessiveRecordsPrepareSqlCmd(type, excessiveSize);
200     auto deleteExcessiveStatement = Prepare(deleteExcessiveSql);
201     if (deleteExcessiveStatement.Step() != Statement::State::DONE) {
202         return FAILURE;
203     }
204     return SUCCESS;
205 }
206 
CreateInsertPrepareSqlCmd(DataType type) const207 std::string PermissionUsedRecordDb::CreateInsertPrepareSqlCmd(DataType type) const
208 {
209     auto it = dataTypeToSqlTable_.find(type);
210     if (it == dataTypeToSqlTable_.end()) {
211         return std::string();
212     }
213     std::string sql = "insert into " + it->second.tableName_ + " values(";
214     int32_t i = 1;
215     for (const auto& columnName : it->second.tableColumnNames_) {
216         sql.append(":" + columnName);
217         if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
218             sql.append(",");
219         }
220         i += 1;
221     }
222     sql.append(")");
223     return sql;
224 }
225 
CreateDeletePrepareSqlCmd(DataType type,const std::vector<std::string> & columnNames) const226 std::string PermissionUsedRecordDb::CreateDeletePrepareSqlCmd(
227     DataType type, const std::vector<std::string>& columnNames) const
228 {
229     auto it = dataTypeToSqlTable_.find(type);
230     if (it == dataTypeToSqlTable_.end()) {
231         return std::string();
232     }
233     std::string sql = "delete from " + it->second.tableName_ + " where 1 = 1";
234     for (const auto& columnName : columnNames) {
235         sql.append(" and ");
236         sql.append(columnName + "=:" + columnName);
237     }
238     return sql;
239 }
240 
CreateUpdatePrepareSqlCmd(DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const241 std::string PermissionUsedRecordDb::CreateUpdatePrepareSqlCmd(DataType type,
242     const std::vector<std::string>& modifyColumns, const std::vector<std::string>& conditionColumns) const
243 {
244     if (modifyColumns.empty()) {
245         return std::string();
246     }
247 
248     auto it = dataTypeToSqlTable_.find(type);
249     if (it == dataTypeToSqlTable_.end()) {
250         return std::string();
251     }
252 
253     std::string sql = "update " + it->second.tableName_ + " set ";
254     int32_t i = 1;
255     for (const auto& columnName : modifyColumns) {
256         sql.append(columnName + "=:" + columnName);
257         if (i < static_cast<int32_t>(modifyColumns.size())) {
258             sql.append(",");
259         }
260         i += 1;
261     }
262 
263     if (!conditionColumns.empty()) {
264         sql.append(" where 1 = 1");
265         for (const auto& columnName : conditionColumns) {
266             sql.append(" and ");
267             sql.append(columnName + "=:" + columnName);
268         }
269     }
270     return sql;
271 }
272 
CreateSelectByConditionPrepareSqlCmd(DataType type,const std::set<int32_t> & opCodeList,const std::vector<std::string> & andColumns) const273 std::string PermissionUsedRecordDb::CreateSelectByConditionPrepareSqlCmd(DataType type,
274     const std::set<int32_t>& opCodeList, const std::vector<std::string>& andColumns) const
275 {
276     auto it = dataTypeToSqlTable_.find(type);
277     if (it == dataTypeToSqlTable_.end()) {
278         return std::string();
279     }
280 
281     std::string sql = "select * from " + it->second.tableName_ + " where 1 = 1";
282     for (const auto& andColName : andColumns) {
283         if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
284             sql.append(" and ");
285             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
286             sql.append(" >=:" + andColName);
287         } else if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
288             sql.append(" and ");
289             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
290             sql.append(" <=:" + andColName);
291         } else {
292             sql.append(" and ");
293             sql.append(andColName + "=:" + andColName);
294         }
295     }
296     if (!opCodeList.empty()) {
297         sql.append(" and (");
298         for (const auto& opCode : opCodeList) {
299             if (opCode != Constant::OP_INVALID) {
300                 sql.append(PrivacyFiledConst::FIELD_OP_CODE);
301                 sql.append(+ " = " + std::to_string(opCode));
302                 sql.append(" or ");
303             }
304         }
305         sql.append("0)");
306     }
307     return sql;
308 }
309 
CreateCountPrepareSqlCmd(DataType type) const310 std::string PermissionUsedRecordDb::CreateCountPrepareSqlCmd(DataType type) const
311 {
312     auto it = dataTypeToSqlTable_.find(type);
313     if (it == dataTypeToSqlTable_.end()) {
314         return std::string();
315     }
316     std::string sql = "select count(*) from " + it->second.tableName_;
317     return sql;
318 }
319 
CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,const std::vector<std::string> & andColumns) const320 std::string PermissionUsedRecordDb::CreateDeleteExpireRecordsPrepareSqlCmd(DataType type,
321     const std::vector<std::string>& andColumns) const
322 {
323     auto it = dataTypeToSqlTable_.find(type);
324     if (it == dataTypeToSqlTable_.end()) {
325         return std::string();
326     }
327     std::string sql = "delete from " + it->second.tableName_ + " where ";
328     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
329     sql.append(" in (select ");
330     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
331     sql.append(" from " + it->second.tableName_ + " where 1 = 1");
332     for (const auto& andColName : andColumns) {
333         if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_BEGIN) {
334             sql.append(" and ");
335             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
336             sql.append(" >=:" + andColName);
337         } else if (andColName == PrivacyFiledConst::FIELD_TIMESTAMP_END) {
338             sql.append(" and ");
339             sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
340             sql.append(" <=:" + andColName);
341         } else {
342             sql.append(" and ");
343             sql.append(andColName + "=:" + andColName);
344         }
345     }
346     sql.append(" )");
347     return sql;
348 }
349 
CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,uint32_t excessiveSize) const350 std::string PermissionUsedRecordDb::CreateDeleteExcessiveRecordsPrepareSqlCmd(DataType type,
351     uint32_t excessiveSize) const
352 {
353     auto it = dataTypeToSqlTable_.find(type);
354     if (it == dataTypeToSqlTable_.end()) {
355         return std::string();
356     }
357     std::string sql = "delete from " + it->second.tableName_ + " where ";
358     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
359     sql.append(" in (select ");
360     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
361     sql.append(" from " + it->second.tableName_ + " order by ");
362     sql.append(PrivacyFiledConst::FIELD_TIMESTAMP);
363     sql.append(" limit ");
364     sql.append(std::to_string(excessiveSize) + " )");
365     return sql;
366 }
367 
CreateGetDistinctValue(DataType type,const std::string conditionColumns) const368 std::string PermissionUsedRecordDb::CreateGetDistinctValue(DataType type,
369     const std::string conditionColumns) const
370 {
371     auto it = dataTypeToSqlTable_.find(type);
372     if (it == dataTypeToSqlTable_.end()) {
373         return std::string();
374     }
375     std::string sql = "select distinct ";
376     sql.append(conditionColumns + " from "+ it->second.tableName_);
377     return sql;
378 }
379 
CreatePermissionRecordTable() const380 int32_t PermissionUsedRecordDb::CreatePermissionRecordTable() const
381 {
382     auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD);
383     if (it == dataTypeToSqlTable_.end()) {
384         return FAILURE;
385     }
386     std::string sql = "create table if not exists ";
387     sql.append(it->second.tableName_ + " (")
388         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
389         .append(" integer not null,")
390         .append(PrivacyFiledConst::FIELD_OP_CODE)
391         .append(" integer not null,")
392         .append(PrivacyFiledConst::FIELD_STATUS)
393         .append(" integer not null,")
394         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
395         .append(" integer not null,")
396         .append(PrivacyFiledConst::FIELD_ACCESS_DURATION)
397         .append(" integer not null,")
398         .append(PrivacyFiledConst::FIELD_ACCESS_COUNT)
399         .append(" integer not null,")
400         .append(PrivacyFiledConst::FIELD_REJECT_COUNT)
401         .append(" integer not null,")
402         .append("primary key(")
403         .append(PrivacyFiledConst::FIELD_TOKEN_ID)
404         .append(",")
405         .append(PrivacyFiledConst::FIELD_OP_CODE)
406         .append(",")
407         .append(PrivacyFiledConst::FIELD_STATUS)
408         .append(",")
409         .append(PrivacyFiledConst::FIELD_TIMESTAMP)
410         .append("))");
411     return ExecuteSql(sql);
412 }
413 } // namespace AccessToken
414 } // namespace Security
415 } // namespace OHOS
416