updated facebook classes
[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
8    Situare is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License
10    version 2 as published by the Free Software Foundation.
11
12    Situare is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Situare; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20    USA.
21 */
22
23 #include "facebookauthentication.h"
24 #include <QtGui>
25 #include <QtDebug>
26 #include <QDateTime>
27
28 FacebookAuthentication::FacebookAuthentication(QWidget *parent)
29     : QMainWindow(parent)
30 {
31     qDebug() << __PRETTY_FUNCTION__;
32
33     webView = new QWebView;
34     mainlayout = new QHBoxLayout;
35
36     QString facebookLoginBase = "http://www.facebook.com/login.php?";
37     QString situarePublicFacebookApiKey = "api_key=4197c64da2fb6b927236feaea32d7d81";
38     //QString situareDeveloperFacebookApiKey = "api_key=cf77865a5070f2c2ba3b52cbf3371579";
39     QString interval1 = "&connect_display=popup&v=1.0&next=";
40     QString situareLoginSuccess = "http://www.facebook.com/connect/login_success.html";
41     QString interval2 = "&cancel_url=";
42     QString situareLoginFailure = "http://www.facebook.com/connect/login_failure.html";
43     QString facebookLoginEnding = "&fbconnect=true&return_session=true&";
44
45     facebookLoginPage.append(facebookLoginBase);
46     facebookLoginPage.append(situarePublicFacebookApiKey);
47     facebookLoginPage.append(interval1);
48     facebookLoginPage.append(situareLoginSuccess);
49     facebookLoginPage.append(interval2);
50     facebookLoginPage.append(situareLoginFailure);
51     facebookLoginPage.append(facebookLoginEnding);
52
53     connect(webView, SIGNAL(urlChanged(const QUrl &)), this, SLOT(updateCredentials(const QUrl &)));   
54
55     readCredentials(loginCredentials);
56
57     if (!verifyCredentials(loginCredentials))
58         start();
59     else
60         emit credentialsReady();
61
62 }
63
64 FacebookAuthentication::~FacebookAuthentication()
65 {
66     qDebug() << __PRETTY_FUNCTION__;
67     delete webView;
68     delete mainlayout;
69 }
70
71 void FacebookAuthentication::start()
72 {
73     qDebug() << __PRETTY_FUNCTION__;
74
75     const double fontSize = 1.2;
76
77     webView->setZoomFactor(fontSize);
78     webView->load(facebookLoginPage);
79     setCentralWidget(webView);    
80 }
81
82
83 bool FacebookAuthentication::updateCredentials(const QUrl &url)
84 {    
85     qDebug() << __PRETTY_FUNCTION__;
86
87     bool foundSessionKey = FALSE;
88     bool foundUserID = FALSE;
89     bool foundExpires = FALSE;
90     bool foundSessionSecret = FALSE;
91     bool foundSig = FALSE;
92
93     if (url.isValid()){
94          qDebug() << "url is valid" << endl;
95
96         QString callbackUrl = url.toString();
97         QString urlEdit(callbackUrl);
98         qDebug() << "callbackUrl:  " << endl << callbackUrl.toAscii() << endl;
99
100         if ( callbackUrl.indexOf("http://www.facebook.com/connect/login_success.html") == 0 ){
101             qDebug() << "login success" << endl;
102
103             // let's find out session key            
104             int indexOfCredential = callbackUrl.indexOf("session_key");
105
106             if (indexOfCredential != -1){
107                 foundSessionKey = TRUE;
108
109                 indexOfCredential += 14; //lenght of string "session_key"%                
110                 urlEdit.remove(0,indexOfCredential);
111                 indexOfCredential = urlEdit.indexOf("uid");
112                 urlEdit.remove(indexOfCredential, urlEdit.length());
113                 urlEdit.remove("\",\"");
114
115                 qDebug() << "session_key" << endl << urlEdit.toAscii() << endl;
116                 loginCredentials.setSessionKey(urlEdit);
117             }
118
119             // let's find out uid            
120             urlEdit = callbackUrl;
121             indexOfCredential = callbackUrl.indexOf("uid");
122
123             if (indexOfCredential != -1){
124                 foundUserID = TRUE;
125
126                 indexOfCredential += 5; //length of string "uid":
127                 urlEdit.remove(0,indexOfCredential);
128                 indexOfCredential = urlEdit.indexOf("expires");
129                 urlEdit.remove(indexOfCredential, urlEdit.length());
130                 urlEdit.remove(",\"");
131
132                 qDebug() << "userID" << endl << urlEdit.toAscii() << endl;
133                 loginCredentials.setUserID(urlEdit);
134             }
135
136             // let's find out expires           
137             urlEdit = callbackUrl;
138             indexOfCredential = callbackUrl.indexOf("expires");
139
140             if (indexOfCredential != -1){
141                 foundExpires = TRUE;
142
143                 indexOfCredential += 9; //length of string "expires"
144                 urlEdit.remove(0,indexOfCredential);
145                 indexOfCredential = urlEdit.indexOf("secret");
146                 urlEdit.remove(indexOfCredential, urlEdit.length());
147                 urlEdit.remove(",\"");
148
149                 qDebug() << "expires" << endl << urlEdit.toAscii() << endl;
150                 loginCredentials.setExpires(urlEdit);
151             }
152
153             // let's find out sessionsecret            
154             urlEdit = callbackUrl;
155             indexOfCredential = callbackUrl.indexOf("secret");
156
157             if (indexOfCredential != -1){
158                 foundSessionSecret = TRUE;
159
160                 indexOfCredential += 9; //" length of "secret":
161                 urlEdit.remove(0,indexOfCredential);
162                 indexOfCredential = urlEdit.indexOf("sig");
163                 urlEdit.remove(indexOfCredential, urlEdit.length());
164                 urlEdit.remove("\",\"");
165
166                 qDebug() << "sessionSecret" << endl << urlEdit.toAscii() << endl;
167                 loginCredentials.setSessionSecret(urlEdit);
168             }
169
170             // let's find out sig            
171             urlEdit = callbackUrl;
172             indexOfCredential = callbackUrl.indexOf("sig");
173
174             if (indexOfCredential != -1){
175                 foundSig = TRUE;
176
177                 indexOfCredential += 6; //" length of "sig":
178                 urlEdit.remove(0,indexOfCredential);
179                 urlEdit.remove("\"}");
180
181                 qDebug() << "sig" << endl << urlEdit.toAscii() << endl;
182                 loginCredentials.setSig(urlEdit);
183             }
184
185             webView->hide();
186             emit credentialsReady();
187             writeCredentials(loginCredentials);
188         }
189
190         else if ( callbackUrl.indexOf("https://login.facebook.com/login.php?login_attempt=") == 0){
191             qWarning() << "login failure" << endl;
192             emit loginFailure();
193         }
194
195         else if ( callbackUrl.indexOf("http://www.facebook.com/login.php?api_key=") == 0){
196             qDebug() << "correct loginPage";
197         }
198
199         else {
200             qDebug() << "totally wrong webPage";
201             emit loginFailure();
202             start();
203         }
204     }
205
206
207     else {
208         qDebug() << " Loading of page failed invalid URL" << endl;
209         emit loginFailure();
210         return FALSE;
211     }
212
213
214     return (foundSessionKey && foundUserID && foundExpires && foundSessionSecret && foundSig);
215 }
216
217 void FacebookAuthentication::writeCredentials(const FacebookCredentials &credentials)
218 {
219     qDebug() << __PRETTY_FUNCTION__;
220     QSettings settings("Ixonos", "Situare");
221
222     settings.setValue("Session Key", credentials.getSessionKey());
223     settings.setValue("User ID", credentials.getUserID());
224     settings.setValue("Expires", credentials.getExpires());
225     settings.setValue("Session Secret", credentials.getSessionSecret());
226     settings.setValue("Sig", credentials.getSig());
227 }
228
229 void FacebookAuthentication::readCredentials(FacebookCredentials &credentialsFromFile)
230 {
231     qDebug() << __PRETTY_FUNCTION__;
232
233     QSettings settings("Ixonos", "Situare");
234
235     credentialsFromFile.setSessionKey(settings.value("Session Key", "Error").toString());
236     credentialsFromFile.setUserID(settings.value("User ID", "Error").toString());
237     credentialsFromFile.setExpires(settings.value("Expires", "Error").toString());
238     credentialsFromFile.setSessionSecret(settings.value("Session Secret", "Error").toString());
239     credentialsFromFile.setSig(settings.value("Sig", "Error").toString());
240 }
241
242  FacebookCredentials FacebookAuthentication::getLoginCredentials() const
243  {
244      qDebug() << __PRETTY_FUNCTION__;
245      return loginCredentials;
246  }
247
248  bool FacebookAuthentication::verifyCredentials(const FacebookCredentials &credentials) const
249  {
250      qDebug() << __PRETTY_FUNCTION__;
251      QString expires = credentials.getExpires();
252      QDateTime expireTime;
253      expireTime.setTime_t(expires.toInt());
254      QString expiresString = expireTime.toString("dd.MM.yyyy  hh:mm:ss");
255      qDebug() << expiresString.toAscii();
256
257      QDateTime currentTime;
258      currentTime = QDateTime::currentDateTime();
259      QString currentTimeString = currentTime.toString("dd.MM.yyyy  hh:mm:ss");
260      qDebug() << currentTimeString.toAscii();
261
262      return currentTime < expireTime;
263  }
264
265  void FacebookAuthentication::closeEvent(QCloseEvent *event)
266  {
267      qDebug() << __PRETTY_FUNCTION__;
268      int eventNumber = 0;     
269      eventNumber = event->registerEventType();
270      qDebug() << "event number" << eventNumber;
271      emit userExit();
272      event->accept();
273  }