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