tizen 2.4 release
[framework/web/wrt-commons.git] / modules / certificate_dao / dao / certificate_dao.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /*
17  * @file    certificate_dao.cpp
18  * @author  Leerang Song (leerang.song@samsung.com)
19  * @author  Wojciech Kosowicz (w.kosowicz@samsung.com
20  * @version 1.0
21  * @brief    This file contains the definition of certificate dao class.
22  */
23
24 #include <wrt-commons/certificate-dao/certificate_dao.h>
25 #include <wrt-commons/certificate-dao/certificate_database.h>
26 #include <wrt-commons/certificate-dao/certificate_dao_types.h>
27 #include <orm_generator_certificate.h>
28 #include <dpl/foreach.h>
29 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
30 #include <dpl/wrt-dao-ro/WrtDatabase.h>
31 #include <dpl/wrt-dao-ro/widget_config.h>
32 #include <dpl/wrt-dao-ro/global_config.h>
33 #include <dpl/wrt-dao-ro/common_dao_types.h>
34 #include <sys/stat.h>
35 #include <dpl/log/wrt_log.h>
36 #include <db-util.h>
37 #include <fstream>
38 /* GCC versions 4.7 had changes to the C++ standard. It
39  * no longer includes <unistd.h> to remove namespace pollution.
40  */
41 #include <unistd.h>
42
43 using namespace DPL::DB::ORM;
44 using namespace DPL::DB::ORM::certificate;
45
46 namespace CertificateDB {
47 #define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN          Try
48
49 #define SQL_CONNECTION_EXCEPTION_HANDLER_END(message)   \
50     Catch(DPL::DB::SqlConnection::Exception::Base) {       \
51         WrtLogE(message);                              \
52         ReThrowMsg(CertificateDAO::Exception::DatabaseError, \
53                    message);                            \
54     }
55
56 namespace {
57 DPL::DB::SqlConnection::Flag::Option CERTIFICATE_DB_OPTION =
58     DPL::DB::SqlConnection::Flag::RW;
59 DPL::DB::SqlConnection::Flag::Type CERTIFICATE_DB_TYPE =
60     DPL::DB::SqlConnection::Flag::UseLucene;
61 const char* const CERTIFICATE_DB_NAME = ".certificate.db";
62 const char* const CERTIFICATE_DB_SQL_PATH =
63     "/usr/share/wrt-engine/certificate_db.sql";
64 const char* const CERTIFICATE_DATABASE_JOURNAL_FILENAME = "-journal";
65 const char* const SELECT_CERTIFICATE_DATA_LIST =
66         "select certificate from CertificateInfo";
67 const char* const SELECT_CERTIFICATE_GET_RESULT =
68         "select result from CertificateInfo"
69         " where certificate=?";
70 const char* const INSERT_CERTIFICATE =
71         "insert into CertificateInfo (certificate, result)"
72         " values (?, ?)";
73 const char* const UPDATE_CERTIFICATE =
74         "update CertificateInfo set result=?"
75         " where certificate=?";
76 const char* const DELETE_CERTIFICATE =
77         "delete from CertificateInfo"
78         " where certificate=?";
79 const char* const DELETE_CERTIFICATE_BY_RESULT =
80         "delete from CertificateInfo"
81         " where result=?";
82
83 const int WEB_APPLICATION_UID = 5000;
84 const int WEB_APPLICATION_GUID = 5000;
85
86 std::string createDatabasePath(const WrtDB::TizenPkgId &pkgName)
87 {
88     std::stringstream filename;
89
90     filename << WrtDB::WidgetConfig::GetWidgetPersistentStoragePath(pkgName)
91              << "/"
92              << CERTIFICATE_DB_NAME;
93     return filename.str();
94 }
95
96 void checkDatabase(std::string databasePath)
97 {
98     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
99     {
100         if (databasePath.empty()) {
101             ThrowMsg(CertificateDAO::Exception::DatabaseError,
102                      "Wrong database Path is passed");
103         }
104
105         struct stat buffer;
106         if (stat(databasePath.c_str(), &buffer) != 0) {
107             //Create fresh database
108             WrtLogD("Creating database %s", databasePath.c_str());
109
110             std::fstream file;
111             file.open(CERTIFICATE_DB_SQL_PATH, std::ios_base::in);
112             if (!file) {
113                 ThrowMsg(CertificateDAO::Exception::DatabaseError,
114                          "Fail to get database schema from: " << CERTIFICATE_DB_SQL_PATH);
115             }
116
117             std::stringstream ssBuffer;
118             ssBuffer << file.rdbuf();
119
120             file.close();
121
122             DPL::DB::SqlConnection con(databasePath,
123                                        CERTIFICATE_DB_TYPE,
124                                        CERTIFICATE_DB_OPTION);
125             con.ExecCommand(ssBuffer.str().c_str());
126         }
127
128         if(chown(databasePath.c_str(),
129                  WEB_APPLICATION_UID,
130                  WEB_APPLICATION_GUID) != 0)
131         {
132             ThrowMsg(CertificateDAO::Exception::DatabaseError,
133                  "Fail to change uid/guid");
134         }
135         std::string databaseJournal =
136             databasePath + CERTIFICATE_DATABASE_JOURNAL_FILENAME;
137         if(chown(databaseJournal.c_str(),
138                  WEB_APPLICATION_UID,
139                  WEB_APPLICATION_GUID) != 0)
140         {
141             ThrowMsg(CertificateDAO::Exception::DatabaseError,
142                  "Fail to change uid/guid");
143         }
144     }
145     SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to get database Path")
146 }
147 }
148
149 CertificateDAO::CertificateDAO(const WrtDB::TizenPkgId &pkgName)
150 {
151     std::string dbPath = createDatabasePath(pkgName);
152     checkDatabase(dbPath);
153     if (DB_UTIL_OK != db_util_open_with_options(
154                             dbPath.c_str(),
155                             &m_databaseInterface,
156                             SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX,
157                             NULL)) {
158         WrtLogE("Cannot open database. %s", sqlite3_errmsg(m_databaseInterface));
159         ThrowMsg(CertificateDAO::Exception::DatabaseError, "Cannot open database");
160     }
161 }
162
163 CertificateDAO::~CertificateDAO()
164 {
165 }
166
167 CertificateDataList CertificateDAO::getCertificateDataList(void)
168 {
169     std::lock_guard<std::mutex> lock(m_dbLock);
170     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
171     {
172         sqlite3_stmt* stmt = sqlPrepare(SELECT_CERTIFICATE_DATA_LIST);
173         int rw = sqlite3_step(stmt);
174
175         CertificateDataList list;
176         while (SQLITE_ROW == rw) {
177             //Read from row
178             list.push_back(
179                 CertificateDataPtr(
180                     new CertificateData(sqlite3_column_string(stmt, 0))));
181             //Next row
182             rw = sqlite3_step(stmt);
183         }
184         releaseStatement(stmt);
185         if (SQLITE_DONE != rw) {
186             //Error occurede
187             WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
188             ThrowMsg(CertificateDAO::Exception::DatabaseError, "getSecurityOriginDataList fail");
189         }
190         return list;
191     }
192     SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get data  list")
193 }
194
195 Result CertificateDAO::getResult(
196     const CertificateData &certificateData)
197 {
198     std::lock_guard<std::mutex> lock(m_dbLock);
199     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
200     {
201         Result retval = RESULT_UNKNOWN;
202         sqlite3_stmt* stmt = sqlPrepare(SELECT_CERTIFICATE_GET_RESULT);
203         sqlBind(stmt, 1, certificateData.certificate);
204         int rw = sqlite3_step(stmt);
205         if (SQLITE_ROW == rw) {
206             retval = static_cast<Result>(sqlite3_column_int(stmt, 0));
207         }
208         releaseStatement(stmt);
209         if (SQLITE_DONE != rw && SQLITE_ROW != rw) {
210             WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
211             ThrowMsg(CertificateDAO::Exception::DatabaseError, "getResult fail");
212         }
213         return retval;
214     }
215     SQL_CONNECTION_EXCEPTION_HANDLER_END("getResult error")
216 }
217
218 void CertificateDAO::setCertificateData(const CertificateData &certificateData,
219     const Result result)
220 {
221     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
222     {
223         if (true == hasResult(certificateData)) {
224             std::lock_guard<std::mutex> lock(m_dbLock);
225             sqlite3_stmt* stmt = sqlPrepare(UPDATE_CERTIFICATE);
226             sqlBind(stmt, 1, static_cast<int>(result));
227             sqlBind(stmt, 2, certificateData.certificate);
228             int rw = sqlite3_step(stmt);
229             releaseStatement(stmt);
230             if (SQLITE_DONE != rw) {
231                 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
232                 ThrowMsg(CertificateDAO::Exception::DatabaseError, "updateData fail");
233             }
234         } else {
235             std::lock_guard<std::mutex> lock(m_dbLock);
236             sqlite3_stmt* stmt = sqlPrepare(INSERT_CERTIFICATE);
237             sqlBind(stmt, 1, certificateData.certificate);
238             sqlBind(stmt, 2, static_cast<int>(result));
239             int rw = sqlite3_step(stmt);
240             releaseStatement(stmt);
241             if (SQLITE_DONE != rw)
242             {
243                 WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
244                 ThrowMsg(CertificateDAO::Exception::DatabaseError, "insertData fail");
245             }
246         }
247     }
248     SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to set security certiInfo data")
249 }
250
251 void CertificateDAO::removeCertificateData(
252     const CertificateData &certificateData)
253 {
254     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
255     {
256         sqlite3_stmt* stmt = sqlPrepare(DELETE_CERTIFICATE);
257         sqlBind(stmt, 1, certificateData.certificate);
258         int rw = sqlite3_step(stmt);
259         releaseStatement(stmt);
260         if (SQLITE_DONE != rw) {
261             WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
262             ThrowMsg(CertificateDAO::Exception::DatabaseError, "failed to delete certificate");
263         }
264     }
265     SQL_CONNECTION_EXCEPTION_HANDLER_END("failed to delete certificate")
266 }
267
268 void CertificateDAO::removeCertificateData(const Result result)
269 {
270     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
271     {
272         std::lock_guard<std::mutex> lock(m_dbLock);
273         sqlite3_stmt* stmt = sqlPrepare(DELETE_CERTIFICATE_BY_RESULT);
274         sqlBind(stmt, 1, static_cast<int>(result));
275         int rw = sqlite3_step(stmt);
276         releaseStatement(stmt);
277         if (SQLITE_DONE != rw) {
278             WrtLogE("sqlite3_step error. %s", sqlite3_errmsg(m_databaseInterface));
279             ThrowMsg(CertificateDAO::Exception::DatabaseError, "failed to delete certificate");
280         }
281     }
282     SQL_CONNECTION_EXCEPTION_HANDLER_END("failed to delete certificate")
283 }
284
285 bool CertificateDAO::hasResult(const CertificateData &certificateData)
286 {
287     Result res = getResult(certificateData);
288     return (res != RESULT_UNKNOWN);
289 }
290
291 } // namespace CertificateDB