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