merge with master
[platform/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  * @version 1.0
20  * @brief    This file contains the definition of certificate dao class.
21  */
22
23 #include <wrt-commons/certificate-dao/certificate_dao.h>
24 #include <wrt-commons/certificate-dao/certificate_database.h>
25 #include <wrt-commons/certificate-dao/certificate_dao_types.h>
26 #include <orm_generator_certificate.h>
27 #include <dpl/foreach.h>
28 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
29 #include <dpl/wrt-dao-ro/WrtDatabase.h>
30 #include <dpl/wrt-dao-ro/widget_config.h>
31 #include <dpl/wrt-dao-ro/global_config.h>
32 #include <dpl/wrt-dao-ro/common_dao_types.h>
33 #include <sys/stat.h>
34 #include <fstream>
35
36 using namespace DPL::DB::ORM;
37 using namespace DPL::DB::ORM::certificate;
38
39 namespace CertificateDB {
40 #define SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN          Try
41
42 #define SQL_CONNECTION_EXCEPTION_HANDLER_END(message)   \
43     Catch(DPL::DB::SqlConnection::Exception::Base) {       \
44         LogError(message);                              \
45         ReThrowMsg(CertificateDAO::Exception::DatabaseError, \
46                    message);                            \
47     }
48
49 namespace {
50 DPL::DB::SqlConnection::Flag::Option CERTIFICATE_DB_OPTION =
51     DPL::DB::SqlConnection::Flag::RW;
52 DPL::DB::SqlConnection::Flag::Type CERTIFICATE_DB_TYPE =
53     DPL::DB::SqlConnection::Flag::UseLucene;
54 const char* const CERTIFICATE_DB_NAME = ".certificate.db";
55 const char* const CERTIFICATE_DB_SQL_PATH =
56     "/usr/share/wrt-engine/certificate_db.sql";
57 const char* const CERTIFICATE_DATABASE_JOURNAL_FILENAME = "-journal";
58
59 const int WEB_APPLICATION_UID = 5000;
60 const int WEB_APPLICATION_GUID = 5000;
61
62 std::string createDatabasePath(const WrtDB::WidgetPkgName &pkgName)
63 {
64     std::stringstream filename;
65
66     filename << WrtDB::WidgetConfig::GetWidgetPersistentStoragePath(pkgName)
67              << "/"
68              << CERTIFICATE_DB_NAME;
69     return filename.str();
70 }
71
72 std::string createDatabasePath(int widgetHandle)
73 {
74     using namespace DPL::DB::ORM;
75     using namespace WrtDB::WidgetConfig;
76     using namespace WrtDB::GlobalConfig;
77
78     WrtDB::TizenAppId appid;
79
80     Try
81     {
82         appid = WrtDB::WidgetDAOReadOnly::getTzAppId(widgetHandle);
83     }
84     Catch(DPL::DB::SqlConnection::Exception::Base) {
85         LogError("Failed to get database Path");
86     }
87     return createDatabasePath(appid);
88 }
89
90 void checkDatabase(std::string databasePath)
91 {
92     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
93     {
94         if (databasePath.empty()) {
95             ThrowMsg(CertificateDAO::Exception::DatabaseError,
96                      "Wrong database Path is passed");
97         }
98
99         struct stat buffer;
100         if (stat(databasePath.c_str(), &buffer) != 0) {
101             //Create fresh database
102             LogInfo("Creating database " << databasePath);
103
104             std::fstream file;
105             file.open(CERTIFICATE_DB_SQL_PATH, std::ios_base::in);
106             if (!file) {
107                 ThrowMsg(CertificateDAO::Exception::DatabaseError,
108                          "Fail to get database Path");
109             }
110
111             std::stringstream ssBuffer;
112             ssBuffer << file.rdbuf();
113
114             file.close();
115
116             DPL::DB::SqlConnection con(databasePath,
117                                        CERTIFICATE_DB_TYPE,
118                                        CERTIFICATE_DB_OPTION);
119             con.ExecCommand(ssBuffer.str().c_str());
120         }
121
122         if(chown(databasePath.c_str(),
123                  WEB_APPLICATION_UID,
124                  WEB_APPLICATION_GUID) != 0)
125         {
126             ThrowMsg(CertificateDAO::Exception::DatabaseError,
127                  "Fail to change uid/guid");
128         }
129         std::string databaseJournal =
130             databasePath + CERTIFICATE_DATABASE_JOURNAL_FILENAME;
131         if(chown(databaseJournal.c_str(),
132                  WEB_APPLICATION_UID,
133                  WEB_APPLICATION_GUID) != 0)
134         {
135             ThrowMsg(CertificateDAO::Exception::DatabaseError,
136                  "Fail to change uid/guid");
137         }
138     }
139     SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to get database Path")
140 }
141 }
142
143 CertificateDAO::CertificateDAO(const WrtDB::WidgetPkgName &pkgName) :
144     m_certificateDBPath(createDatabasePath(pkgName)),
145     m_certificateDBInterface(m_certificateDBPath, CERTIFICATE_DB_TYPE)
146 {
147     checkDatabase(m_certificateDBPath);
148     m_certificateDBInterface.AttachToThread(CERTIFICATE_DB_OPTION);
149 }
150
151 CertificateDAO::~CertificateDAO()
152 {
153     m_certificateDBInterface.DetachFromThread();
154 }
155
156 CertificateDataList CertificateDAO::getCertificateDataList(void)
157 {
158     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
159     {
160         CertificateDataList list;
161         CERTIFICATE_DB_SELECT(select,
162             CertificateInfo,
163             &m_certificateDBInterface);
164         typedef std::list<CertificateInfo::Row> RowList;
165         RowList rowList = select->GetRowList();
166
167         FOREACH(it, rowList) {
168             list.push_back(
169                 CertificateDataPtr(
170                     new CertificateData(it->Get_certificate())));
171         }
172         return list;
173     }
174     SQL_CONNECTION_EXCEPTION_HANDLER_END("Failed to get data  list")
175 }
176
177 Result CertificateDAO::getResult(
178     const CertificateData &certificateData)
179 {
180     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
181     {
182         CERTIFICATE_DB_SELECT(select,
183             CertificateInfo,
184             &m_certificateDBInterface);
185         select->Where(
186             Equals<CertificateInfo::certificate>(certificateData.certificate));
187         CertificateInfo::Select::RowList rows = select->GetRowList();
188
189         if (rows.empty()) {
190             return RESULT_UNKNOWN;
191         }
192         CertificateInfo::Row row = rows.front();
193         return static_cast<Result>(row.Get_result());
194     }
195     SQL_CONNECTION_EXCEPTION_HANDLER_END(
196         "Failed to get result for security certiInfo")
197 }
198
199 void CertificateDAO::setCertificateData(const CertificateData &certificateData,
200     const Result result)
201 {
202     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
203     {
204         ScopedTransaction transaction(&m_certificateDBInterface);
205         CertificateInfo::Row row;
206         row.Set_certificate(certificateData.certificate);
207         row.Set_result(result);
208
209         if (true == hasResult(certificateData)) {
210             CERTIFICATE_DB_UPDATE(update,
211                 CertificateInfo,
212                 &m_certificateDBInterface);
213             update->Values(row);
214             update->Execute();
215         } else {
216             CERTIFICATE_DB_INSERT(insert,
217                 CertificateInfo,
218                 &m_certificateDBInterface);
219             insert->Values(row);
220             insert->Execute();
221         }
222         transaction.Commit();
223     }
224     SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to set security certiInfo data")
225 }
226
227 void CertificateDAO::removeCertificateData(
228     const CertificateData &certificateData)
229 {
230     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
231     {
232         ScopedTransaction transaction(&m_certificateDBInterface);
233
234         if (true == hasResult(certificateData)) {
235             CERTIFICATE_DB_DELETE(del,
236                 CertificateInfo,
237                 &m_certificateDBInterface)
238             del->Where(
239                 Equals<CertificateInfo::certificate>(certificateData.certificate));
240             del->Execute();
241             transaction.Commit();
242         }
243     }
244     SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to set certiInfo data")
245 }
246
247 void CertificateDAO::removeCertificateData(const Result result)
248 {
249     SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
250     {
251         ScopedTransaction transaction(&m_certificateDBInterface);
252         CERTIFICATE_DB_DELETE(del,
253                                   CertificateInfo,
254                                   &m_certificateDBInterface)
255         del->Where(Equals<CertificateInfo::result>(result));
256         del->Execute();
257         transaction.Commit();
258     }
259     SQL_CONNECTION_EXCEPTION_HANDLER_END("Fail to remove data by result")
260 }
261
262 bool CertificateDAO::hasResult(const CertificateData &certificateData)
263 {
264     Result res = getResult(certificateData);
265     return (res != RESULT_UNKNOWN);
266 }
267
268 #undef SQL_CONNECTION_EXCEPTION_HANDLER_BEGIN
269 #undef SQL_CONNECTION_EXCEPTION_HANDLER_END
270 } // namespace CertificateDB