• 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 "database_helper.h"
17 #include <sstream>
18 #include <array>
19 #include <cinttypes>
20 #include "i_model_info.h"
21 #include "security_guard_define.h"
22 #include "security_guard_log.h"
23 
24 namespace OHOS::Security::SecurityGuard {
DatabaseHelper(std::string dbTable)25 DatabaseHelper::DatabaseHelper(std::string dbTable)
26 {
27     dbTable_ = dbTable;
28 }
29 
Init()30 int DatabaseHelper::Init()
31 {
32     return SUCCESS;
33 }
34 
Release()35 void DatabaseHelper::Release()
36 {
37 }
38 
InsertEvent(const SecEvent & event)39 int DatabaseHelper::InsertEvent(const SecEvent& event)
40 {
41     GenericValues values;
42     SetValuesBucket(event, values);
43     int64_t rowId;
44     int ret = Insert(rowId, dbTable_, values);
45     if (ret != SUCCESS) {
46         SGLOGI("failed to add event, eventId=%{public}" PRId64 ", ret=%{public}d", event.eventId, ret);
47         return FAILED;
48     }
49     return SUCCESS;
50 }
51 
QueryAllEvent(std::vector<SecEvent> & events)52 int DatabaseHelper::QueryAllEvent(std::vector<SecEvent> &events)
53 {
54     return QueryEventBase({}, events, {});
55 }
56 
QueryRecentEventByEventId(int64_t eventId,SecEvent & event)57 int DatabaseHelper::QueryRecentEventByEventId(int64_t eventId, SecEvent &event)
58 {
59     std::vector<SecEvent> results;
60     QueryOptions options;
61     options.orderBy = std::string(ID) + " DESC";
62     options.limit = 1;
63     GenericValues conditions;
64     conditions.Put(EVENT_ID, std::to_string(eventId));
65     int ret = QueryEventBase(conditions, results, options);
66     if (ret == SUCCESS && !results.empty()) {
67         event = results[0];
68         return SUCCESS;
69     }
70     return FAILED;
71 }
72 
QueryRecentEventByEventId(const std::vector<int64_t> & eventIds,std::vector<SecEvent> & events)73 int DatabaseHelper::QueryRecentEventByEventId(const std::vector<int64_t> &eventIds, std::vector<SecEvent> &events)
74 {
75     if (eventIds.empty()) {
76         return FAILED;
77     }
78 
79     std::vector<std::string> idStrList;
80     for (const auto &id: eventIds) {
81         idStrList.push_back(std::to_string(id));
82     }
83 
84     GenericValues conditions;
85     conditions.Put(std::string(EVENT_ID) + "_IN", Join(idStrList, ","));
86 
87     QueryOptions options;
88     options.orderBy = std::string(DATE) + " DESC";
89     options.limit = 1;
90     int ret = QueryEventBase(conditions, events, options);
91     if (ret != SUCCESS) {
92         SGLOGE("query fail");
93         events.clear();
94     }
95     return ret;
96 }
97 
QueryEventByEventId(int64_t eventId,std::vector<SecEvent> & events)98 int DatabaseHelper::QueryEventByEventId(int64_t eventId, std::vector<SecEvent> &events)
99 {
100     GenericValues conditions;
101     conditions.Put(EVENT_ID, std::to_string(eventId));
102     return QueryEventBase(conditions, events);
103 }
104 
QueryEventByEventId(std::vector<int64_t> & eventIds,std::vector<SecEvent> & events)105 int DatabaseHelper::QueryEventByEventId(std::vector<int64_t> &eventIds, std::vector<SecEvent> &events)
106 {
107     if (eventIds.empty()) {
108         return BAD_PARAM;
109     }
110 
111     std::ostringstream oss;
112     for (size_t i = 0; i < eventIds.size(); ++i) {
113         if (i > 0) {
114             oss << ",";
115         }
116         oss << eventIds[i];
117     }
118 
119     GenericValues conditions;
120     conditions.Put(std::string(EVENT_ID) + "_IN", oss.str());
121     return QueryEventBase(conditions, events);
122 }
123 
QueryEventByEventIdAndDate(std::vector<int64_t> & eventIds,std::vector<SecEvent> & events,std::string beginTime,std::string endTime)124 int DatabaseHelper::QueryEventByEventIdAndDate(std::vector<int64_t> &eventIds, std::vector<SecEvent> &events,
125     std::string beginTime, std::string endTime)
126 {
127     if (eventIds.empty()) {
128         return BAD_PARAM;
129     }
130 
131     GenericValues conditions;
132     conditions.Put(std::string(EVENT_ID) + "_IN", Join(eventIds, ","));
133     if (!beginTime.empty()) {
134         conditions.Put(std::string(DATE) + "_GE", beginTime);
135     }
136 
137     if (!endTime.empty()) {
138         conditions.Put(std::string(DATE) + "_LT", endTime);
139     }
140     return QueryEventBase(conditions, events);
141 }
142 
QueryEventByEventType(int32_t eventType,std::vector<SecEvent> & events)143 int DatabaseHelper::QueryEventByEventType(int32_t eventType, std::vector<SecEvent> &events)
144 {
145     GenericValues conditions;
146     conditions.Put(EVENT_TYPE, std::to_string(eventType));
147     return QueryEventBase(conditions, events);
148 }
149 
QueryEventByLevel(int32_t level,std::vector<SecEvent> & events)150 int DatabaseHelper::QueryEventByLevel(int32_t level, std::vector<SecEvent> &events)
151 {
152     GenericValues conditions;
153     conditions.Put(DATA_SENSITIVITY_LEVEL, std::to_string(level));
154     return QueryEventBase(conditions, events);
155 }
156 
QueryEventByOwner(std::string owner,std::vector<SecEvent> & events)157 int DatabaseHelper::QueryEventByOwner(std::string owner, std::vector<SecEvent> &events)
158 {
159     GenericValues conditions;
160     std::string safeOwner = FilterSpecialChars(owner);
161     conditions.Put(std::string(OWNER) + "_LIKE", "%" + safeOwner + "%");
162     return QueryEventBase(conditions, events);
163 }
164 
CountAllEvent()165 int64_t DatabaseHelper::CountAllEvent()
166 {
167     int64_t count;
168     int ret = Count(count, dbTable_, {});
169     if (ret != SUCCESS) {
170         SGLOGE("failed to count event, ret=%{public}d", ret);
171     }
172     return count;
173 }
174 
CountEventByEventId(int64_t eventId)175 int64_t DatabaseHelper::CountEventByEventId(int64_t eventId)
176 {
177     int64_t count;
178     GenericValues conditions;
179     conditions.Put(EVENT_ID, std::to_string(eventId));
180     int ret = Count(count, dbTable_, conditions);
181     if (ret != SUCCESS) {
182         SGLOGE("failed to count event, eventId=%{public}" PRId64 ", ret=%{public}d", eventId, ret);
183     }
184     return count;
185 }
186 
DeleteOldEventByEventId(int64_t eventId,int64_t count)187 int DatabaseHelper::DeleteOldEventByEventId(int64_t eventId, int64_t count)
188 {
189     if (count <= 0 || eventId < 0) {
190         return BAD_PARAM;
191     }
192     GenericValues conditions;
193     conditions.Put(EVENT_ID, std::to_string(eventId));
194     QueryOptions options;
195     options.orderBy = std::string(DATE) + " ASC";
196     options.limit = static_cast<int>(count);
197     options.columns = {ID};
198 
199     std::vector<GenericValues> idResults;
200     int ret = Query(dbTable_, conditions, idResults, options);
201     if (ret != SUCCESS || idResults.empty()) {
202         return ret;
203     }
204 
205     std::vector<std::string> primaryKeys;
206     for (const auto& row: idResults) {
207         primaryKeys.push_back(std::to_string(row.GetInt64(ID)));
208     }
209 
210     GenericValues deleteConditions;
211     deleteConditions.Put(std::string(ID) + "_IN", Join(primaryKeys, ","));
212     int deleteRows = 0;
213     return Delete(deleteRows, dbTable_, deleteConditions);
214 }
215 
DeleteAllEventByEventId(int64_t eventId)216 int DatabaseHelper::DeleteAllEventByEventId(int64_t eventId)
217 {
218     if (eventId < 0) {
219         return BAD_PARAM;
220     }
221     GenericValues conditions;
222     conditions.Put(EVENT_ID, std::to_string(eventId));
223     int deleteRows = 0;
224     return Delete(deleteRows, dbTable_, conditions);
225 }
226 
FlushAllEvent()227 int DatabaseHelper::FlushAllEvent()
228 {
229     return SUCCESS;
230 }
231 
QueryEventBase(const GenericValues & conditions,std::vector<SecEvent> & events,const QueryOptions & options)232 int DatabaseHelper::QueryEventBase(const GenericValues &conditions, std::vector<SecEvent> &events,
233     const QueryOptions &options)
234 {
235     std::vector<GenericValues> queryResults;
236     QueryOptions baseOptions = options;
237     baseOptions.columns = {EVENT_ID, VERSION, DATE, CONTENT, USER_ID, DEVICE_ID};
238 
239     int ret = Query(dbTable_, conditions, queryResults, baseOptions);
240     if (ret != SUCCESS) {
241         return ret;
242     }
243 
244     for (const auto& row : queryResults) {
245         events.emplace_back(
246             SecEvent{
247                 .eventId = row.GetInt64(EVENT_ID),
248                 .date = row.GetString(DATE),
249                 .content = row.GetString(CONTENT),
250                 .userId = row.GetInt(USER_ID),
251                 .deviceId = row.GetString(DEVICE_ID)
252             }
253         );
254     }
255 
256     return SUCCESS;
257 }
258 
SetValuesBucket(const SecEvent & event,GenericValues & values)259 void DatabaseHelper::SetValuesBucket(const SecEvent &event, GenericValues &values)
260 {
261     values.Put(EVENT_ID, event.eventId);
262     values.Put(VERSION, event.version);
263     values.Put(DATE, event.date);
264     values.Put(CONTENT, event.content);
265     values.Put(EVENT_TYPE, event.eventType);
266     values.Put(DATA_SENSITIVITY_LEVEL, event.dataSensitivityLevel);
267     values.Put(OWNER, event.owner);
268     values.Put(USER_ID, event.userId);
269     values.Put(DEVICE_ID, event.deviceId);
270 }
271 
CreateTable()272 std::string DatabaseHelper::CreateTable()
273 {
274     std::string table;
275     table.append("CREATE TABLE IF NOT EXISTS ").append(dbTable_);
276     table.append("(").append(ID).append(" INTEGER PRIMARY KEY AUTOINCREMENT, ");
277     table.append(EVENT_ID).append(" INTEGER NOT NULL, ");
278     table.append(VERSION).append(" TEXT NOT NULL, ");
279     table.append(DATE).append(" TEXT NOT NULL, ");
280     table.append(CONTENT).append(" TEXT NOT NULL, ");
281     table.append(EVENT_TYPE).append(" INTEGER NOT NULL, ");
282     table.append(DATA_SENSITIVITY_LEVEL).append(" INTEGER NOT NULL, ");
283     table.append(OWNER).append(" TEXT NOT NULL, ");
284     table.append(USER_ID).append(" INTEGER NOT NULL, ");
285     table.append(DEVICE_ID).append(" TEXT NOT NULL)");
286     return table;
287 }
288 
FilterSpecialChars(const std::string & input)289 std::string DatabaseHelper::FilterSpecialChars(const std::string &input)
290 {
291     std::string filtered;
292     for (auto c : input) {
293         if (isalnum(c) || c == '_' || c == '%') {
294             filtered += c;
295         }
296     }
297 
298     return filtered;
299 }
300 
Join(const std::vector<int64_t> & vec,const std::string delimiter)301 std::string DatabaseHelper::Join(const std::vector<int64_t> &vec, const std::string delimiter)
302 {
303     if (vec.empty()) {
304         return "";
305     }
306 
307     std::ostringstream oss;
308     oss << vec[0];
309 
310     for (size_t i = 1; i < vec.size(); ++i) {
311         oss << delimiter << vec[i];
312     }
313 
314     return oss.str();
315 }
316 
Join(const std::vector<std::string> & vec,const std::string delimiter)317 std::string DatabaseHelper::Join(const std::vector<std::string> &vec, const std::string delimiter)
318 {
319     if (vec.empty()) {
320         return "";
321     }
322 
323     std::string result;
324     bool isFirst = true;
325     for (const auto &str : vec) {
326         if (!isFirst) {
327             result += delimiter;
328         }
329         result += str;
330         isFirst = false;
331     }
332 
333     return result;
334 }
335 
336 } // namespace OHOS::Security::SecurityGuard