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 "ohos_web_permission_data_base_adapter_impl.h"
17 #include <cinttypes>
18 #include <unistd.h>
19 #include "foundation/ability/ability_runtime/interfaces/kits/native/appkit/ability_runtime/context/application_context.h"
20 #include "nweb_log.h"
21 #include "sqlite_database_utils.h"
22
23 using namespace OHOS::NativeRdb;
24 using namespace OHOS::NWeb;
25
26 namespace {
27 const int32_t RDB_VERSION = 1;
28 const std::string WEB_PERMISSION_DATABASE_FILE = "web_permission.db";
29
30 const std::string ID_COL = "_id";
31 const std::string GEOLOCATION_TABLE_NAME = "geolocation";
32 const std::string PERMISSION_ORIGIN_COL = "origin";
33 const std::string PERMISSION_RESULT_COL = "result";
34
35 const std::string CREATE_TABLE = "CREATE TABLE " + GEOLOCATION_TABLE_NAME
36 + " (" + ID_COL + " INTEGER PRIMARY KEY, "
37 + PERMISSION_ORIGIN_COL + " TEXT, " + PERMISSION_RESULT_COL + " INTEGER, "
38 + " UNIQUE (" + PERMISSION_ORIGIN_COL + ") ON CONFLICT REPLACE);";
39
40 const std::string WEB_PATH = "/web";
41 }
42
OnCreate(OHOS::NativeRdb::RdbStore & store)43 int32_t PermissionDataBaseRdbOpenCallBack::OnCreate(OHOS::NativeRdb::RdbStore& store)
44 {
45 WVLOG_I("web permission database opened, create table: %{public}s", CREATE_TABLE.c_str());
46 return store.ExecuteSql(CREATE_TABLE);
47 }
48
OnUpgrade(OHOS::NativeRdb::RdbStore & rdbStore,int32_t currentVersion,int32_t targetVersion)49 int32_t PermissionDataBaseRdbOpenCallBack::OnUpgrade(OHOS::NativeRdb::RdbStore& rdbStore,
50 int32_t currentVersion, int32_t targetVersion)
51 {
52 WVLOG_I("web permission database upgrade");
53 return OHOS::NativeRdb::E_OK;
54 }
55
GetInstance()56 OhosWebPermissionDataBaseAdapterImpl& OhosWebPermissionDataBaseAdapterImpl::GetInstance()
57 {
58 WVLOG_I("webdatabase get permission data base instance");
59 static OhosWebPermissionDataBaseAdapterImpl instance;
60 return instance;
61 }
62
CreateDataBase(const std::string & dataBeseName,OHOS::NativeRdb::RdbOpenCallback & callBack)63 std::shared_ptr<OHOS::NativeRdb::RdbStore> OhosWebPermissionDataBaseAdapterImpl::CreateDataBase(
64 const std::string& dataBeseName, OHOS::NativeRdb::RdbOpenCallback& callBack)
65 {
66 WVLOG_I("web permission database create rdb store");
67 std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore = nullptr;
68 std::shared_ptr<AbilityRuntime::ApplicationContext> context =
69 OHOS::AbilityRuntime::ApplicationContext::GetApplicationContext();
70 if (context == nullptr) {
71 WVLOG_E("web permission database get context failed");
72 return rdbStore;
73 }
74
75 std::string databaseDir = context->GetCacheDir() + WEB_PATH;
76 if (access(databaseDir.c_str(), F_OK) != 0) {
77 WVLOG_I("web permission database fail to access cache web dir:%{public}s", databaseDir.c_str());
78 return rdbStore;
79 }
80
81 std::string bundleName = context->GetBundleName();
82 std::string name = dataBeseName;
83 int32_t errorCode = E_OK;
84 std::string realPath = SqliteDatabaseUtils::GetDefaultDatabasePath(databaseDir, name, errorCode);
85 RdbStoreConfig config("");
86 config.SetPath(std::move(realPath));
87 config.SetBundleName(bundleName);
88 config.SetName(std::move(name));
89 config.SetArea(context->GetArea());
90 WVLOG_I("web permission database databaseDir=%{public}s", databaseDir.c_str());
91 WVLOG_I("web permission database bundleName=%{public}s", bundleName.c_str());
92
93 int32_t errCode = NativeRdb::E_OK;
94 rdbStore = RdbHelper::GetRdbStore(config, RDB_VERSION, callBack, errCode);
95 WVLOG_I("web permission database create rdb store end, errCode=%{public}d", errCode);
96 return rdbStore;
97 }
98
OhosWebPermissionDataBaseAdapterImpl()99 OhosWebPermissionDataBaseAdapterImpl::OhosWebPermissionDataBaseAdapterImpl()
100 {
101 PermissionDataBaseRdbOpenCallBack callBack;
102 rdbStore_ = OhosWebPermissionDataBaseAdapterImpl::CreateDataBase(WEB_PERMISSION_DATABASE_FILE, callBack);
103 }
104
KeyToTableName(const WebPermissionType & key) const105 std::string OhosWebPermissionDataBaseAdapterImpl::KeyToTableName(const WebPermissionType& key) const
106 {
107 if (key == WebPermissionType::GEOLOCATION) {
108 return GEOLOCATION_TABLE_NAME;
109 }
110 return "";
111 }
112
ExistPermissionByOrigin(const std::string & origin,const WebPermissionType & key) const113 bool OhosWebPermissionDataBaseAdapterImpl::ExistPermissionByOrigin(const std::string& origin,
114 const WebPermissionType& key) const
115 {
116 WVLOG_I("web permission database check exist permissions origin=%{public}s info", origin.c_str());
117 if (rdbStore_ == nullptr || origin.empty()) {
118 return false;
119 }
120 std::string tableName = KeyToTableName(key);
121 if (tableName.empty()) {
122 return false;
123 }
124
125 std::unique_ptr<AbsSharedResultSet> resultSet = nullptr;
126 std::vector<std::string> columns;
127 NativeRdb::AbsRdbPredicates dirAbsPred(tableName);
128 dirAbsPred.EqualTo(PERMISSION_ORIGIN_COL, origin);
129 resultSet = rdbStore_->Query(dirAbsPred, columns);
130 if ((resultSet == nullptr) || (resultSet->GoToFirstRow() != NativeRdb::E_OK)) {
131 WVLOG_E("web permissions database rdb store query failed");
132 return false;
133 }
134 return true;
135 }
136
GetPermissionResultByOrigin(const std::string & origin,const WebPermissionType & key,bool & result) const137 bool OhosWebPermissionDataBaseAdapterImpl::GetPermissionResultByOrigin(const std::string& origin,
138 const WebPermissionType& key, bool& result) const
139 {
140 WVLOG_I("web permission database get permissions origin=%{public}s info", origin.c_str());
141 if (rdbStore_ == nullptr || origin.empty()) {
142 return false;
143 }
144 std::string tableName = KeyToTableName(key);
145 if (tableName.empty()) {
146 return false;
147 }
148 std::unique_ptr<AbsSharedResultSet> resultSet = nullptr;
149 std::vector<std::string> columns;
150 NativeRdb::AbsRdbPredicates dirAbsPred(tableName);
151 dirAbsPred.EqualTo(PERMISSION_ORIGIN_COL, origin);
152 resultSet = rdbStore_->Query(dirAbsPred, columns);
153 if ((resultSet == nullptr) || (resultSet->GoToFirstRow() != NativeRdb::E_OK)) {
154 WVLOG_E("web permissions database rdb store query failed");
155 return false;
156 }
157
158 int32_t columnIndex;
159 int32_t resultVal = 0;
160 resultSet->GetColumnIndex(PERMISSION_RESULT_COL, columnIndex);
161 resultSet->GetInt(columnIndex, resultVal);
162 result = resultVal ? true : false;
163 return true;
164 }
165
SetPermissionByOrigin(const std::string & origin,const WebPermissionType & key,bool result)166 void OhosWebPermissionDataBaseAdapterImpl::SetPermissionByOrigin(const std::string& origin,
167 const WebPermissionType& key, bool result)
168 {
169 WVLOG_I("web permission database set info origin:%{public}s key:%{public}d", origin.c_str(), key);
170 if (rdbStore_ == nullptr || origin.empty()) {
171 return;
172 }
173 std::string tableName = KeyToTableName(key);
174 if (tableName.empty()) {
175 return;
176 }
177 int32_t errCode;
178 int64_t outRowId;
179 NativeRdb::ValuesBucket valuesBucket;
180 valuesBucket.Clear();
181 valuesBucket.PutString(PERMISSION_ORIGIN_COL, origin);
182 valuesBucket.PutInt(PERMISSION_RESULT_COL, (int)result);
183 errCode = rdbStore_->Insert(outRowId, tableName, valuesBucket);
184 WVLOG_I("web permission database set info end, errCode=%{public}d", errCode);
185 }
186
ClearPermissionByOrigin(const std::string & origin,const WebPermissionType & key)187 void OhosWebPermissionDataBaseAdapterImpl::ClearPermissionByOrigin(const std::string& origin,
188 const WebPermissionType& key)
189 {
190 if (rdbStore_ == nullptr || origin.empty()) {
191 return;
192 }
193 WVLOG_I("web permission database clear origin:%{public}s info", origin.c_str());
194 std::string tableName = KeyToTableName(key);
195 if (tableName.empty()) {
196 return;
197 }
198 int32_t deletedRows = 0;
199 NativeRdb::AbsRdbPredicates dirAbsPred(tableName);
200 dirAbsPred.EqualTo(PERMISSION_ORIGIN_COL, origin);
201 int32_t ret = rdbStore_->Delete(deletedRows, dirAbsPred);
202 WVLOG_I("web permission database clear info: ret=%{public}d, deletedRows=%{public}d", ret, deletedRows);
203 }
204
ClearAllPermission(const WebPermissionType & key)205 void OhosWebPermissionDataBaseAdapterImpl::ClearAllPermission(const WebPermissionType& key)
206 {
207 if (rdbStore_ == nullptr) {
208 return;
209 }
210 std::string tableName = KeyToTableName(key);
211 if (tableName.empty()) {
212 return;
213 }
214 WVLOG_I("web permission database clear all permission:%{public}s info", tableName.c_str());
215
216 int32_t deletedRows = 0;
217 NativeRdb::AbsRdbPredicates dirAbsPred(tableName);
218 int32_t ret = rdbStore_->Delete(deletedRows, dirAbsPred);
219 WVLOG_I("web permission database clear all info: ret=%{public}d, deletedRows=%{public}d", ret, deletedRows);
220 }
221
GetOriginsByPermission(const WebPermissionType & key,std::vector<std::string> & origins) const222 void OhosWebPermissionDataBaseAdapterImpl::GetOriginsByPermission(const WebPermissionType& key,
223 std::vector<std::string>& origins) const
224 {
225 if (rdbStore_ == nullptr) {
226 return;
227 }
228 std::string tableName = KeyToTableName(key);
229 if (tableName.empty()) {
230 return;
231 }
232 std::vector<std::string> columns;
233 NativeRdb::AbsRdbPredicates dirAbsPred(tableName);
234 std::unique_ptr<AbsSharedResultSet> resultSet = rdbStore_->Query(dirAbsPred, columns);
235 if ((resultSet == nullptr) || (resultSet->GoToFirstRow() != NativeRdb::E_OK)) {
236 WVLOG_E("web permissions database rdb store query failed");
237 return;
238 }
239 int32_t columnIndex;
240 resultSet->GetColumnIndex(PERMISSION_ORIGIN_COL, columnIndex);
241 WVLOG_I("web permission database origin columnIndex:%{public}d", columnIndex);
242 do {
243 std::string origin;
244 resultSet->GetString(columnIndex, origin);
245 origins.push_back(origin);
246 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
247 }