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 "app_domain_verify_rdb_data_manager.h"
17 #include <string>
18 #include "app_domain_verify_hilog.h"
19 #include "scope_guard.h"
20 #include "inner_verify_status.h"
21 
22 namespace OHOS {
23 namespace AppDomainVerify {
24 const std::string DB_BUNDLE_NAME = "BUNDLE_NAME";
25 const std::string DB_APP_IDENTIFIER = "APP_IDENTIFIER";
26 const std::string DB_DOMAIN = "DOMAIN";
27 const std::string DB_STATUES = "VERIFY_STATUES";
28 const std::string DB_VERIFY_TIME = "VERIFY_TIME";
29 const std::string DB_VERIFY_COUNT = "VERIFY_COUNT";
30 const int32_t DB_BUNDLE_NAME_INDEX = 1;
31 const int32_t DB_APP_IDENTIFIER_INDEX = 2;
32 const int32_t DB_DOMAIN_INDEX = 3;
33 const int32_t DB_STATUES_INDEX = 4;
34 const int32_t DB_VERIFY_TIME_INDEX = 5;
35 const int32_t DB_VERIFY_COUNT_INDEX = 6;
36 const int32_t CLOSE_TIME = 20;  // delay 20s stop rdbStore
37 
AppDomainVerifyRdbDataManager(const AppDomainVerifyRdbConfig & rdbConfig)38 AppDomainVerifyRdbDataManager::AppDomainVerifyRdbDataManager(const AppDomainVerifyRdbConfig& rdbConfig)
39     : appDomainVerifyRdbConfig_(rdbConfig)
40 {
41     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "new instance create.");
42     DeleteIfCannotAccess();
43 }
DeleteIfCannotAccess()44 void AppDomainVerifyRdbDataManager::DeleteIfCannotAccess()
45 {
46     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "DeleteIfCannotAccess.");
47     auto rdbFile = appDomainVerifyRdbConfig_.dbPath + appDomainVerifyRdbConfig_.dbName;
48     // �ļ����ڵ���û�ж�дȨ�ޣ�ɾ���ļ�
49     if (access(rdbFile.c_str(), F_OK) == 0 && access(rdbFile.c_str(), R_OK | W_OK) != 0) {
50         auto ret = remove(rdbFile.c_str());
51         APP_DOMAIN_VERIFY_HILOGW(
52             APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "DeleteIfCannotAccess remove, ret:%{public}d.", ret);
53     }
54     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "DeleteIfCannotAccess end.");
55 }
~AppDomainVerifyRdbDataManager()56 AppDomainVerifyRdbDataManager::~AppDomainVerifyRdbDataManager()
57 {
58     rdbStore_ = nullptr;
59     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "instance dead.");
60 }
61 
InsertData(const RdbDataItem & rdbDataItem)62 bool AppDomainVerifyRdbDataManager::InsertData(const RdbDataItem& rdbDataItem)
63 {
64     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
65     auto rdbStore = GetRdbStore();
66     if (!CheckRdbStoreExist(rdbStore)) {
67         return false;
68     }
69     int64_t rowId = -1;
70     NativeRdb::ValuesBucket valuesBucket;
71     valuesBucket.PutString(DB_BUNDLE_NAME, rdbDataItem.bundleName);
72     valuesBucket.PutString(DB_APP_IDENTIFIER, rdbDataItem.appIdentifier);
73     valuesBucket.PutString(DB_DOMAIN, rdbDataItem.domain);
74     valuesBucket.PutInt(DB_STATUES, rdbDataItem.status);
75     valuesBucket.PutString(DB_VERIFY_TIME, rdbDataItem.verifyTs);
76     valuesBucket.PutInt(DB_VERIFY_COUNT, rdbDataItem.count);
77     auto ret = rdbStore->InsertWithConflictResolution(
78         rowId, appDomainVerifyRdbConfig_.tableName, valuesBucket, NativeRdb::ConflictResolution::ON_CONFLICT_REPLACE);
79     return CheckRdbReturnIfOk(ret);
80 }
81 
QueryDomainByBundleName(const std::string & bundleName,std::vector<RdbDataItem> & items)82 bool AppDomainVerifyRdbDataManager::QueryDomainByBundleName(
83     const std::string& bundleName, std::vector<RdbDataItem>& items)
84 {
85     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
86     NativeRdb::AbsRdbPredicates absRdbPredicates(appDomainVerifyRdbConfig_.tableName);
87     absRdbPredicates.EqualTo(DB_BUNDLE_NAME, bundleName)->And()->EqualTo(DB_STATUES, InnerVerifyStatus::STATE_SUCCESS);
88     std::vector<std::string> columns = {};
89     return Query(absRdbPredicates, columns, items);
90 }
QueryBundleNameByDomain(const std::string & domain,std::vector<RdbDataItem> & items)91 bool AppDomainVerifyRdbDataManager::QueryBundleNameByDomain(const std::string& domain, std::vector<RdbDataItem>& items)
92 {
93     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
94     NativeRdb::AbsRdbPredicates absRdbPredicates(appDomainVerifyRdbConfig_.tableName);
95     absRdbPredicates.EqualTo(DB_DOMAIN, domain)->And()->EqualTo(DB_STATUES, InnerVerifyStatus::STATE_SUCCESS);
96     std::vector<std::string> columns = {};
97 
98     return Query(absRdbPredicates, columns, items);
99 }
Query(const NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns,std::vector<RdbDataItem> & items)100 bool AppDomainVerifyRdbDataManager::Query(const NativeRdb::AbsRdbPredicates& predicates,
101     const std::vector<std::string>& columns, std::vector<RdbDataItem>& items)
102 {
103     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
104     auto rdbStore = GetRdbStore();
105     if (!CheckRdbStoreExist(rdbStore)) {
106         return false;
107     }
108     auto absSharedResultSet = rdbStore->Query(predicates, columns);
109     if (absSharedResultSet == nullptr) {
110         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdbStore query absSharedResultSet failed");
111         return false;
112     }
113     ScopeGuard stateGuard([&] { absSharedResultSet->Close(); });
114     if (!absSharedResultSet->HasBlock()) {
115         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "absSharedResultSet has no block");
116         return false;
117     }
118 
119     if (CheckRdbReturnIfOk(absSharedResultSet->GoToFirstRow())) {
120         do {
121             RdbDataItem item;
122             if (!CheckRdbReturnIfOk(absSharedResultSet->GetString(DB_BUNDLE_NAME_INDEX, item.bundleName)) ||
123                 !CheckRdbReturnIfOk(absSharedResultSet->GetString(DB_APP_IDENTIFIER_INDEX, item.appIdentifier)) ||
124                 !CheckRdbReturnIfOk(absSharedResultSet->GetString(DB_DOMAIN_INDEX, item.domain)) ||
125                 !CheckRdbReturnIfOk(absSharedResultSet->GetInt(DB_STATUES_INDEX, item.status)) ||
126                 !CheckRdbReturnIfOk(absSharedResultSet->GetString(DB_VERIFY_TIME_INDEX, item.verifyTs)) ||
127                 !CheckRdbReturnIfOk(absSharedResultSet->GetInt(DB_VERIFY_COUNT_INDEX, item.count))) {
128                 return false;
129             }
130             items.emplace_back(item);
131         } while (absSharedResultSet->GoToNextRow() == NativeRdb::E_OK);
132     } else {
133         APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "GoToFirstRow fail, seems rdb table is empty");
134     }
135     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
136     return true;
137 }
DeleteData(const std::string & bundleName)138 bool AppDomainVerifyRdbDataManager::DeleteData(const std::string& bundleName)
139 {
140     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
141     auto rdbStore = GetRdbStore();
142     if (!CheckRdbStoreExist(rdbStore)) {
143         return false;
144     }
145     int32_t rowId = -1;
146     NativeRdb::AbsRdbPredicates absRdbPredicates(appDomainVerifyRdbConfig_.tableName);
147     absRdbPredicates.EqualTo(DB_BUNDLE_NAME, bundleName);
148     auto ret = rdbStore->Delete(rowId, absRdbPredicates);
149     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
150     return CheckRdbReturnIfOk(ret);
151 }
152 
QueryAllData(std::unordered_map<std::string,std::vector<RdbDataItem>> & dataMap)153 bool AppDomainVerifyRdbDataManager::QueryAllData(std::unordered_map<std::string, std::vector<RdbDataItem>>& dataMap)
154 {
155     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
156     auto rdbStore = GetRdbStore();
157     if (!CheckRdbStoreExist(rdbStore)) {
158         return false;
159     }
160     NativeRdb::AbsRdbPredicates absRdbPredicates(appDomainVerifyRdbConfig_.tableName);
161     std::vector<RdbDataItem> items;
162     std::vector<std::string> columns = {};
163     if (!Query(absRdbPredicates, columns, items)) {
164         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "Query failed.");
165         return false;
166     }
167 
168     dataMap.clear();
169     for (auto item : items) {
170         if (dataMap.count(item.bundleName) != 0) {
171             dataMap[item.bundleName].emplace_back(item);
172         } else {
173             std::vector<RdbDataItem> tmpItems;
174             tmpItems.emplace_back(item);
175             dataMap.insert(std::make_pair(item.bundleName, tmpItems));
176         }
177     }
178 
179     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
180     return true;
181 }
182 
CreateTable()183 bool AppDomainVerifyRdbDataManager::CreateTable()
184 {
185     std::string createTableSql;
186     if (appDomainVerifyRdbConfig_.createTableSql.empty()) {
187         createTableSql = std::string("CREATE TABLE IF NOT EXISTS " + appDomainVerifyRdbConfig_.tableName +
188             "(ID INTEGER PRIMARY KEY AUTOINCREMENT, BUNDLE_NAME TEXT NOT NULL, APP_IDENTIFIER TEXT, " +
189             "DOMAIN TEXT NOT NULL, VERIFY_STATUES INTEGER, VERIFY_TIME TEXT NOT NULL, VERIFY_COUNT INTEGER);");
190     } else {
191         createTableSql = appDomainVerifyRdbConfig_.createTableSql;
192     }
193     auto rdbStore = GetRdbStore();
194     if (CheckRdbStoreExist(rdbStore) && CheckRdbReturnIfOk(rdbStore->ExecuteSql(createTableSql))) {
195         return true;
196     }
197     return false;
198 }
199 
DelayCloseRdbStore()200 void AppDomainVerifyRdbDataManager::DelayCloseRdbStore()
201 {
202     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
203     if (continuationHandler_ == nullptr) {
204         continuationHandler_ = std::make_shared<ffrt::queue>("RdbContinuationMgr");
205     }
206     std::weak_ptr<AppDomainVerifyRdbDataManager> weakPtr = shared_from_this();
207     auto func = [weakPtr]() {
208         APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "DelayCloseRdbStore thread begin");
209         std::this_thread::sleep_for(std::chrono::seconds(CLOSE_TIME));
210         auto sharedPtr = weakPtr.lock();
211         if (sharedPtr == nullptr) {
212             return;
213         }
214         std::lock_guard<std::mutex> lock(sharedPtr->rdbMutex_);
215         sharedPtr->rdbStore_ = nullptr;
216         APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "DelayCloseRdbStore thread end");
217     };
218     continuationHandler_->submit(func);
219     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
220 }
221 
GetRdbStore()222 std::shared_ptr<NativeRdb::RdbStore> AppDomainVerifyRdbDataManager::GetRdbStore()
223 {
224     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "called");
225     std::lock_guard<std::mutex> lock(rdbMutex_);
226     if (rdbStore_ != nullptr) {
227         return rdbStore_;
228     }
229     NativeRdb::RdbStoreConfig rdbStoreConfig(appDomainVerifyRdbConfig_.dbPath + appDomainVerifyRdbConfig_.dbName);
230     rdbStoreConfig.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
231     int32_t errCode = NativeRdb::E_OK;
232     AppDomainVerifyRdbOpenCallback appDomainVerifyRdbOpenCallback(appDomainVerifyRdbConfig_);
233     rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(
234         rdbStoreConfig, appDomainVerifyRdbConfig_.version, appDomainVerifyRdbOpenCallback, errCode);
235     DelayCloseRdbStore();
236     APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "call end");
237     return rdbStore_;
238 }
239 
CheckRdbReturnIfOk(int errcode)240 bool AppDomainVerifyRdbDataManager::CheckRdbReturnIfOk(int errcode)
241 {
242     if (errcode != NativeRdb::E_OK) {
243         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "rdb failed, ret: %{public}d", errcode);
244         return false;
245     }
246     return true;
247 }
248 
CheckRdbStoreExist(const std::shared_ptr<NativeRdb::RdbStore> & rdbStore)249 bool AppDomainVerifyRdbDataManager::CheckRdbStoreExist(const std::shared_ptr<NativeRdb::RdbStore>& rdbStore)
250 {
251     if (rdbStore == nullptr) {
252         APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "RdbStore is null");
253         return false;
254     }
255     return true;
256 }
257 }  // namespace AppDomainVerify
258 }  // namespace OHOS