Changed implementation
[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         emit newLoginRequest();
97     }
98 }
99
100 bool FacebookAuthentication::updateCredentials(const QUrl &url)
101 {
102     qDebug() << __PRETTY_FUNCTION__;
103
104     bool found = false;
105
106     if (url.isValid()){
107          qDebug() << "url is valid";
108
109         QString callbackUrl = url.toString();
110         qDebug() << "callbackUrl:  " << callbackUrl.toAscii();
111
112         if (callbackUrl.indexOf(LOGIN_SUCCESS_REPLY) == 0) {
113             qDebug() << "login success";
114
115             // let's find out session credentials
116             if(callbackUrl.contains(SESSION_KEY)) {
117
118                 QJson::Parser parser;
119                 bool ok;
120
121                 // split string into string part and json part
122                 QStringList list = url.toString().split("=");
123
124                 for(int i=0;i<list.count();i++) {
125                     // if string starts with json item
126                     if(list.at(i).startsWith("{")) {
127                         QByteArray jsonString = list.at(i).toAscii();
128                         QVariantMap result = parser.parse (jsonString, &ok).toMap();
129                         if (!ok) {
130
131                             qFatal("An error occurred during parsing");
132                             exit (1);
133                         }
134                         qDebug() << "Session Key" << result[SESSION_KEY].toString();
135                         m_loginCredentials.setSessionKey(result[SESSION_KEY].toString());
136
137 //                        // commeted out until qjson parser can handle 64-bit integers
138 //                        qDebug() << "userID" << result[USER_ID].toString();
139 //                        m_loginCredentials.setUserID(result[USER_ID].toString().toAscii());
140
141                         // dirty fix, get user id from session_key
142                         QStringList list = result[SESSION_KEY].toString().split("-");
143                         m_loginCredentials.setUserID(list.at(1));
144                         qDebug() << m_loginCredentials.userID();
145
146                         qDebug() << "Expires" << result[EXPIRES].toString();
147                         m_loginCredentials.setExpires(result[EXPIRES].toString());
148
149                         qDebug() << "Session Secret" << result[SESSION_SECRET].toString();
150                         m_loginCredentials.setSessionSecret(result[SESSION_SECRET].toString());
151
152                         qDebug() << "Signature" << result[SIGNATURE].toString();
153                         m_loginCredentials.setSig(result[SIGNATURE].toString());
154                     }
155                 }
156                 found = true;
157                 m_freshLogin = false;
158                 emit saveCookiesRequest();
159             }
160             emit credentialsReady(m_loginCredentials);
161         }
162         else if ( callbackUrl.indexOf(LOGIN_FAILURE_REPLY) == 0){
163             qWarning() << "login failure" << endl;
164             qDebug() << callbackUrl;
165             ++m_loginAttempts;
166             /* emit loginFailure for every second login attemps, since webview loads login
167                error page (loadingDone() signal is emitted) and we need to avoid that because
168                at this point we don't have new login parameters */
169             if(m_loginAttempts % 2) {
170                 clearAccountInformation(true);
171                 if(m_freshLogin) {
172                     emit error(LOGIN_FAILED);
173                     emit loginFailure();
174                 }
175                 else {
176                     m_freshLogin = true;
177                     emit error(SESSION_EXPIRED);
178                 }
179             }
180         }
181         else if(callbackUrl.indexOf(LOGIN_PAGE) == 0) {
182             qDebug() << "correct loginPage";
183         }
184         else {
185             qDebug() << "totally wrong webPage";
186             // we should not get a wrong page at this point
187             emit loginFailure();
188         }
189     }
190     else {
191         qDebug() << " Loading of page failed invalid URL" << endl;
192         // we should not get a wrong page at this point
193         emit loginFailure();
194         return false;
195     }
196     return found;
197 }