2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file security_origin_dao.cpp
18 * @author Jihoon Chung (jihoon.chung@samsung.com)
19 * @author Kamil Lysik (k.lysik@samsung.com)
21 * @brief This file contains the definition of security origin dao class.
24 #include <wrt-commons/security-origin-dao/security_origin_dao.h>
25 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
26 #include <dpl/wrt-dao-ro/WrtDatabase.h>
27 #include <dpl/wrt-dao-ro/widget_config.h>
28 #include <dpl/wrt-dao-ro/global_config.h>
29 #include <dpl/wrt-dao-ro/common_dao_types.h>
30 #include <dpl/log/wrt_log.h>
36 namespace SecurityOriginDB {
37 using namespace WrtDB;
38 #define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN Try
40 #define SQL_CONNECTION_EXCEPTION_HANDLER_END(message) \
41 Catch(DPL::DB::SqlConnection::Exception::Base) { \
43 ReThrowMsg(SecurityOriginDAO::Exception::DatabaseError, \
48 DPL::DB::SqlConnection::Flag::Option SECURITY_ORIGIN_DB_OPTION =
49 DPL::DB::SqlConnection::Flag::RW;
50 DPL::DB::SqlConnection::Flag::Type SECURITY_ORIGIN_DB_TYPE =
51 DPL::DB::SqlConnection::Flag::UseLucene;
53 const char* const SECURITY_ORIGIN_DB_NAME = ".security_origin.db";
54 const char* const SECURITY_ORIGIN_DB_SQL_PATH =
55 "/usr/share/wrt-engine/security_origin_db.sql";
56 const char* const SECURITY_DATABASE_JOURNAL_FILENAME = "-journal";
59 const char* const SELECT_ORIGIN_DATA_LIST =
60 "select scheme,host,port,feature from SecurityOriginInfo";
61 const char* const SELECT_ORIGIN_GET_RESULT =
62 "select result from SecurityOriginInfo"
63 " where feature=? and scheme=? and host=? and port=?";
64 const char* const SELECT_ORIGIN_GET_READONLY =
65 "select readonly from SecurityOriginInfo"
66 " where feature=? and scheme=? and host=? and port=?";
67 const char* const DELETE_SECURITY_ORIGIN =
68 "delete from SecurityOriginInfo"
69 " where feature=? and scheme=? and host=? and port=?";
70 const char* const DELETE_SECURITY_ORIGIN_BY_RESULT =
71 "delete from SecurityOriginInfo"
73 const char* const INSERT_SECURITY_ORIGIN =
74 "insert into SecurityOriginInfo (feature, scheme, host, port, result, readonly)"
75 "values (?, ?, ?, ?, ?, ?)";
76 const char* const UPDATE_SECURITY_ORIGIN =
77 "update SecurityOriginInfo"
78 " set result=?, readonly=?"
79 " where feature=? and scheme=? and host=? and port=?";
81 const int WEB_APPLICATION_UID = 5000;
82 const int WEB_APPLICATION_GUID = 5000;
84 std::string createDatabasePath(const WrtDB::TizenPkgId &pkgName)
86 std::stringstream filename;
88 filename << WrtDB::WidgetConfig::GetWidgetPersistentStoragePath(pkgName)
90 << SECURITY_ORIGIN_DB_NAME;
91 return filename.str();
94 void checkDatabase(std::string databasePath)
96 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
98 if (databasePath.empty()) {
99 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError,
100 "Wrong database Path is passed");
104 if (stat(databasePath.c_str(), &buffer) != 0) {
105 //Create fresh database
106 WrtLogD("Creating database %s", databasePath.c_str());
109 file.open(SECURITY_ORIGIN_DB_SQL_PATH, std::ios_base::in);
111 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError,
112 "Fail to get database Path");
115 std::stringstream ssBuffer;
116 ssBuffer << file.rdbuf();
120 DPL::DB::SqlConnection con(databasePath,
121 SECURITY_ORIGIN_DB_TYPE,
122 SECURITY_ORIGIN_DB_OPTION);
123 con.ExecCommand(ssBuffer.str().c_str());
125 if(chown(databasePath.c_str(),
127 WEB_APPLICATION_GUID) != 0)
129 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError,
130 "Fail to change uid/guid");
132 std::string databaseJournal =
133 databasePath + SECURITY_DATABASE_JOURNAL_FILENAME;
134 if(chown(databaseJournal.c_str(),
136 WEB_APPLICATION_GUID) != 0)
138 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError,
139 "Fail to change uid/guid");
143 SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to get database Path")
145 } // anonymous namespace
147 SecurityOriginDAO::SecurityOriginDAO(const WrtDB::TizenPkgId &pkgName)
149 std::string dbPath = createDatabasePath(pkgName);
150 checkDatabase(dbPath);
151 if (DB_UTIL_OK != db_util_open_with_options(
153 &m_databaseInterface,
154 SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX,
156 WrtLogE("Cannot open database. %s", sqlite3_errmsg(m_databaseInterface));
157 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "Cannot open database");
161 SecurityOriginDAO::~SecurityOriginDAO()
165 SecurityOriginDataList SecurityOriginDAO::getSecurityOriginDataList(void)
167 std::lock_guard<std::mutex> lock(m_dbLock);
168 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
170 sqlite3_stmt* stmt = sqlPrepare(SELECT_ORIGIN_DATA_LIST);
171 int rw = sqlite3_step(stmt);
173 SecurityOriginDataList list;
174 while (SQLITE_ROW == rw)
177 Origin origin((sqlite3_column_string(stmt, 0)),
178 (sqlite3_column_string(stmt, 1)),
179 sqlite3_column_int(stmt, 2));
181 SecurityOriginDataPtr(
182 new SecurityOriginData(
183 static_cast<Feature>(sqlite3_column_int(stmt, 3)), origin)));
185 rw = sqlite3_step(stmt);
187 releaseStatement(stmt);
189 if (SQLITE_DONE != rw)
192 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
193 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "getSecurityOriginDataList fail");
198 SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get data list")
201 Result SecurityOriginDAO::getResult(const SecurityOriginData &data)
203 std::lock_guard<std::mutex> lock(m_dbLock);
204 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
206 Result retval = RESULT_UNKNOWN;
207 sqlite3_stmt* stmt = sqlPrepare(SELECT_ORIGIN_GET_RESULT);
208 sqlBind(stmt, 1, data.feature);
209 sqlBind(stmt, 2, data.origin.scheme);
210 sqlBind(stmt, 3, data.origin.host);
211 sqlBind(stmt, 4, data.origin.port);
212 int rw = sqlite3_step(stmt);
213 if (SQLITE_ROW == rw)
215 retval = static_cast<Result>(sqlite3_column_int(stmt, 0));
218 releaseStatement(stmt);
219 if (SQLITE_DONE != rw && SQLITE_ROW != rw)
221 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
222 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "getResult fail");
226 SQL_CONNECTION_EXCEPTION_HANDLER_END("getResult error")
229 bool SecurityOriginDAO::isReadOnly(const SecurityOriginData &data)
231 std::lock_guard<std::mutex> lock(m_dbLock);
232 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
235 sqlite3_stmt* stmt = sqlPrepare(SELECT_ORIGIN_GET_READONLY);
236 sqlBind(stmt, 1, data.feature);
237 sqlBind(stmt, 2, data.origin.scheme);
238 sqlBind(stmt, 3, data.origin.host);
239 sqlBind(stmt, 4, data.origin.port);
240 int rw = sqlite3_step(stmt);
241 if (SQLITE_ROW == rw)
243 retval = static_cast<int>(sqlite3_column_int(stmt, 0));
246 releaseStatement(stmt);
247 if (SQLITE_DONE != rw && SQLITE_ROW != rw)
249 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
250 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "isReadOnly fail");
254 SQL_CONNECTION_EXCEPTION_HANDLER_END("isReadOnly error")
257 void SecurityOriginDAO::setSecurityOriginData(const SecurityOriginData &data,
261 if (true == hasResult(data)) {
262 updateData(data, result, readOnly);
264 insertData(data, result, readOnly);
268 void SecurityOriginDAO::setPrivilegeSecurityOriginData(
269 const Feature feature,
270 bool isOnlyAllowedLocalOrigin)
272 //TODO: this breaks app:// scheme code -> no case for app scheme
273 Origin origin(DPL::FromUTF8String("file"),
274 DPL::FromUTF8String(""),
276 if (!isOnlyAllowedLocalOrigin) {
277 origin.scheme = DPL::FromUTF8String("");
279 SecurityOriginData data(feature, origin);
280 setSecurityOriginData(data, RESULT_ALLOW_ALWAYS, true);
283 void SecurityOriginDAO::removeSecurityOriginData(const SecurityOriginData &data)
285 if (false == hasResult(data)) {
290 std::lock_guard<std::mutex> lock(m_dbLock);
291 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
293 sqlite3_stmt* stmt = sqlPrepare(DELETE_SECURITY_ORIGIN);
294 sqlBind(stmt, 1, data.feature);
295 sqlBind(stmt, 2, data.origin.scheme);
296 sqlBind(stmt, 3, data.origin.host);
297 sqlBind(stmt, 4, data.origin.port);
300 int rw = sqlite3_step(stmt);
301 releaseStatement(stmt);
302 if (SQLITE_DONE != rw)
304 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
305 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "removeSecurityOriginData fail");
308 SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to remove security origin data")
311 void SecurityOriginDAO::removeSecurityOriginData(const Result result)
313 std::lock_guard<std::mutex> lock(m_dbLock);
314 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
316 sqlite3_stmt* stmt = sqlPrepare(DELETE_SECURITY_ORIGIN_BY_RESULT);
317 sqlBind(stmt, 1, static_cast<int>(result));
320 int rw = sqlite3_step(stmt);
321 releaseStatement(stmt);
322 if (SQLITE_DONE != rw)
324 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
325 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "removeSecurityOriginData fail");
328 SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to remove data by result")
331 bool SecurityOriginDAO::hasResult(const SecurityOriginData &data)
333 Result ret = getResult(data);
334 return (ret != RESULT_UNKNOWN);
337 void SecurityOriginDAO::insertData(const SecurityOriginData &data,
341 std::lock_guard<std::mutex> lock(m_dbLock);
342 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
344 sqlite3_stmt* stmt = sqlPrepare(INSERT_SECURITY_ORIGIN);
345 sqlBind(stmt, 1, data.feature);
346 sqlBind(stmt, 2, data.origin.scheme);
347 sqlBind(stmt, 3, data.origin.host);
348 sqlBind(stmt, 4, data.origin.port);
349 sqlBind(stmt, 5, static_cast<int>(result));
350 sqlBind(stmt, 6, readOnly ? 1 : 0);
353 int rw = sqlite3_step(stmt);
354 releaseStatement(stmt);
355 if (SQLITE_DONE != rw)
357 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
358 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "insertData fail");
361 SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to insert")
364 void SecurityOriginDAO::updateData(const SecurityOriginData &data,
368 std::lock_guard<std::mutex> lock(m_dbLock);
369 SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
371 sqlite3_stmt* stmt = sqlPrepare(UPDATE_SECURITY_ORIGIN);
373 sqlBind(stmt, 1, static_cast<int>(result));
374 sqlBind(stmt, 2, readOnly ? 1 : 0);
376 sqlBind(stmt, 3, data.feature);
377 sqlBind(stmt, 4, data.origin.scheme);
378 sqlBind(stmt, 5, data.origin.host);
379 sqlBind(stmt, 6, data.origin.port);
382 int rw = sqlite3_step(stmt);
383 releaseStatement(stmt);
384 if (SQLITE_DONE != rw)
386 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
387 ThrowMsg(SecurityOriginDAO::Exception::DatabaseError, "updateData fail");
390 SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to update")
393 } // namespace SecurityOriginDB