Cleaned up code and added a few missing comments
[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 "facebookauthentication.h"
35 #include "facebookcommon.h"
36 #include "situarecommon.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 //                        // commeted out until qjson parser can handle 64-bit integers
107 //                        qDebug() << "userID" << result[USER_ID].toString();
108 //                        m_loginCredentials.setUserID(result[USER_ID].toString().toAscii());
109
110                         // dirty fix, get user id from session_key
111                         QStringList list = result[SESSION_KEY].toString().split("-");
112                         m_loginCredentials.setUserID(list.at(1));
113                         qDebug() << m_loginCredentials.userID();
114
115                         qDebug() << "Expires" << result[EXPIRES].toString();
116                         m_loginCredentials.setExpires(result[EXPIRES].toString());
117
118                         qDebug() << "Session Secret" << result[SESSION_SECRET].toString();
119                         m_loginCredentials.setSessionSecret(result[SESSION_SECRET].toString());
120
121                         qDebug() << "Signature" << result[SIGNATURE].toString();
122                         m_loginCredentials.setSig(result[SIGNATURE].toString());
123                     }
124                 }
125                 found = true;
126             }
127             writeCredentials(m_loginCredentials);
128             emit credentialsReady(m_loginCredentials);
129         }
130         else if ( callbackUrl.indexOf(LOGIN_FAILURE_REPLY) == 0){
131             qWarning() << "login failure" << endl;
132             qDebug() << callbackUrl;
133             ++m_loginAttempts;
134             /* emit loginFailure for every second login attemps, since webview loads login
135                error page (loadingDone() signal is emitted) and we need to avoid that because
136                at this point we don't have new login parameters */
137             if(m_loginAttempts % 2) {
138                 emit loginFailure();
139             }
140         }
141         else if(callbackUrl.indexOf(LOGIN_PAGE) == 0) {
142             qDebug() << "correct loginPage";
143         }
144         else {
145             qDebug() << "totally wrong webPage";
146             // we should not get a wrong page at this point
147             emit loginFailure();
148         }
149     }
150     else {
151         qDebug() << " Loading of page failed invalid URL" << endl;
152         // we should not get a wrong page at this point
153         emit loginFailure();
154         return false;
155     }
156     return found;
157 }
158
159 void FacebookAuthentication::writeCredentials(const FacebookCredentials &credentials)
160 {
161     qDebug() << __PRETTY_FUNCTION__;
162     QSettings settings(DIRECTORY_NAME, FILE_NAME);
163
164     settings.setValue(SESSION_KEY, credentials.sessionKey());
165     settings.setValue(USER_ID, credentials.userID());
166     settings.setValue(EXPIRES, credentials.expires());
167     settings.setValue(SESSION_SECRET, credentials.sessionSecret());
168     settings.setValue(SIGNATURE, credentials.sig());
169 }
170
171 void FacebookAuthentication::readCredentials(FacebookCredentials &credentialsFromFile)
172 {
173     qDebug() << __PRETTY_FUNCTION__;
174
175     QSettings settings(DIRECTORY_NAME, FILE_NAME);
176
177     credentialsFromFile.setSessionKey(settings.value(SESSION_KEY, ERROR).toString());
178     credentialsFromFile.setUserID(settings.value(USER_ID, ERROR).toString());
179     credentialsFromFile.setExpires(settings.value(EXPIRES, ERROR).toString());
180     credentialsFromFile.setSessionSecret(settings.value(SESSION_SECRET, ERROR).toString());
181     credentialsFromFile.setSig(settings.value(SIGNATURE, ERROR).toString());
182 }
183
184  FacebookCredentials FacebookAuthentication::loginCredentials() const
185  {
186      qDebug() << __PRETTY_FUNCTION__;
187      return m_loginCredentials;
188  }
189
190  bool FacebookAuthentication::verifyCredentials(const FacebookCredentials &credentials) const
191  {
192      qDebug() << __PRETTY_FUNCTION__;
193
194      // if expires value is 0, then credentials are valid forever
195      if(credentials.expires() == "0") {
196          return true;
197      }
198      else {
199          const QString dateTimeFormat = "dd.MM.yyyy  hh:mm:ss";
200          QString expires = credentials.expires();
201          QDateTime expireTime;
202          expireTime.setTime_t(expires.toInt());
203          QString expiresString = expireTime.toString(dateTimeFormat);
204          qDebug() << expiresString.toAscii();
205
206          QDateTime currentTime;
207          currentTime = QDateTime::currentDateTime();
208          QString currentTimeString = currentTime.toString(dateTimeFormat);
209          qDebug() << currentTimeString.toAscii();
210
211          return currentTime < expireTime;
212      }
213  }
214
215  QUrl FacebookAuthentication::formLoginPageUrl(const QStringList &urlParts) const
216  {
217     qDebug() << __PRETTY_FUNCTION__;
218
219     return QUrl(urlParts.join(EMPTY));
220  }