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