mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-31 11:35:24 +01:00
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"
|
||||
)
|
||||
|
||||
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"
|
||||
DEPENDS "libcdio" CDIO_FOUND
|
||||
)
|
||||
|
@ -291,6 +291,7 @@
|
||||
<file>providers/podcast16.png</file>
|
||||
<file>providers/podcast32.png</file>
|
||||
<file>providers/rockradio.png</file>
|
||||
<file>providers/skydrive.png</file>
|
||||
<file>providers/skyfm.png</file>
|
||||
<file>providers/somafm.png</file>
|
||||
<file>providers/songkick.png</file>
|
||||
|
BIN
data/providers/skydrive.png
Normal file
BIN
data/providers/skydrive.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
@ -1072,6 +1072,14 @@ optional_source(HAVE_DROPBOX
|
||||
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
|
||||
optional_source(LINUX
|
||||
SOURCES core/ubuntuunityhack.cpp
|
||||
|
@ -36,6 +36,7 @@
|
||||
#cmakedefine HAVE_LIBMTP
|
||||
#cmakedefine HAVE_MOODBAR
|
||||
#cmakedefine HAVE_QCA
|
||||
#cmakedefine HAVE_SKYDRIVE
|
||||
#cmakedefine HAVE_SPARKLE
|
||||
#cmakedefine HAVE_SPOTIFY
|
||||
#cmakedefine HAVE_SPOTIFY_DOWNLOADER
|
||||
|
@ -89,7 +89,8 @@ Client::Client(QObject* parent)
|
||||
|
||||
ConnectResponse* Client::Connect(const QString& refresh_token) {
|
||||
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()) {
|
||||
oauth->StartAuthorisation(
|
||||
|
@ -51,6 +51,9 @@
|
||||
#ifdef HAVE_DROPBOX
|
||||
#include "dropboxservice.h"
|
||||
#endif
|
||||
#ifdef HAVE_SKYDRIVE
|
||||
#include "skydriveservice.h"
|
||||
#endif
|
||||
|
||||
using smart_playlists::Generator;
|
||||
using smart_playlists::GeneratorMimeData;
|
||||
@ -97,6 +100,9 @@ InternetModel::InternetModel(Application* app, QObject* parent)
|
||||
#ifdef HAVE_DROPBOX
|
||||
AddService(new DropboxService(app, this));
|
||||
#endif
|
||||
#ifdef HAVE_SKYDRIVE
|
||||
AddService(new SkydriveService(app, this));
|
||||
#endif
|
||||
}
|
||||
|
||||
void InternetModel::AddService(InternetService *service) {
|
||||
|
@ -13,10 +13,12 @@
|
||||
OAuthenticator::OAuthenticator(
|
||||
const QString& client_id,
|
||||
const QString& client_secret,
|
||||
RedirectStyle redirect,
|
||||
QObject* parent)
|
||||
: QObject(parent),
|
||||
client_id_(client_id),
|
||||
client_secret_(client_secret) {
|
||||
client_secret_(client_secret),
|
||||
redirect_style_(redirect) {
|
||||
}
|
||||
|
||||
void OAuthenticator::StartAuthorisation(
|
||||
@ -27,25 +29,35 @@ void OAuthenticator::StartAuthorisation(
|
||||
LocalRedirectServer* server = new LocalRedirectServer(this);
|
||||
server->Listen();
|
||||
|
||||
NewClosure(server, SIGNAL(Finished()),
|
||||
this, SLOT(RedirectArrived(LocalRedirectServer*)), server);
|
||||
|
||||
QUrl url = QUrl(oauth_endpoint);
|
||||
url.addQueryItem("response_type", "code");
|
||||
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);
|
||||
|
||||
NewClosure(server, SIGNAL(Finished()),
|
||||
this, SLOT(RedirectArrived(LocalRedirectServer*,QUrl)),
|
||||
server, redirect_url);
|
||||
|
||||
QDesktopServices::openUrl(url);
|
||||
}
|
||||
|
||||
void OAuthenticator::RedirectArrived(LocalRedirectServer* server) {
|
||||
void OAuthenticator::RedirectArrived(
|
||||
LocalRedirectServer* server, QUrl url) {
|
||||
server->deleteLater();
|
||||
QUrl request_url = server->request_url();
|
||||
qLog(Debug) << Q_FUNC_INFO << request_url;
|
||||
RequestAccessToken(
|
||||
request_url.queryItemValue("code").toUtf8(),
|
||||
server->url());
|
||||
url);
|
||||
}
|
||||
|
||||
QByteArray OAuthenticator::ParseHttpRequest(const QByteArray& request) const {
|
||||
|
@ -12,9 +12,18 @@ class QTcpSocket;
|
||||
class OAuthenticator : public QObject {
|
||||
Q_OBJECT
|
||||
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(
|
||||
const QString& client_id,
|
||||
const QString& client_secret,
|
||||
RedirectStyle redirect,
|
||||
QObject* parent = 0);
|
||||
void StartAuthorisation(
|
||||
const QString& oauth_endpoint,
|
||||
@ -31,13 +40,12 @@ class OAuthenticator : public QObject {
|
||||
const QString& refresh_token() const { return refresh_token_; }
|
||||
|
||||
const QDateTime& expiry_time() const { return expiry_time_; }
|
||||
const QString& user_email() const { return user_email_; }
|
||||
|
||||
signals:
|
||||
void Finished();
|
||||
|
||||
private slots:
|
||||
void RedirectArrived(LocalRedirectServer* server);
|
||||
void RedirectArrived(LocalRedirectServer* server, QUrl url);
|
||||
void FetchAccessTokenFinished(QNetworkReply* reply);
|
||||
void RefreshAccessTokenFinished(QNetworkReply* reply);
|
||||
|
||||
@ -51,11 +59,11 @@ class OAuthenticator : public QObject {
|
||||
QString access_token_;
|
||||
QString refresh_token_;
|
||||
QDateTime expiry_time_;
|
||||
QString user_email_;
|
||||
|
||||
const QString client_id_;
|
||||
const QString client_secret_;
|
||||
QUrl token_endpoint_;
|
||||
RedirectStyle redirect_style_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
61
src/internet/skydriveservice.cpp
Normal file
61
src/internet/skydriveservice.cpp
Normal file
@ -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());
|
||||
}
|
26
src/internet/skydriveservice.h
Normal file
26
src/internet/skydriveservice.h
Normal file
@ -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_UbuntuOne,
|
||||
Page_Dropbox,
|
||||
Page_Skydrive,
|
||||
};
|
||||
|
||||
enum Role {
|
||||
|
Loading…
x
Reference in New Issue
Block a user