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