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