1 #include <QDebug>
2 #include <QDateTime>
3 #include <QMap>
4 #include <QString>
5 #include <QStringList>
6 #if QT_VERSION >= 0x050000
7 #include <QUrlQuery>
8 #endif
9 
10 #include "o2skydrive.h"
11 #include "o0globals.h"
12 
O2Skydrive(QObject * parent)13 O2Skydrive::O2Skydrive(QObject *parent): O2(parent) {
14     setRequestUrl("https://login.live.com/oauth20_authorize.srf");
15     setTokenUrl("https://login.live.com/oauth20_token.srf");
16     setRefreshTokenUrl("https://login.live.com/oauth20_token.srf");
17 }
18 
link()19 void O2Skydrive::link() {
20     qDebug() << "O2Skydrive::link";
21     if (linked()) {
22         qDebug() << "O2kydrive::link: Linked already";
23         return;
24     }
25 
26     setLinked(false);
27     setToken("");
28     setTokenSecret("");
29     setExtraTokens(QVariantMap());
30     setRefreshToken(QString());
31     setExpires(0);
32 
33     redirectUri_ = QString("https://login.live.com/oauth20_desktop.srf");
34 
35     // Assemble initial authentication URL
36     QList<QPair<QString, QString> > parameters;
37     parameters.append(qMakePair(QString(O2_OAUTH2_RESPONSE_TYPE), (grantFlow_ == GrantFlowAuthorizationCode) ? QString(O2_OAUTH2_GRANT_TYPE_CODE) : QString(O2_OAUTH2_GRANT_TYPE_TOKEN)));
38     parameters.append(qMakePair(QString(O2_OAUTH2_CLIENT_ID), clientId_));
39     parameters.append(qMakePair(QString(O2_OAUTH2_REDIRECT_URI), redirectUri_));
40     parameters.append(qMakePair(QString(O2_OAUTH2_SCOPE), scope_));
41 
42     // Show authentication URL with a web browser
43     QUrl url(requestUrl_);
44 #if QT_VERSION < 0x050000
45     url.setQueryItems(parameters);
46 #else
47     QUrlQuery query(url);
48     query.setQueryItems(parameters);
49     url.setQuery(query);
50 #endif
51     Q_EMIT openBrowser(url);
52 }
53 
redirected(const QUrl & url)54 void O2Skydrive::redirected(const QUrl &url) {
55     qDebug() << "O2Skydrive::redirected" << url;
56 
57     Q_EMIT closeBrowser();
58 
59     if (grantFlow_ == GrantFlowAuthorizationCode) {
60         // Get access code
61         QString urlCode;
62 #if QT_VERSION < 0x050000
63         urlCode = url.queryItemValue(O2_OAUTH2_GRANT_TYPE_CODE);
64 #else
65         QUrlQuery query(url);
66         urlCode = query.queryItemValue(O2_OAUTH2_GRANT_TYPE_CODE);
67 #endif
68         if (urlCode.isEmpty()) {
69             qDebug() << "O2Skydrive::redirected: Code not received";
70             Q_EMIT linkingFailed();
71             return;
72         }
73         setCode(urlCode);
74 
75         // Exchange access code for access/refresh tokens
76         QNetworkRequest tokenRequest(tokenUrl_);
77         tokenRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
78         QMap<QString, QString> parameters;
79         parameters.insert(O2_OAUTH2_GRANT_TYPE_CODE, code());
80         parameters.insert(O2_OAUTH2_CLIENT_ID, clientId_);
81         parameters.insert(O2_OAUTH2_CLIENT_SECRET, clientSecret_);
82         parameters.insert(O2_OAUTH2_REDIRECT_URI, redirectUri_);
83         parameters.insert(O2_OAUTH2_GRANT_TYPE, O2_AUTHORIZATION_CODE);
84         QByteArray data = buildRequestBody(parameters);
85         QNetworkReply *tokenReply = manager_->post(tokenRequest, data);
86         timedReplies_.add(tokenReply);
87         connect(tokenReply, SIGNAL(finished()), this, SLOT(onTokenReplyFinished()), Qt::QueuedConnection);
88         connect(tokenReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onTokenReplyError(QNetworkReply::NetworkError)), Qt::QueuedConnection);
89     } else {
90         // Get access token
91         QString urlToken = "";
92         QString urlRefreshToken = "";
93         int urlExpiresIn = 0;
94 
95         QStringList parts = url.toString().split("#");
96         if (parts.length() > 1) {
97             foreach (QString item, parts[1].split("&")) {
98                 int index = item.indexOf("=");
99                 if (index == -1) {
100                     continue;
101                 }
102                 QString key = item.left(index);
103                 QString value = item.mid(index + 1);
104                 qDebug() << "O2Skydrive::redirected: Got" << key;
105                 if (key == O2_OAUTH2_ACCESS_TOKEN) {
106                     urlToken = value;
107                 } else if (key == O2_OAUTH2_EXPIRES_IN) {
108                     urlExpiresIn = value.toInt();
109                 } else if (key == O2_OAUTH2_REFRESH_TOKEN) {
110                     urlRefreshToken = value;
111                 }
112             }
113         }
114 
115         setToken(urlToken);
116         setRefreshToken(urlRefreshToken);
117         setExpires(QDateTime::currentMSecsSinceEpoch() / 1000 + urlExpiresIn);
118         if (urlToken.isEmpty()) {
119             Q_EMIT linkingFailed();
120         } else {
121             setLinked(true);
122             Q_EMIT linkingSucceeded();
123         }
124     }
125 }
126