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