Merge branch 'list_panel'
[situare] / src / facebookservice / facebookauthentication.cpp
1 /*
2    Situare - A location system for Facebook
3    Copyright (C) 2010  Ixonos Plc. Authors:
4
5        Ville Tiensuu - ville.tiensuu@ixonos.com
6        Kaj Wallin - kaj.wallin@ixonos.com
7        Henri Lampela - henri.lampela@ixonos.com
8
9    Situare is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License
11    version 2 as published by the Free Software Foundation.
12
13    Situare is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Situare; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
21    USA.
22 */
23
24 #include <QtDebug>
25 #include <QDateTime>
26 #include <QSettings>
27 #include <QStringList>
28 #include <QVariantMap>
29
30 #ifdef Q_WS_MAEMO_5
31 #include <QMaemo5InformationBox>
32 #endif // Q_WS_MAEMO_5
33
34 #include "situarecommon.h"
35 #include "facebookauthentication.h"
36 #include "facebookcommon.h"
37 #include "parser.h"
38
39 FacebookAuthentication::FacebookAuthentication(QObject *parent)
40     : QObject(parent),
41     m_loginAttempts(0)
42
43 {
44     qDebug() << __PRETTY_FUNCTION__;
45
46     readCredentials(m_loginCredentials);
47 }
48
49 void FacebookAuthentication::start()
50 {
51     qDebug() << __PRETTY_FUNCTION__;
52
53     if (!verifyCredentials(m_loginCredentials)) {
54         QStringList list;
55         list.append(FACEBOOK_LOGINBASE);
56         list.append(SITUARE_PUBLIC_FACEBOOKAPI_KEY);
57         list.append(INTERVAL1);
58         list.append(SITUARE_LOGIN_SUCCESS);
59         list.append(INTERVAL2);
60         list.append(SITUARE_LOGIN_FAILURE);
61         list.append(FACEBOOK_LOGIN_ENDING);
62
63         emit newLoginRequest(formLoginPageUrl(list));
64     }
65     else
66         emit credentialsReady(m_loginCredentials);
67 }
68
69 bool FacebookAuthentication::updateCredentials(const QUrl &url)
70 {
71     qDebug() << __PRETTY_FUNCTION__;
72
73     bool found = false;
74
75     if (url.isValid()){
76          qDebug() << "url is valid";
77
78         QString callbackUrl = url.toString();
79         qDebug() << "callbackUrl:  " << callbackUrl.toAscii();
80
81         if (callbackUrl.indexOf(LOGIN_SUCCESS_REPLY) == 0) {
82             qDebug() << "login success";
83
84             // let's find out session credentials
85             if(callbackUrl.contains(SESSION_KEY)) {
86
87                 QJson::Parser parser;
88                 bool ok;
89
90                 // split string into string part and json part
91                 QStringList list = url.toString().split("=");
92
93                 for(int i=0;i<list.count();i++) {
94                     // if string starts with json item
95                     if(list.at(i).startsWith("{")) {
96                         QByteArray jsonString = list.at(i).toAscii();
97                         QVariantMap result = parser.parse (jsonString, &ok).toMap();
98                         if (!ok) {
99
100                             qFatal("An error occurred during parsing");
101                             exit (1);
102                         }
103                         qDebug() << "Session Key" << result[SESSION_KEY].toString();
104                         m_loginCredentials.setSessionKey(result[SESSION_KEY].toString());
105
106                         qDebug() << "userID" << result[USER_ID].toString();
107                         m_loginCredentials.setUserID(result[USER_ID].toString());
108
109                         qDebug() << "Expires" << result[EXPIRES].toString();
110                         m_loginCredentials.setExpires(result[EXPIRES].toString());
111
112                         qDebug() << "Session Secret" << result[SESSION_SECRET].toString();
113                         m_loginCredentials.setSessionSecret(result[SESSION_SECRET].toString());
114
115                         qDebug() << "Signature" << result[SIGNATURE].toString();
116                         m_loginCredentials.setSig(result[SIGNATURE].toString());
117                     }
118                 }
119                 found = true;
120             }
121             writeCredentials(m_loginCredentials);
122             emit credentialsReady(m_loginCredentials);
123         }
124         else if ( callbackUrl.indexOf(LOGIN_FAILURE_REPLY) == 0){
125             qWarning() << "login failure" << endl;
126             qDebug() << callbackUrl;
127             ++m_loginAttempts;
128             /* emit loginFailure for every second login attemps, since webview loads login
129                error page (loadingDone() signal is emitted) and we need to avoid that because
130                at this point we don't have new login parameters */
131             if(m_loginAttempts % 2) {
132                 emit loginFailure();
133             }
134         }
135         else if(callbackUrl.indexOf(LOGIN_PAGE) == 0) {
136             qDebug() << "correct loginPage";
137         }
138         else {
139             qDebug() << "totally wrong webPage";
140             // we should not get a wrong page at this point
141             emit loginFailure();
142         }
143     }
144     else {
145         qDebug() << " Loading of page failed invalid URL" << endl;
146         // we should not get a wrong page at this point
147         emit loginFailure();
148         return false;
149     }
150     return found;
151 }
152
153 void FacebookAuthentication::writeCredentials(const FacebookCredentials &credentials)
154 {
155     qDebug() << __PRETTY_FUNCTION__;
156     QSettings settings(DIRECTORY_NAME, FILE_NAME);
157
158     settings.setValue(SESSION_KEY, credentials.sessionKey());
159     settings.setValue(USER_ID, credentials.userID());
160     settings.setValue(EXPIRES, credentials.expires());
161     settings.setValue(SESSION_SECRET, credentials.sessionSecret());
162     settings.setValue(SIGNATURE, credentials.sig());
163 }
164
165 void FacebookAuthentication::readCredentials(FacebookCredentials &credentialsFromFile)
166 {
167     qDebug() << __PRETTY_FUNCTION__;
168
169     QSettings settings(DIRECTORY_NAME, FILE_NAME);
170
171     credentialsFromFile.setSessionKey(settings.value(SESSION_KEY, ERROR).toString());
172     credentialsFromFile.setUserID(settings.value(USER_ID, ERROR).toString());
173     credentialsFromFile.setExpires(settings.value(EXPIRES, ERROR).toString());
174     credentialsFromFile.setSessionSecret(settings.value(SESSION_SECRET, ERROR).toString());
175     credentialsFromFile.setSig(settings.value(SIGNATURE, ERROR).toString());
176 }
177
178  FacebookCredentials FacebookAuthentication::loginCredentials() const
179  {
180      qDebug() << __PRETTY_FUNCTION__;
181      return m_loginCredentials;
182  }
183
184  bool FacebookAuthentication::verifyCredentials(const FacebookCredentials &credentials) const
185  {
186      qDebug() << __PRETTY_FUNCTION__;
187
188      // if expires value is 0, then credentials are valid forever
189      if(credentials.expires() == "0") {
190          return true;
191      }
192      else {
193          const QString dateTimeFormat = "dd.MM.yyyy  hh:mm:ss";
194          QString expires = credentials.expires();
195          QDateTime expireTime;
196          expireTime.setTime_t(expires.toInt());
197          QString expiresString = expireTime.toString(dateTimeFormat);
198          qDebug() << expiresString.toAscii();
199
200          QDateTime currentTime;
201          currentTime = QDateTime::currentDateTime();
202          QString currentTimeString = currentTime.toString(dateTimeFormat);
203          qDebug() << currentTimeString.toAscii();
204
205          return currentTime < expireTime;
206      }
207  }
208
209  QUrl FacebookAuthentication::formLoginPageUrl(const QStringList &urlParts) const
210  {
211     qDebug() << __PRETTY_FUNCTION__;
212
213     return QUrl(urlParts.join(EMPTY));
214  }