• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "access_token_db.h"
17 
18 #include "accesstoken_log.h"
19 
20 namespace OHOS {
21 namespace Security {
22 namespace AccessToken {
23 namespace {
24 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenDb"};
25 static const std::string INTEGER_STR = " integer not null,";
26 static const std::string TEXT_STR = " text not null,";
27 }
28 
GetInstance()29 AccessTokenDb& AccessTokenDb::GetInstance()
30 {
31     static AccessTokenDb instance;
32     return instance;
33 }
34 
~AccessTokenDb()35 AccessTokenDb::~AccessTokenDb()
36 {
37     Close();
38 }
39 
OnCreate()40 void AccessTokenDb::OnCreate()
41 {
42     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__);
43     CreateHapTokenInfoTable();
44     CreateNativeTokenInfoTable();
45     CreatePermissionDefinitionTable();
46     CreatePermissionStateTable();
47 }
48 
OnUpdate()49 void AccessTokenDb::OnUpdate()
50 {
51     ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__);
52     AddAvailableTypeColumn();
53     AddPermDialogCapColumn();
54 }
55 
AccessTokenDb()56 AccessTokenDb::AccessTokenDb() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION)
57 {
58     SqliteTable hapTokenInfoTable;
59     hapTokenInfoTable.tableName_ = HAP_TOKEN_INFO_TABLE;
60     hapTokenInfoTable.tableColumnNames_ = {
61         TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_USER_ID,
62         TokenFiledConst::FIELD_BUNDLE_NAME, TokenFiledConst::FIELD_INST_INDEX, TokenFiledConst::FIELD_DLP_TYPE,
63         TokenFiledConst::FIELD_APP_ID, TokenFiledConst::FIELD_DEVICE_ID,
64         TokenFiledConst::FIELD_APL, TokenFiledConst::FIELD_TOKEN_VERSION,
65         TokenFiledConst::FIELD_TOKEN_ATTR, TokenFiledConst::FIELD_API_VERSION,
66         TokenFiledConst::FIELD_FORBID_PERM_DIALOG
67     };
68 
69     SqliteTable nativeTokenInfoTable;
70     nativeTokenInfoTable.tableName_ = NATIVE_TOKEN_INFO_TABLE;
71     nativeTokenInfoTable.tableColumnNames_ = {
72         TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PROCESS_NAME,
73         TokenFiledConst::FIELD_TOKEN_VERSION, TokenFiledConst::FIELD_TOKEN_ATTR,
74         TokenFiledConst::FIELD_DCAP, TokenFiledConst::FIELD_NATIVE_ACLS, TokenFiledConst::FIELD_APL
75     };
76 
77     SqliteTable permissionDefTable;
78     permissionDefTable.tableName_ = PERMISSION_DEF_TABLE;
79     permissionDefTable.tableColumnNames_ = {
80         TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PERMISSION_NAME,
81         TokenFiledConst::FIELD_BUNDLE_NAME, TokenFiledConst::FIELD_GRANT_MODE,
82         TokenFiledConst::FIELD_AVAILABLE_LEVEL, TokenFiledConst::FIELD_PROVISION_ENABLE,
83         TokenFiledConst::FIELD_DISTRIBUTED_SCENE_ENABLE, TokenFiledConst::FIELD_LABEL,
84         TokenFiledConst::FIELD_LABEL_ID, TokenFiledConst::FIELD_DESCRIPTION,
85         TokenFiledConst::FIELD_DESCRIPTION_ID, TokenFiledConst::FIELD_AVAILABLE_TYPE
86     };
87 
88     SqliteTable permissionStateTable;
89     permissionStateTable.tableName_ = PERMISSION_STATE_TABLE;
90     permissionStateTable.tableColumnNames_ = {
91         TokenFiledConst::FIELD_TOKEN_ID, TokenFiledConst::FIELD_PERMISSION_NAME,
92         TokenFiledConst::FIELD_DEVICE_ID, TokenFiledConst::FIELD_GRANT_IS_GENERAL,
93         TokenFiledConst::FIELD_GRANT_STATE, TokenFiledConst::FIELD_GRANT_FLAG
94     };
95 
96     dataTypeToSqlTable_ = {
97         {ACCESSTOKEN_HAP_INFO, hapTokenInfoTable},
98         {ACCESSTOKEN_NATIVE_INFO, nativeTokenInfoTable},
99         {ACCESSTOKEN_PERMISSION_DEF, permissionDefTable},
100         {ACCESSTOKEN_PERMISSION_STATE, permissionStateTable},
101     };
102 
103     Open();
104 }
105 
Add(const DataType type,const std::vector<GenericValues> & values)106 int AccessTokenDb::Add(const DataType type, const std::vector<GenericValues>& values)
107 {
108     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
109     std::string prepareSql = CreateInsertPrepareSqlCmd(type);
110     auto statement = Prepare(prepareSql);
111     BeginTransaction();
112     bool isExecuteSuccessfully = true;
113     for (const auto& value : values) {
114         std::vector<std::string> columnNames = value.GetAllKeys();
115         for (const auto& columnName : columnNames) {
116             statement.Bind(columnName, value.Get(columnName));
117         }
118         int ret = statement.Step();
119         if (ret != Statement::State::DONE) {
120             ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", SpitError().c_str());
121             isExecuteSuccessfully = false;
122         }
123         statement.Reset();
124     }
125     if (!isExecuteSuccessfully) {
126         ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction.");
127         RollbackTransaction();
128         return FAILURE;
129     }
130     ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction.");
131     CommitTransaction();
132     return SUCCESS;
133 }
134 
Remove(const DataType type,const GenericValues & conditions)135 int AccessTokenDb::Remove(const DataType type, const GenericValues& conditions)
136 {
137     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
138     std::vector<std::string> columnNames = conditions.GetAllKeys();
139     std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames);
140     auto statement = Prepare(prepareSql);
141     for (const auto& columnName : columnNames) {
142         statement.Bind(columnName, conditions.Get(columnName));
143     }
144     int ret = statement.Step();
145     return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
146 }
147 
Modify(const DataType type,const GenericValues & modifyValues,const GenericValues & conditions)148 int AccessTokenDb::Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions)
149 {
150     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
151     std::vector<std::string> modifyColumns = modifyValues.GetAllKeys();
152     std::vector<std::string> conditionColumns = conditions.GetAllKeys();
153     std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyColumns, conditionColumns);
154     auto statement = Prepare(prepareSql);
155     for (const auto& columnName : modifyColumns) {
156         statement.Bind(columnName, modifyValues.Get(columnName));
157     }
158     for (const auto& columnName : conditionColumns) {
159         statement.Bind(columnName, conditions.Get(columnName));
160     }
161     int ret = statement.Step();
162     return (ret == Statement::State::DONE) ? SUCCESS : FAILURE;
163 }
164 
Find(const DataType type,std::vector<GenericValues> & results)165 int AccessTokenDb::Find(const DataType type, std::vector<GenericValues>& results)
166 {
167     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
168     std::string prepareSql = CreateSelectPrepareSqlCmd(type);
169     auto statement = Prepare(prepareSql);
170     while (statement.Step() == Statement::State::ROW) {
171         int columnCount = statement.GetColumnCount();
172         GenericValues value;
173         for (int i = 0; i < columnCount; i++) {
174             value.Put(statement.GetColumnName(i), statement.GetValue(i, false));
175         }
176         results.emplace_back(value);
177     }
178     return SUCCESS;
179 }
180 
RefreshAll(const DataType type,const std::vector<GenericValues> & values)181 int AccessTokenDb::RefreshAll(const DataType type, const std::vector<GenericValues>& values)
182 {
183     OHOS::Utils::UniqueWriteGuard<OHOS::Utils::RWLock> lock(this->rwLock_);
184     std::string deleteSql = CreateDeletePrepareSqlCmd(type);
185     std::string insertSql = CreateInsertPrepareSqlCmd(type);
186     auto deleteStatement = Prepare(deleteSql);
187     auto insertStatement = Prepare(insertSql);
188     BeginTransaction();
189     bool canCommit = deleteStatement.Step() == Statement::State::DONE;
190     for (const auto& value : values) {
191         std::vector<std::string> columnNames = value.GetAllKeys();
192         for (const auto& columnName : columnNames) {
193             insertStatement.Bind(columnName, value.Get(columnName));
194         }
195         int ret = insertStatement.Step();
196         if (ret != Statement::State::DONE) {
197             ACCESSTOKEN_LOG_ERROR(
198                 LABEL, "insert failed, errorMsg: %{public}s", SpitError().c_str());
199             canCommit = false;
200         }
201         insertStatement.Reset();
202     }
203     if (!canCommit) {
204         ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction.");
205         RollbackTransaction();
206         return FAILURE;
207     }
208     ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction.");
209     CommitTransaction();
210     return SUCCESS;
211 }
212 
CreateInsertPrepareSqlCmd(const DataType type) const213 std::string AccessTokenDb::CreateInsertPrepareSqlCmd(const DataType type) const
214 {
215     auto it = dataTypeToSqlTable_.find(type);
216     if (it == dataTypeToSqlTable_.end()) {
217         return std::string();
218     }
219     std::string sql = "insert into " + it->second.tableName_ + " values(";
220     int i = 1;
221     for (const auto& columnName : it->second.tableColumnNames_) {
222         sql.append(":" + columnName);
223         if (i < static_cast<int32_t>(it->second.tableColumnNames_.size())) {
224             sql.append(",");
225         }
226         i += 1;
227     }
228     sql.append(")");
229     return sql;
230 }
231 
CreateDeletePrepareSqlCmd(const DataType type,const std::vector<std::string> & columnNames) const232 std::string AccessTokenDb::CreateDeletePrepareSqlCmd(
233     const DataType type, const std::vector<std::string>& columnNames) const
234 {
235     auto it = dataTypeToSqlTable_.find(type);
236     if (it == dataTypeToSqlTable_.end()) {
237         return std::string();
238     }
239     std::string sql = "delete from " + it->second.tableName_ + " where 1 = 1";
240     for (const auto& columnName : columnNames) {
241         sql.append(" and ");
242         sql.append(columnName + "=:" + columnName);
243     }
244     return sql;
245 }
246 
CreateUpdatePrepareSqlCmd(const DataType type,const std::vector<std::string> & modifyColumns,const std::vector<std::string> & conditionColumns) const247 std::string AccessTokenDb::CreateUpdatePrepareSqlCmd(const DataType type, const std::vector<std::string>& modifyColumns,
248     const std::vector<std::string>& conditionColumns) const
249 {
250     if (modifyColumns.empty()) {
251         return std::string();
252     }
253 
254     auto it = dataTypeToSqlTable_.find(type);
255     if (it == dataTypeToSqlTable_.end()) {
256         return std::string();
257     }
258 
259     std::string sql = "update " + it->second.tableName_ + " set ";
260     int i = 1;
261     for (const auto& columnName : modifyColumns) {
262         sql.append(columnName + "=:" + columnName);
263         if (i < static_cast<int32_t>(modifyColumns.size())) {
264             sql.append(",");
265         }
266         i += 1;
267     }
268 
269     if (!conditionColumns.empty()) {
270         sql.append(" where 1 = 1");
271         for (const auto& columnName : conditionColumns) {
272             sql.append(" and ");
273             sql.append(columnName + "=:" + columnName);
274         }
275     }
276     return sql;
277 }
278 
CreateSelectPrepareSqlCmd(const DataType type) const279 std::string AccessTokenDb::CreateSelectPrepareSqlCmd(const DataType type) const
280 {
281     auto it = dataTypeToSqlTable_.find(type);
282     if (it == dataTypeToSqlTable_.end()) {
283         return std::string();
284     }
285     std::string sql = "select * from " + it->second.tableName_;
286     return sql;
287 }
288 
CreateHapTokenInfoTable() const289 int AccessTokenDb::CreateHapTokenInfoTable() const
290 {
291     auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_HAP_INFO);
292     if (it == dataTypeToSqlTable_.end()) {
293         return FAILURE;
294     }
295     std::string sql = "create table if not exists ";
296     sql.append(it->second.tableName_ + " (")
297         .append(TokenFiledConst::FIELD_TOKEN_ID)
298         .append(INTEGER_STR)
299         .append(TokenFiledConst::FIELD_USER_ID)
300         .append(INTEGER_STR)
301         .append(TokenFiledConst::FIELD_BUNDLE_NAME)
302         .append(TEXT_STR)
303         .append(TokenFiledConst::FIELD_INST_INDEX)
304         .append(INTEGER_STR)
305         .append(TokenFiledConst::FIELD_DLP_TYPE)
306         .append(INTEGER_STR)
307         .append(TokenFiledConst::FIELD_APP_ID)
308         .append(TEXT_STR)
309         .append(TokenFiledConst::FIELD_DEVICE_ID)
310         .append(TEXT_STR)
311         .append(TokenFiledConst::FIELD_APL)
312         .append(INTEGER_STR)
313         .append(TokenFiledConst::FIELD_TOKEN_VERSION)
314         .append(INTEGER_STR)
315         .append(TokenFiledConst::FIELD_TOKEN_ATTR)
316         .append(INTEGER_STR)
317         .append(TokenFiledConst::FIELD_API_VERSION)
318         .append(INTEGER_STR)
319         .append(TokenFiledConst::FIELD_FORBID_PERM_DIALOG)
320         .append(INTEGER_STR)
321         .append("primary key(")
322         .append(TokenFiledConst::FIELD_TOKEN_ID)
323         .append("))");
324     return ExecuteSql(sql);
325 }
326 
CreateNativeTokenInfoTable() const327 int AccessTokenDb::CreateNativeTokenInfoTable() const
328 {
329     auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_NATIVE_INFO);
330     if (it == dataTypeToSqlTable_.end()) {
331         return FAILURE;
332     }
333     std::string sql = "create table if not exists ";
334     sql.append(it->second.tableName_ + " (")
335         .append(TokenFiledConst::FIELD_TOKEN_ID)
336         .append(INTEGER_STR)
337         .append(TokenFiledConst::FIELD_PROCESS_NAME)
338         .append(TEXT_STR)
339         .append(TokenFiledConst::FIELD_TOKEN_VERSION)
340         .append(INTEGER_STR)
341         .append(TokenFiledConst::FIELD_TOKEN_ATTR)
342         .append(INTEGER_STR)
343         .append(TokenFiledConst::FIELD_DCAP)
344         .append(TEXT_STR)
345         .append(TokenFiledConst::FIELD_NATIVE_ACLS)
346         .append(TEXT_STR)
347         .append(TokenFiledConst::FIELD_APL)
348         .append(INTEGER_STR)
349         .append("primary key(")
350         .append(TokenFiledConst::FIELD_TOKEN_ID)
351         .append("))");
352     return ExecuteSql(sql);
353 }
354 
CreatePermissionDefinitionTable() const355 int AccessTokenDb::CreatePermissionDefinitionTable() const
356 {
357     auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_DEF);
358     if (it == dataTypeToSqlTable_.end()) {
359         return FAILURE;
360     }
361     std::string sql = "create table if not exists ";
362     sql.append(it->second.tableName_ + " (")
363         .append(TokenFiledConst::FIELD_TOKEN_ID)
364         .append(INTEGER_STR)
365         .append(TokenFiledConst::FIELD_PERMISSION_NAME)
366         .append(TEXT_STR)
367         .append(TokenFiledConst::FIELD_BUNDLE_NAME)
368         .append(TEXT_STR)
369         .append(TokenFiledConst::FIELD_GRANT_MODE)
370         .append(INTEGER_STR)
371         .append(TokenFiledConst::FIELD_AVAILABLE_LEVEL)
372         .append(INTEGER_STR)
373         .append(TokenFiledConst::FIELD_PROVISION_ENABLE)
374         .append(INTEGER_STR)
375         .append(TokenFiledConst::FIELD_DISTRIBUTED_SCENE_ENABLE)
376         .append(INTEGER_STR)
377         .append(TokenFiledConst::FIELD_LABEL)
378         .append(TEXT_STR)
379         .append(TokenFiledConst::FIELD_LABEL_ID)
380         .append(INTEGER_STR)
381         .append(TokenFiledConst::FIELD_DESCRIPTION)
382         .append(TEXT_STR)
383         .append(TokenFiledConst::FIELD_DESCRIPTION_ID)
384         .append(INTEGER_STR)
385         .append(TokenFiledConst::FIELD_AVAILABLE_TYPE)
386         .append(INTEGER_STR)
387         .append("primary key(")
388         .append(TokenFiledConst::FIELD_TOKEN_ID)
389         .append(",")
390         .append(TokenFiledConst::FIELD_PERMISSION_NAME)
391         .append("))");
392     return ExecuteSql(sql);
393 }
394 
AddAvailableTypeColumn() const395 int32_t AccessTokenDb::AddAvailableTypeColumn() const
396 {
397     ACCESSTOKEN_LOG_INFO(LABEL, "Entry");
398     auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_DEF);
399     if (it == dataTypeToSqlTable_.end()) {
400         return FAILURE;
401     }
402     std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
403         TokenFiledConst::FIELD_AVAILABLE_TYPE + "=" +
404         std::to_string(ATokenAvailableTypeEnum::NORMAL);
405     int32_t checkResult = ExecuteSql(checkSql);
406     ACCESSTOKEN_LOG_INFO(LABEL, "check result:%{public}d", checkResult);
407     if (checkResult != -1) {
408         return SUCCESS;
409     }
410 
411     std::string sql = "alter table ";
412     sql.append(it->second.tableName_ + " add column ")
413         .append(TokenFiledConst::FIELD_AVAILABLE_TYPE)
414         .append(" integer default ")
415         .append(std::to_string(ATokenAvailableTypeEnum::NORMAL));
416     int32_t insertResult = ExecuteSql(sql);
417     ACCESSTOKEN_LOG_INFO(LABEL, "insert column result:%{public}d", insertResult);
418     return insertResult;
419 }
420 
AddPermDialogCapColumn() const421 int32_t AccessTokenDb::AddPermDialogCapColumn() const
422 {
423     ACCESSTOKEN_LOG_INFO(LABEL, "Entry");
424     auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_HAP_INFO);
425     if (it == dataTypeToSqlTable_.end()) {
426         return FAILURE;
427     }
428     std::string checkSql = "SELECT 1 FROM " + it->second.tableName_ + " WHERE " +
429         TokenFiledConst::FIELD_FORBID_PERM_DIALOG + "=" + std::to_string(false);
430     int32_t checkResult = ExecuteSql(checkSql);
431     ACCESSTOKEN_LOG_INFO(LABEL, "check result:%{public}d", checkResult);
432     if (checkResult != -1) {
433         return SUCCESS;
434     }
435 
436     std::string sql = "alter table ";
437     sql.append(it->second.tableName_ + " add column ")
438         .append(TokenFiledConst::FIELD_FORBID_PERM_DIALOG)
439         .append(" integer default ")
440         .append(std::to_string(false));
441     int32_t insertResult = ExecuteSql(sql);
442     ACCESSTOKEN_LOG_INFO(LABEL, "insert column result:%{public}d", insertResult);
443     return insertResult;
444 }
445 
CreatePermissionStateTable() const446 int AccessTokenDb::CreatePermissionStateTable() const
447 {
448     auto it = dataTypeToSqlTable_.find(DataType::ACCESSTOKEN_PERMISSION_STATE);
449     if (it == dataTypeToSqlTable_.end()) {
450         return FAILURE;
451     }
452     std::string sql = "create table if not exists ";
453     sql.append(it->second.tableName_ + " (")
454         .append(TokenFiledConst::FIELD_TOKEN_ID)
455         .append(INTEGER_STR)
456         .append(TokenFiledConst::FIELD_PERMISSION_NAME)
457         .append(TEXT_STR)
458         .append(TokenFiledConst::FIELD_DEVICE_ID)
459         .append(TEXT_STR)
460         .append(TokenFiledConst::FIELD_GRANT_IS_GENERAL)
461         .append(INTEGER_STR)
462         .append(TokenFiledConst::FIELD_GRANT_STATE)
463         .append(INTEGER_STR)
464         .append(TokenFiledConst::FIELD_GRANT_FLAG)
465         .append(INTEGER_STR)
466         .append("primary key(")
467         .append(TokenFiledConst::FIELD_TOKEN_ID)
468         .append(",")
469         .append(TokenFiledConst::FIELD_PERMISSION_NAME)
470         .append(",")
471         .append(TokenFiledConst::FIELD_DEVICE_ID)
472         .append("))");
473     return ExecuteSql(sql);
474 }
475 } // namespace AccessToken
476 } // namespace Security
477 } // namespace OHOS
478