• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "uri_permission_rdb.h"
17 
18 #include <string>
19 #include <vector>
20 
21 #include "scope_guard.h"
22 #include "ability_manager_errors.h"
23 #include "hilog_wrapper.h"
24 #include "want.h"
25 
26 namespace OHOS {
27 namespace AAFwk {
28 
29 namespace {
30 const std::string URI_PERMISSION_RDB_NAME = "/uripmdb.db";
31 const std::string URI_PERMISSION_TABLE_NAME = "uri_permission";
32 const std::string COLUMN_URI = "URI";
33 const std::string COLUMN_FLAG = "FLAG";
34 const std::string COLUMN_FROM_TOKEN_ID = "FROM_TOKEN_ID";
35 const std::string COLUMN_TARGET_TOKEN_ID = "TARGET_TOKEN_ID";
36 const int32_t COLUMN_URI_INDEX = 1;
37 const int32_t COLUMN_FLAG_INDEX = 2;
38 const int32_t COLUMN_FROM_TOKEN_ID_INDEX = 3;
39 const int32_t COLUMN_TARGET_TOKEN_ID_INDEX = 4;
40 }
41 
PrintRdbGrantInfo(const RdbGrantInfo & info)42 void PrintRdbGrantInfo(const RdbGrantInfo &info)
43 {
44     HILOG_DEBUG("uri: %{private}s, flag: %{public}u, fromTokenId: %{public}u, targetTokenId: %{public}u.",
45         info.uri.c_str(), info.flag, info.fromTokenId, info.targetTokenId);
46 }
47 
UriPermissionRdb()48 UriPermissionRdb::UriPermissionRdb()
49 {
50     HILOG_DEBUG("UriPermissionRdb: Create DataBase");
51     RdbConfig rdbConfig;
52     rdbConfig.dbName = URI_PERMISSION_RDB_NAME;
53     rdbConfig.tableName = URI_PERMISSION_TABLE_NAME;
54     // create database
55     rdbConfig.createTableSql = std::string("CREATE TABLE IF NOT EXISTS " + URI_PERMISSION_TABLE_NAME +
56         "(ID INTEGER PRIMARY KEY AUTOINCREMENT, URI TEXT NOT NULL, " +
57         "FLAG INTEGER, FROM_TOKEN_ID INTEGER, TARGET_TOKEN_ID INTEGER);");
58     HILOG_DEBUG("CreateTableSql: %{public}s", rdbConfig.createTableSql.c_str());
59     rdbDataManager_ = std::make_shared<RdbDataManager>(rdbConfig);
60     bool ret = rdbDataManager_->CreateTable();
61     if (!ret) {
62         HILOG_DEBUG("Failed to createTable");
63     }
64 }
65 
AddGrantInfo(const std::string & uri,uint32_t flag,uint32_t fromTokenId,uint32_t targetTokenId)66 int32_t UriPermissionRdb::AddGrantInfo(const std::string &uri, uint32_t flag, uint32_t fromTokenId,
67     uint32_t targetTokenId)
68 {
69     HILOG_INFO("AddGrantInfo uri=%{private}s, flag=%{public}u, fromTokenId=%{public}u, targetTokenId=%{public}u.",
70         uri.c_str(), flag, fromTokenId, targetTokenId);
71     NativeRdb::AbsRdbPredicates absRdbPredicates(URI_PERMISSION_TABLE_NAME);
72     absRdbPredicates.EqualTo(COLUMN_FROM_TOKEN_ID, std::to_string(fromTokenId));
73     absRdbPredicates.EqualTo(COLUMN_TARGET_TOKEN_ID, std::to_string(targetTokenId));
74     absRdbPredicates.EqualTo(COLUMN_URI, uri);
75     std::vector<RdbGrantInfo> rdbGrantInfoList;
76     int rowCount;
77     bool ret = QueryData(absRdbPredicates, rdbGrantInfoList, rowCount);
78     if (!ret) {
79         HILOG_ERROR("QueryData failed");
80         return INNER_ERR;
81     }
82     HILOG_DEBUG("rowCount = %{public}d", rowCount);
83     // should query no more than one uri permission
84     if (rowCount > 1) {
85         HILOG_ERROR("Query more than one uri permission grant info!");
86         for (const auto &info : rdbGrantInfoList) {
87             PrintRdbGrantInfo(info);
88         }
89         return INNER_ERR;
90     }
91     if (rowCount == 0) {
92         HILOG_INFO("Add a new uri permission info");
93         RdbGrantInfo grantInfo = { uri, flag, static_cast<uint32_t>(fromTokenId),
94                                    static_cast<uint32_t>(targetTokenId) };
95         rdbGrantInfoList.push_back(grantInfo);
96         ret = InsertData(rdbGrantInfoList);
97         if (!ret) {
98             HILOG_ERROR("InsertData failed");
99             return INNER_ERR;
100         }
101         return ERR_OK;
102     }
103     // update flag
104     if ((rdbGrantInfoList[0].flag & flag) == Want::FLAG_AUTH_PERSISTABLE_URI_PERMISSION) {
105         HILOG_INFO("Update an uri permission info");
106         NativeRdb::ValuesBucket valuesBucket;
107         valuesBucket.PutInt(COLUMN_FLAG, flag);
108         ret = UpdateData(absRdbPredicates, valuesBucket);
109         if (!ret) {
110             HILOG_ERROR("UpdateData failed");
111             return INNER_ERR;
112         }
113         return ERR_OK;
114     }
115     HILOG_INFO("Uri has been granted");
116     return ERR_OK;
117 }
118 
RemoveGrantInfo(uint32_t tokenId,sptr<StorageManager::IStorageManager> storageManager)119 int32_t UriPermissionRdb::RemoveGrantInfo(uint32_t tokenId, sptr<StorageManager::IStorageManager> storageManager)
120 {
121     HILOG_INFO("RemoveGrantInfo, TokenId = %{public}u", tokenId);
122     NativeRdb::AbsRdbPredicates absRdbPredicates(URI_PERMISSION_TABLE_NAME);
123     absRdbPredicates.EqualTo(COLUMN_FROM_TOKEN_ID, std::to_string(tokenId));
124     absRdbPredicates.Or();
125     absRdbPredicates.EqualTo(COLUMN_TARGET_TOKEN_ID, std::to_string(tokenId));
126     int ret = RemoveGrantInfo(absRdbPredicates, storageManager);
127     return ret;
128 }
129 
RemoveGrantInfo(const std::string & uri,uint32_t tokenId,sptr<StorageManager::IStorageManager> storageManager)130 int32_t UriPermissionRdb::RemoveGrantInfo(const std::string &uri, uint32_t tokenId,
131     sptr<StorageManager::IStorageManager> storageManager)
132 {
133     HILOG_INFO("RemoveGrantInfo, uri = %{private}s, TokenId = %{public}u", uri.c_str(), tokenId);
134     NativeRdb::AbsRdbPredicates absRdbPredicates(URI_PERMISSION_TABLE_NAME);
135     absRdbPredicates.EqualTo(COLUMN_URI, uri);
136     absRdbPredicates.EqualTo(COLUMN_TARGET_TOKEN_ID, std::to_string(tokenId));
137     int ret = RemoveGrantInfo(absRdbPredicates, storageManager);
138     return ret;
139 }
140 
RemoveGrantInfo(const NativeRdb::AbsRdbPredicates & absRdbPredicates,sptr<StorageManager::IStorageManager> storageManager)141 int32_t UriPermissionRdb::RemoveGrantInfo(const NativeRdb::AbsRdbPredicates &absRdbPredicates,
142     sptr<StorageManager::IStorageManager> storageManager)
143 {
144     if (storageManager == nullptr) {
145         HILOG_ERROR("storageManager is nullptr!");
146         return INNER_ERR;
147     }
148     std::map<unsigned int, std::vector<std::string>> uriLists;
149     int rowCount;
150     std::vector<RdbGrantInfo> rdbGrantInfoList;
151     bool ret = QueryData(absRdbPredicates, rdbGrantInfoList, rowCount);
152     if (!ret) {
153         return INNER_ERR;
154     }
155     for (const auto &info : rdbGrantInfoList) {
156         uriLists[info.targetTokenId].emplace_back(info.uri);
157     }
158     // 1. delete share file
159     for (auto iter = uriLists.begin(); iter != uriLists.end(); iter++) {
160         storageManager->DeleteShareFile(iter->first, iter->second);
161     }
162     // 2. delete rdb data
163     HILOG_DEBUG("total %{public}u uri permissions info to be removed", rowCount);
164     ret = DeleteData(absRdbPredicates);
165     if (!ret) {
166         HILOG_ERROR("RemoveGrantInfo failed");
167         return INNER_ERR;
168     }
169     return ERR_OK;
170 }
171 
CheckPersistableUriPermissionProxy(const std::string & uri,uint32_t flag,uint32_t tokenId)172 bool UriPermissionRdb::CheckPersistableUriPermissionProxy(const std::string& uri, uint32_t flag, uint32_t tokenId)
173 {
174     // check if the uri has flag permission
175     HILOG_DEBUG("CheckPersistablekUriPermissionProxy: uri = %{private}s, flag = %{public}i,\
176         callerTokenId = %{public}i", uri.c_str(), flag, tokenId);
177     NativeRdb::AbsRdbPredicates absRdbPredicates(URI_PERMISSION_TABLE_NAME);
178     absRdbPredicates.EqualTo(COLUMN_URI, uri);
179     absRdbPredicates.EqualTo(COLUMN_TARGET_TOKEN_ID, std::to_string(tokenId));
180     int rowCount;
181     std::vector<RdbGrantInfo> rdbGrantInfoList;
182     bool ret = QueryData(absRdbPredicates, rdbGrantInfoList, rowCount);
183     flag &= (~Want::FLAG_AUTH_PERSISTABLE_URI_PERMISSION);
184     if (ret && rowCount > 0) {
185         for (const auto &info : rdbGrantInfoList) {
186             if (((info.flag | Want::FLAG_AUTH_READ_URI_PERMISSION) & flag) != 0) {
187                 HILOG_DEBUG("CheckUriPermissionProxy ok.");
188                 return true;
189             }
190         }
191     }
192     HILOG_DEBUG("CheckUriPermissionProxy failed.");
193     return false;
194 }
195 
ShowAllGrantInfo()196 void UriPermissionRdb::ShowAllGrantInfo()
197 {
198     NativeRdb::AbsRdbPredicates absRdbPredicates(URI_PERMISSION_TABLE_NAME);
199     std::vector<RdbGrantInfo> rdbGrantInfoList;
200     int rowCount;
201     bool ret = QueryData(absRdbPredicates, rdbGrantInfoList, rowCount);
202     if (!ret) {
203         HILOG_WARN("failed to query");
204     }
205 }
206 
GetGrantInfo(std::shared_ptr<NativeRdb::AbsSharedResultSet> absSharedResultSet,std::vector<RdbGrantInfo> & rdbGrantInfoList)207 bool UriPermissionRdb::GetGrantInfo(std::shared_ptr<NativeRdb::AbsSharedResultSet> absSharedResultSet,
208     std::vector<RdbGrantInfo> &rdbGrantInfoList)
209 {
210     if (absSharedResultSet == nullptr) {
211         return false;
212     }
213     std::string uri;
214     bool ret = absSharedResultSet->GetString(COLUMN_URI_INDEX, uri);
215     if (ret != NativeRdb::E_OK) {
216         HILOG_ERROR("Get COLUMN_URI_INDEX  failed");
217         return false;
218     }
219     int flag;
220     ret = absSharedResultSet->GetInt(COLUMN_FLAG_INDEX, flag);
221     if (ret != NativeRdb::E_OK) {
222         HILOG_ERROR("Get COLUMN_TARGET_TOKEN_ID_INDEX failed");
223         return false;
224     }
225     int targetTokenId;
226     ret = absSharedResultSet->GetInt(COLUMN_TARGET_TOKEN_ID_INDEX, targetTokenId);
227     if (ret != NativeRdb::E_OK) {
228         HILOG_ERROR("Get COLUMN_FLAG_INDEX failed");
229         return false;
230     }
231     int fromTokenId;
232     ret = absSharedResultSet->GetInt(COLUMN_FROM_TOKEN_ID_INDEX, fromTokenId);
233     if (ret != NativeRdb::E_OK) {
234         HILOG_ERROR("Get COLUMN_FROM_TOKEN_ID_INDEX failed");
235         return false;
236     }
237     RdbGrantInfo grantInfo = { uri, flag, static_cast<uint32_t>(fromTokenId), static_cast<uint32_t>(targetTokenId) };
238     rdbGrantInfoList.push_back(grantInfo);
239     return true;
240 }
241 
QueryData(const NativeRdb::AbsRdbPredicates & absRdbPredicates,std::vector<RdbGrantInfo> & rdbGrantInfoList,int & rowCount)242 bool UriPermissionRdb::QueryData(const NativeRdb::AbsRdbPredicates &absRdbPredicates,
243     std::vector<RdbGrantInfo> &rdbGrantInfoList, int &rowCount)
244 {
245     auto absSharedResultSet = rdbDataManager_->QueryData(absRdbPredicates);
246     if (absSharedResultSet == nullptr) {
247         HILOG_ERROR("UriPermissionRdb::QueryData failed");
248         return false;
249     }
250     ScopeGuard stateGuard([&] { absSharedResultSet->Close(); });
251     int ret = absSharedResultSet->GetRowCount(rowCount);
252     if (ret != NativeRdb::E_OK) {
253         HILOG_ERROR("GetRowCount failed");
254         return false;
255     }
256     if (rowCount == 0) {
257         HILOG_DEBUG("Query Result, total %{public}i uri", rowCount);
258         return true;
259     }
260     ret = absSharedResultSet->GoToFirstRow();
261     if (ret != NativeRdb::E_OK) {
262         HILOG_ERROR("GoToFirstRow failed");
263         return false;
264     }
265     do {
266         // ger grant info from query result
267         bool result = GetGrantInfo(absSharedResultSet, rdbGrantInfoList);
268         if (!result) {
269             return false;
270         }
271     } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
272     HILOG_DEBUG("Query Result, total %{public}i uri", rowCount);
273     for (const auto &info : rdbGrantInfoList) {
274         PrintRdbGrantInfo(info);
275     }
276     return true;
277 }
278 
InsertData(const std::vector<RdbGrantInfo> & rdbGrantInfoList)279 bool UriPermissionRdb::InsertData(const std::vector<RdbGrantInfo> &rdbGrantInfoList)
280 {
281     std::vector<NativeRdb::ValuesBucket> valuesBuckets;
282     int64_t grantInfoNum = rdbGrantInfoList.size();
283     for (int i = 0; i < grantInfoNum; i++) {
284         NativeRdb::ValuesBucket valuesBucket;
285         valuesBucket.PutString(COLUMN_URI, rdbGrantInfoList[i].uri);
286         valuesBucket.PutInt(COLUMN_FLAG, rdbGrantInfoList[i].flag);
287         valuesBucket.PutInt(COLUMN_FROM_TOKEN_ID, rdbGrantInfoList[i].fromTokenId);
288         valuesBucket.PutInt(COLUMN_TARGET_TOKEN_ID, rdbGrantInfoList[i].targetTokenId);
289         valuesBuckets.push_back(valuesBucket);
290     }
291     bool ret = rdbDataManager_->BatchInsert(grantInfoNum, valuesBuckets);
292     return ret;
293 }
294 
UpdateData(const NativeRdb::AbsRdbPredicates & absRdbPredicates,const NativeRdb::ValuesBucket & valuesBucket)295 bool UriPermissionRdb::UpdateData(const NativeRdb::AbsRdbPredicates &absRdbPredicates,
296     const NativeRdb::ValuesBucket &valuesBucket)
297 {
298     bool ret = rdbDataManager_->UpdateData(valuesBucket, absRdbPredicates);
299     return ret;
300 }
301 
DeleteData(const NativeRdb::AbsRdbPredicates & absRdbPredicates)302 bool UriPermissionRdb::DeleteData(const NativeRdb::AbsRdbPredicates &absRdbPredicates)
303 {
304     bool ret = rdbDataManager_->DeleteData(absRdbPredicates);
305     return ret;
306 }
307 }
308 }
309