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