Source code formating unification
[platform/framework/web/wrt.git] / src / view / common / view_logic_password_support.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    view_logic_password_support.cpp
18  * @author  Pawel Sikorski (p.sikorski@samsung.com)
19  * @brief   Implementation file of PasswordSupport API used by ViewLogic
20  */
21 #include "view_logic_password_support.h"
22
23 #include <string>
24 #include <memory>
25 #include <dpl/assert.h>
26 #include <dpl/log/log.h>
27 #include <dpl/scoped_ptr.h>
28 #include <dpl/scoped_fclose.h>
29 #include <dpl/string.h>
30 #include <dpl/optional_typedefs.h>
31 #include <dpl/foreach.h>
32 #include <wrt-commons/auto-save-dao-rw/auto_save_dao.h>
33 #include <popup-runner/PopupInvoker.h>
34
35 #include <Eina.h>
36 #include <iri.h>
37 #include <vconf.h>
38
39 namespace ViewModule {
40 namespace PasswordSupport {
41 namespace {
42 const char *SCHEME_TYPE_HTTP = "http";
43 const char *SCHEME_TYPE_HTTPS = "https";
44 const char *AUTOSAVEIDPASS_OFF = "OFF";
45 const char *AUTOSAVEIDPASS_ON = "ON";
46 const char *AUTOSAVEIDPASS_ALWAYS_ASK = "ALWAYS_ASK";
47 // This message isn't confirmed by UX guide
48 // It should be change to use IDS for translate
49 const char AUTOSAVE_ASK_MSG[] = "Do you want to remember the password on ";
50 const char AUTOSAVE_ASK_TITLE[] = "Ask to save ID, password";
51
52 const char * const COMMA = ",";
53 const char * const DOUBLE_QUOTES = "\"";
54 const char * const FILE_PATH_AUTOSAVE_JS = "/usr/share/wrt-engine/AutoSave.js";
55 const char * const FILE_OPTION_READ = "r";
56 const std::string JS_KEY_TAG = "$KEY";
57 const std::string JS_VALUE_TAG = "$VALUE";
58 const unsigned int MIN_SUBMIT_FORM_DATA_SIZE = 0;
59
60 // Internal declaration
61 Eina_Bool submitFormDataSet(const Eina_Hash* hash,
62                             const void* key,
63                             void* data,
64                             void* fdata);
65
66 Eina_Bool submitFormDataSet(const Eina_Hash* /*hash*/,
67                             const void* key,
68                             void* data,
69                             void* fdata)
70 {
71     using namespace AutoSaveDB;
72     SubmitFormData *submitFormData = static_cast<SubmitFormData*>(fdata);
73
74     if (!key ||
75         !data ||
76         strlen(static_cast<const char *>(key)) == 0 ||
77         strlen(static_cast<char *>(data)) == 0)
78     {
79         LogDebug("input data is empty");
80         return EINA_TRUE;
81     }
82
83     SubmitFormElement element;
84     element.key = DPL::FromUTF8String(static_cast<const char *>(key));
85     element.value = DPL::FromUTF8String(static_cast<char *>(data));
86     (*submitFormData).push_back(element);
87
88     return EINA_TRUE;
89 }
90 }
91
92 void submitClicked(std::string uri, Eina_Hash* data)
93 {
94     using namespace AutoSaveDB;
95
96     LogDebug("submitClicked called");
97
98     // Temporary set to "always ask"
99     // After implement setting menu and database, it will be used that
100     const char* const autoSaveStatus = AUTOSAVEIDPASS_ALWAYS_ASK;
101
102     // check setting is always off
103     if (!strcmp(autoSaveStatus, AUTOSAVEIDPASS_OFF)) {
104         LogDebug("AutoSaveStatus is AUTOSAVEIDPASS_ALWAYS_OFF");
105         return;
106     }
107
108     std::unique_ptr<iri_t> iri(iri_parse(uri.c_str()));
109     if (!iri.get()) {
110         LogDebug("Fail to get iri");
111         return;
112     }
113     DPL::String host;
114     if (strstr(uri.c_str(), SCHEME_TYPE_HTTP) == uri.c_str() ||
115         strstr(uri.c_str(), SCHEME_TYPE_HTTPS) == uri.c_str())
116     {
117         if (NULL == iri->host) {
118             LogDebug("host is invalid");
119             return;
120         }
121         host = DPL::FromASCIIString(std::string(iri->host));
122     } else {
123         if (NULL == iri->path) {
124             LogDebug("path is invalid");
125             return;
126         }
127         // case of local file, store full path
128         host = DPL::FromASCIIString(std::string(iri->path));
129     }
130
131     SubmitFormData submitFormData;
132     eina_hash_foreach(data, submitFormDataSet, &submitFormData);
133
134     if (MIN_SUBMIT_FORM_DATA_SIZE == submitFormData.size()) {
135         LogDebug("not enough data size " << submitFormData.size());
136         return;
137     }
138
139     if (!strcmp(autoSaveStatus, AUTOSAVEIDPASS_ON)) {
140         LogDebug("AutoSaveStatus is AUTOSAVEIDPASS_ALWAYS_ON");
141         AutoSaveDAO::setAutoSaveSubmitFormData(host, submitFormData);
142     } else if (!strcmp(autoSaveStatus, AUTOSAVEIDPASS_ALWAYS_ASK)) {
143         LogDebug("AutoSaveStatus is AUTOSAVEIDPASS_ALWAYS_ASK");
144         // show popup
145         bool answer = Wrt::Popup::PopupInvoker().askYesNo(AUTOSAVE_ASK_TITLE,
146                                                           AUTOSAVE_ASK_MSG);
147         if (answer) {
148             LogDebug("save data");
149             AutoSaveDAO::setAutoSaveSubmitFormData(host, submitFormData);
150         }
151         return;
152     }
153 }
154
155 DPL::Optional<DPL::String> jsForAutoFillData(const char *uri)
156 {
157     using namespace AutoSaveDB;
158
159     LogDebug("jsForAutoFillData called");
160     Assert(uri);
161
162     // check uri is invalid
163     std::unique_ptr<iri_t> iri(iri_parse(uri));
164     if (!iri.get()) {
165         LogDebug("Fail to get iri");
166         return DPL::OptionalString::Null;
167     }
168     DPL::String host;
169     if (strstr(uri, SCHEME_TYPE_HTTP) == uri ||
170         strstr(uri, SCHEME_TYPE_HTTPS) == uri)
171     {
172         if (NULL == iri->host) {
173             LogDebug("host is invalid");
174             return DPL::OptionalString::Null;
175         }
176         host = DPL::FromASCIIString(std::string(iri->host));
177     } else {
178         if (NULL == iri->path) {
179             LogDebug("path is invalid");
180             return DPL::OptionalString::Null;
181         }
182         // case of local file, compare fullpath
183         host = DPL::FromASCIIString(std::string(iri->path));
184     }
185     SubmitFormData submitData =
186         AutoSaveDAOReadOnly::getAutoSaveSubmitFormData(host);
187
188     if (submitData.empty()) {
189         LogDebug("no matching data");
190         return DPL::OptionalString::Null;
191     }
192
193     std::ostringstream keyOstring;
194     std::ostringstream valueOstring;
195     // "Email", "Passwd"
196     // "xxx", "xxx"
197     FOREACH(iterator, submitData) {
198         keyOstring << DOUBLE_QUOTES << iterator->key << DOUBLE_QUOTES;
199         valueOstring << DOUBLE_QUOTES << iterator->value << DOUBLE_QUOTES;
200         if (*iterator != submitData.back()) {
201             keyOstring << COMMA;
202             valueOstring << COMMA;
203         }
204     }
205
206     DPL::ScopedFClose fd;
207     fd.Reset(fopen(FILE_PATH_AUTOSAVE_JS, FILE_OPTION_READ));
208     if (!fd) {
209         LogError("Fail to open");
210         return DPL::OptionalString::Null;
211     }
212
213     fseek(fd.Get(), 0, SEEK_END);
214     long size = ftell(fd.Get());
215     fseek(fd.Get(), 0, SEEK_SET);
216
217     if (size < 0) {
218         LogError("Size error: " << size);
219         return DPL::OptionalString::Null;
220     }
221     char* data = new char[size + 1];
222
223     memset(data, 0, size + 1);
224     size_t ret = fread(data, 1, size, fd.Get());
225     if (static_cast<long>(ret) != size) {
226         LogError("Read size is mismatched");
227         delete[] data;
228         return DPL::OptionalString::Null;
229     }
230
231     std::string dataStr = data;
232     delete[] data;
233     // replace $VALUE, $KEY to data from database
234     std::ostringstream jsOstring;
235     jsOstring << dataStr;
236     std::string jsStr = jsOstring.str();
237     jsStr.replace(jsStr.find(JS_KEY_TAG),
238                   JS_KEY_TAG.length(),
239                   keyOstring.str());
240     jsStr.replace(jsStr.find(JS_VALUE_TAG),
241                   JS_VALUE_TAG.length(),
242                   valueOstring.str());
243
244     return DPL::FromUTF8String(jsStr);
245 }
246 } // namespaec PasswordSupport
247 } // namespaec ViewModule