Finalized login using cookies
[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 "../common.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 }
47
48 void FacebookAuthentication::clearAccountInformation(bool keepUsername)
49 {
50     qDebug() << __PRETTY_FUNCTION__;
51
52     m_loginCredentials.clearCredentials();
53     QSettings settings(DIRECTORY_NAME, FILE_NAME);
54
55     if(!keepUsername)
56         settings.remove(USERNAME);
57
58     settings.remove(COOKIES);
59 }
60
61 const QString FacebookAuthentication::loadUsername()
62 {
63     qDebug() << __PRETTY_FUNCTION__;
64
65     QSettings settings(DIRECTORY_NAME, FILE_NAME);
66     return settings.value(USERNAME, EMPTY).toString();
67 }
68
69 FacebookCredentials FacebookAuthentication::loginCredentials() const
70 {
71     qDebug() << __PRETTY_FUNCTION__;
72     return m_loginCredentials;
73 }
74
75 void FacebookAuthentication::saveUsername(const QString &username)
76 {
77     qDebug() << __PRETTY_FUNCTION__;
78
79     QSettings settings(DIRECTORY_NAME, FILE_NAME);
80     settings.setValue(USERNAME, username);
81 }
82
83 void FacebookAuthentication::start()
84 {
85     qDebug() << __PRETTY_FUNCTION__;
86
87     QSettings settings(DIRECTORY_NAME, FILE_NAME);
88
89     QStringList cookies = settings.value(COOKIES).toStringList();
90     if(!cookies.isEmpty()) {
91         emit loginUsingCookies();
92     }
93     else {
94         QStringList list;
95         list.append(FACEBOOK_LOGINBASE);
96         list.append(SITUARE_PUBLIC_FACEBOOKAPI_KEY);
97         list.append(INTERVAL1);
98         list.append(SITUARE_LOGIN_SUCCESS);
99         list.append(INTERVAL2);
100         list.append(SITUARE_LOGIN_FAILURE);
101         list.append(FACEBOOK_LOGIN_ENDING);
102
103         emit newLoginRequest(list.join(EMPTY));
104     }
105 }
106
107 bool FacebookAuthentication::updateCredentials(const QUrl &url)
108 {
109     qDebug() << __PRETTY_FUNCTION__;
110
111     bool found = false;
112
113     if (url.isValid()){
114          qDebug() << "url is valid";
115
116         QString callbackUrl = url.toString();
117         qDebug() << "callbackUrl:  " << callbackUrl.toAscii();
118
119         if (callbackUrl.indexOf(LOGIN_SUCCESS_REPLY) == 0) {
120             qDebug() << "login success";
121
122             // let's find out session credentials
123             if(callbackUrl.contains(SESSION_KEY)) {
124
125                 QJson::Parser parser;
126                 bool ok;
127
128                 // split string into string part and json part
129                 QStringList list = url.toString().split("=");
130
131                 for(int i=0;i<list.count();i++) {
132                     // if string starts with json item
133                     if(list.at(i).startsWith("{")) {
134                         QByteArray jsonString = list.at(i).toAscii();
135                         QVariantMap result = parser.parse (jsonString, &ok).toMap();
136                         if (!ok) {
137
138                             qFatal("An error occurred during parsing");
139                             exit (1);
140                         }
141                         qDebug() << "Session Key" << result[SESSION_KEY].toString();
142                         m_loginCredentials.setSessionKey(result[SESSION_KEY].toString());
143
144 //                        // commeted out until qjson parser can handle 64-bit integers
145 //                        qDebug() << "userID" << result[USER_ID].toString();
146 //                        m_loginCredentials.setUserID(result[USER_ID].toString().toAscii());
147
148                         // dirty fix, get user id from session_key
149                         QStringList list = result[SESSION_KEY].toString().split("-");
150                         m_loginCredentials.setUserID(list.at(1));
151                         qDebug() << m_loginCredentials.userID();
152
153                         qDebug() << "Expires" << result[EXPIRES].toString();
154                         m_loginCredentials.setExpires(result[EXPIRES].toString());
155
156                         qDebug() << "Session Secret" << result[SESSION_SECRET].toString();
157                         m_loginCredentials.setSessionSecret(result[SESSION_SECRET].toString());
158
159                         qDebug() << "Signature" << result[SIGNATURE].toString();
160                         m_loginCredentials.setSig(result[SIGNATURE].toString());
161                     }
162                 }
163                 found = true;
164                 emit saveCookiesRequest();
165             }
166             emit credentialsReady(m_loginCredentials);
167         }
168         else if ( callbackUrl.indexOf(LOGIN_FAILURE_REPLY) == 0){
169             qWarning() << "login failure" << endl;
170             qDebug() << callbackUrl;
171             ++m_loginAttempts;
172             /* emit loginFailure for every second login attemps, since webview loads login
173                error page (loadingDone() signal is emitted) and we need to avoid that because
174                at this point we don't have new login parameters */
175             if(m_loginAttempts % 2) {
176                 clearAccountInformation(true);
177                 emit loginFailure();
178             }
179         }
180         else if(callbackUrl.indexOf(LOGIN_PAGE) == 0) {
181             qDebug() << "correct loginPage";
182         }
183         else {
184             qDebug() << "totally wrong webPage";
185             // we should not get a wrong page at this point
186             emit loginFailure();
187         }
188     }
189     else {
190         qDebug() << " Loading of page failed invalid URL" << endl;
191         // we should not get a wrong page at this point
192         emit loginFailure();
193         return false;
194     }
195     return found;
196 }