More or less working Skydrive authentication.
This commit is contained in:
parent
8eea98ba66
commit
c4db401597
|
@ -202,6 +202,11 @@ optional_component(DROPBOX ON "Dropbox support"
|
||||||
DEPENDS "Taglib 1.8" "TAGLIB_VERSION VERSION_GREATER 1.7.999"
|
DEPENDS "Taglib 1.8" "TAGLIB_VERSION VERSION_GREATER 1.7.999"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
optional_component(SKYDRIVE ON "Skydrive support"
|
||||||
|
DEPENDS "Google sparsehash" SPARSEHASH_INCLUDE_DIRS
|
||||||
|
DEPENDS "Taglib 1.8" "TAGLIB_VERSION VERSION_GREATER 1.7.999"
|
||||||
|
)
|
||||||
|
|
||||||
optional_component(AUDIOCD ON "Devices: Audio CD support"
|
optional_component(AUDIOCD ON "Devices: Audio CD support"
|
||||||
DEPENDS "libcdio" CDIO_FOUND
|
DEPENDS "libcdio" CDIO_FOUND
|
||||||
)
|
)
|
||||||
|
|
|
@ -291,6 +291,7 @@
|
||||||
<file>providers/podcast16.png</file>
|
<file>providers/podcast16.png</file>
|
||||||
<file>providers/podcast32.png</file>
|
<file>providers/podcast32.png</file>
|
||||||
<file>providers/rockradio.png</file>
|
<file>providers/rockradio.png</file>
|
||||||
|
<file>providers/skydrive.png</file>
|
||||||
<file>providers/skyfm.png</file>
|
<file>providers/skyfm.png</file>
|
||||||
<file>providers/somafm.png</file>
|
<file>providers/somafm.png</file>
|
||||||
<file>providers/songkick.png</file>
|
<file>providers/songkick.png</file>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -1072,6 +1072,14 @@ optional_source(HAVE_DROPBOX
|
||||||
internet/dropboxsettingspage.ui
|
internet/dropboxsettingspage.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Skydrive support
|
||||||
|
optional_source(HAVE_SKYDRIVE
|
||||||
|
SOURCES
|
||||||
|
internet/skydriveservice.cpp
|
||||||
|
HEADERS
|
||||||
|
internet/skydriveservice.h
|
||||||
|
)
|
||||||
|
|
||||||
# Hack to add Clementine to the Unity system tray whitelist
|
# Hack to add Clementine to the Unity system tray whitelist
|
||||||
optional_source(LINUX
|
optional_source(LINUX
|
||||||
SOURCES core/ubuntuunityhack.cpp
|
SOURCES core/ubuntuunityhack.cpp
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#cmakedefine HAVE_LIBMTP
|
#cmakedefine HAVE_LIBMTP
|
||||||
#cmakedefine HAVE_MOODBAR
|
#cmakedefine HAVE_MOODBAR
|
||||||
#cmakedefine HAVE_QCA
|
#cmakedefine HAVE_QCA
|
||||||
|
#cmakedefine HAVE_SKYDRIVE
|
||||||
#cmakedefine HAVE_SPARKLE
|
#cmakedefine HAVE_SPARKLE
|
||||||
#cmakedefine HAVE_SPOTIFY
|
#cmakedefine HAVE_SPOTIFY
|
||||||
#cmakedefine HAVE_SPOTIFY_DOWNLOADER
|
#cmakedefine HAVE_SPOTIFY_DOWNLOADER
|
||||||
|
|
|
@ -89,7 +89,8 @@ Client::Client(QObject* parent)
|
||||||
|
|
||||||
ConnectResponse* Client::Connect(const QString& refresh_token) {
|
ConnectResponse* Client::Connect(const QString& refresh_token) {
|
||||||
ConnectResponse* ret = new ConnectResponse(this);
|
ConnectResponse* ret = new ConnectResponse(this);
|
||||||
OAuthenticator* oauth = new OAuthenticator(kClientId, kClientSecret, this);
|
OAuthenticator* oauth = new OAuthenticator(
|
||||||
|
kClientId, kClientSecret, OAuthenticator::RedirectStyle::LOCALHOST, this);
|
||||||
|
|
||||||
if (refresh_token.isEmpty()) {
|
if (refresh_token.isEmpty()) {
|
||||||
oauth->StartAuthorisation(
|
oauth->StartAuthorisation(
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
#ifdef HAVE_DROPBOX
|
#ifdef HAVE_DROPBOX
|
||||||
#include "dropboxservice.h"
|
#include "dropboxservice.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SKYDRIVE
|
||||||
|
#include "skydriveservice.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using smart_playlists::Generator;
|
using smart_playlists::Generator;
|
||||||
using smart_playlists::GeneratorMimeData;
|
using smart_playlists::GeneratorMimeData;
|
||||||
|
@ -97,6 +100,9 @@ InternetModel::InternetModel(Application* app, QObject* parent)
|
||||||
#ifdef HAVE_DROPBOX
|
#ifdef HAVE_DROPBOX
|
||||||
AddService(new DropboxService(app, this));
|
AddService(new DropboxService(app, this));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SKYDRIVE
|
||||||
|
AddService(new SkydriveService(app, this));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InternetModel::AddService(InternetService *service) {
|
void InternetModel::AddService(InternetService *service) {
|
||||||
|
|
|
@ -13,10 +13,12 @@
|
||||||
OAuthenticator::OAuthenticator(
|
OAuthenticator::OAuthenticator(
|
||||||
const QString& client_id,
|
const QString& client_id,
|
||||||
const QString& client_secret,
|
const QString& client_secret,
|
||||||
|
RedirectStyle redirect,
|
||||||
QObject* parent)
|
QObject* parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
client_id_(client_id),
|
client_id_(client_id),
|
||||||
client_secret_(client_secret) {
|
client_secret_(client_secret),
|
||||||
|
redirect_style_(redirect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OAuthenticator::StartAuthorisation(
|
void OAuthenticator::StartAuthorisation(
|
||||||
|
@ -27,25 +29,35 @@ void OAuthenticator::StartAuthorisation(
|
||||||
LocalRedirectServer* server = new LocalRedirectServer(this);
|
LocalRedirectServer* server = new LocalRedirectServer(this);
|
||||||
server->Listen();
|
server->Listen();
|
||||||
|
|
||||||
NewClosure(server, SIGNAL(Finished()),
|
|
||||||
this, SLOT(RedirectArrived(LocalRedirectServer*)), server);
|
|
||||||
|
|
||||||
QUrl url = QUrl(oauth_endpoint);
|
QUrl url = QUrl(oauth_endpoint);
|
||||||
url.addQueryItem("response_type", "code");
|
url.addQueryItem("response_type", "code");
|
||||||
url.addQueryItem("client_id", client_id_);
|
url.addQueryItem("client_id", client_id_);
|
||||||
url.addQueryItem("redirect_uri", server->url().toString());
|
QUrl redirect_url;
|
||||||
|
if (redirect_style_ == RedirectStyle::REMOTE) {
|
||||||
|
const int port = server->url().port();
|
||||||
|
redirect_url = QUrl(
|
||||||
|
QString("http://data.clementine-player.org/skydrive?port=%1").arg(port));
|
||||||
|
} else {
|
||||||
|
redirect_url = server->url();
|
||||||
|
}
|
||||||
|
url.addQueryItem("redirect_uri", redirect_url.toString());
|
||||||
url.addQueryItem("scope", scope);
|
url.addQueryItem("scope", scope);
|
||||||
|
|
||||||
|
NewClosure(server, SIGNAL(Finished()),
|
||||||
|
this, SLOT(RedirectArrived(LocalRedirectServer*,QUrl)),
|
||||||
|
server, redirect_url);
|
||||||
|
|
||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OAuthenticator::RedirectArrived(LocalRedirectServer* server) {
|
void OAuthenticator::RedirectArrived(
|
||||||
|
LocalRedirectServer* server, QUrl url) {
|
||||||
server->deleteLater();
|
server->deleteLater();
|
||||||
QUrl request_url = server->request_url();
|
QUrl request_url = server->request_url();
|
||||||
qLog(Debug) << Q_FUNC_INFO << request_url;
|
qLog(Debug) << Q_FUNC_INFO << request_url;
|
||||||
RequestAccessToken(
|
RequestAccessToken(
|
||||||
request_url.queryItemValue("code").toUtf8(),
|
request_url.queryItemValue("code").toUtf8(),
|
||||||
server->url());
|
url);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray OAuthenticator::ParseHttpRequest(const QByteArray& request) const {
|
QByteArray OAuthenticator::ParseHttpRequest(const QByteArray& request) const {
|
||||||
|
|
|
@ -12,9 +12,18 @@ class QTcpSocket;
|
||||||
class OAuthenticator : public QObject {
|
class OAuthenticator : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
enum class RedirectStyle {
|
||||||
|
// Redirect to localhost immediately.
|
||||||
|
LOCALHOST = 0,
|
||||||
|
// Redirect via data.clementine-player.org for when localhost is
|
||||||
|
// unsupported (eg. Skydrive).
|
||||||
|
REMOTE = 1,
|
||||||
|
};
|
||||||
|
|
||||||
OAuthenticator(
|
OAuthenticator(
|
||||||
const QString& client_id,
|
const QString& client_id,
|
||||||
const QString& client_secret,
|
const QString& client_secret,
|
||||||
|
RedirectStyle redirect,
|
||||||
QObject* parent = 0);
|
QObject* parent = 0);
|
||||||
void StartAuthorisation(
|
void StartAuthorisation(
|
||||||
const QString& oauth_endpoint,
|
const QString& oauth_endpoint,
|
||||||
|
@ -31,13 +40,12 @@ class OAuthenticator : public QObject {
|
||||||
const QString& refresh_token() const { return refresh_token_; }
|
const QString& refresh_token() const { return refresh_token_; }
|
||||||
|
|
||||||
const QDateTime& expiry_time() const { return expiry_time_; }
|
const QDateTime& expiry_time() const { return expiry_time_; }
|
||||||
const QString& user_email() const { return user_email_; }
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void Finished();
|
void Finished();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void RedirectArrived(LocalRedirectServer* server);
|
void RedirectArrived(LocalRedirectServer* server, QUrl url);
|
||||||
void FetchAccessTokenFinished(QNetworkReply* reply);
|
void FetchAccessTokenFinished(QNetworkReply* reply);
|
||||||
void RefreshAccessTokenFinished(QNetworkReply* reply);
|
void RefreshAccessTokenFinished(QNetworkReply* reply);
|
||||||
|
|
||||||
|
@ -51,11 +59,11 @@ class OAuthenticator : public QObject {
|
||||||
QString access_token_;
|
QString access_token_;
|
||||||
QString refresh_token_;
|
QString refresh_token_;
|
||||||
QDateTime expiry_time_;
|
QDateTime expiry_time_;
|
||||||
QString user_email_;
|
|
||||||
|
|
||||||
const QString client_id_;
|
const QString client_id_;
|
||||||
const QString client_secret_;
|
const QString client_secret_;
|
||||||
QUrl token_endpoint_;
|
QUrl token_endpoint_;
|
||||||
|
RedirectStyle redirect_style_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include "skydriveservice.h"
|
||||||
|
|
||||||
|
#include "oauthenticator.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static const char* kServiceName = "Skydrive";
|
||||||
|
static const char* kServiceId = "skydrive";
|
||||||
|
static const char* kSettingsGroup = "Skydrive";
|
||||||
|
|
||||||
|
static const char* kClientId = "00000000400E7C78";
|
||||||
|
static const char* kClientSecret = "B0KLZjEgC5SpW0KknrsBFwlaKmGThaAk";
|
||||||
|
|
||||||
|
static const char* kOAuthEndpoint =
|
||||||
|
"https://login.live.com/oauth20_authorize.srf";
|
||||||
|
static const char* kOAuthTokenEndpoint =
|
||||||
|
"https://login.live.com/oauth20_token.srf";
|
||||||
|
static const char* kOAuthScope = "wl.basic wl.skydrive wl.offline_access";
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
SkydriveService::SkydriveService(
|
||||||
|
Application* app,
|
||||||
|
InternetModel* parent)
|
||||||
|
: CloudFileService(
|
||||||
|
app, parent, kServiceName, kServiceId,
|
||||||
|
QIcon(":providers/skydrive.png"), SettingsDialog::Page_Skydrive) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SkydriveService::has_credentials() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkydriveService::Connect() {
|
||||||
|
OAuthenticator* oauth = new OAuthenticator(
|
||||||
|
kClientId, kClientSecret, OAuthenticator::RedirectStyle::REMOTE, this);
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
if (s.contains("refresh_token")) {
|
||||||
|
oauth->RefreshAuthorisation(
|
||||||
|
kOAuthTokenEndpoint, s.value("refresh_token").toString());
|
||||||
|
} else {
|
||||||
|
oauth->StartAuthorisation(
|
||||||
|
kOAuthEndpoint,
|
||||||
|
kOAuthTokenEndpoint,
|
||||||
|
kOAuthScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewClosure(oauth, SIGNAL(Finished()),
|
||||||
|
this, SLOT(ConnectFinished(OAuthenticator*)), oauth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkydriveService::ConnectFinished(OAuthenticator* oauth) {
|
||||||
|
qLog(Debug) << oauth->access_token()
|
||||||
|
<< oauth->refresh_token();
|
||||||
|
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
|
s.setValue("refresh_token", oauth->refresh_token());
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef SKYDRIVESERVICE_H
|
||||||
|
#define SKYDRIVESERVICE_H
|
||||||
|
|
||||||
|
#include "cloudfileservice.h"
|
||||||
|
|
||||||
|
class OAuthenticator;
|
||||||
|
|
||||||
|
class SkydriveService : public CloudFileService {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
SkydriveService(
|
||||||
|
Application* app,
|
||||||
|
InternetModel* parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// CloudFileService
|
||||||
|
virtual bool has_credentials() const;
|
||||||
|
virtual void Connect();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void ConnectFinished(OAuthenticator* oauth);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SKYDRIVESERVICE_H
|
|
@ -79,6 +79,7 @@ public:
|
||||||
Page_GoogleDrive,
|
Page_GoogleDrive,
|
||||||
Page_UbuntuOne,
|
Page_UbuntuOne,
|
||||||
Page_Dropbox,
|
Page_Dropbox,
|
||||||
|
Page_Skydrive,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Role {
|
enum Role {
|
||||||
|
|
Loading…
Reference in New Issue