From 6c726e3e382bdd28fd00a5e68725980ef0da91e1 Mon Sep 17 00:00:00 2001 From: Andreas Date: Wed, 3 Feb 2016 15:33:46 +0100 Subject: [PATCH] Use desktopauth instead of mobileauth for last.fm It now uses an oauth like authentication process so the user isn't required to enter the last.fm password in Clementine but rather authenticate through the last.fm website. Updates #5028 --- src/internet/lastfm/lastfmservice.cpp | 56 +++++++++++++------ src/internet/lastfm/lastfmservice.h | 6 ++- src/internet/lastfm/lastfmsettingspage.cpp | 29 ++++++---- src/internet/lastfm/lastfmsettingspage.h | 1 + src/internet/lastfm/lastfmsettingspage.ui | 62 +++++++++++----------- 5 files changed, 97 insertions(+), 57 deletions(-) diff --git a/src/internet/lastfm/lastfmservice.cpp b/src/internet/lastfm/lastfmservice.cpp index d8445fa60..a3981d1f4 100644 --- a/src/internet/lastfm/lastfmservice.cpp +++ b/src/internet/lastfm/lastfmservice.cpp @@ -74,6 +74,7 @@ const char* LastFMService::kSettingsGroup = "Last.fm"; const char* LastFMService::kAudioscrobblerClientId = "tng"; const char* LastFMService::kApiKey = "75d20fb472be99275392aefa2760ea09"; const char* LastFMService::kSecret = "d3072b60ae626be12be69448f5c46e70"; +const char* LastFMService::kAuthLoginUrl = "http://www.last.fm/api/auth/?api_key=%1&token=%2"; LastFMService::LastFMService(Application* app, QObject* parent) : Scrobbler(parent), @@ -82,6 +83,8 @@ LastFMService::LastFMService(Application* app, QObject* parent) scrobbling_enabled_(false), connection_problems_(false), app_(app) { + lastfm::ws::setScheme(lastfm::ws::Https); + ReloadSettings(); // we emit the signal the first time to be sure the buttons are in the right @@ -127,13 +130,32 @@ bool LastFMService::IsSubscriber() const { return settings.value("Subscriber", false).toBool(); } -void LastFMService::Authenticate(const QString& username, - const QString& password) { +void LastFMService::GetToken() { QMap params; - params["method"] = "auth.getMobileSession"; - params["username"] = username; - params["authToken"] = - lastfm::md5((username + lastfm::md5(password.toUtf8())).toUtf8()); + params["method"] = "auth.getToken"; + QNetworkReply* reply = lastfm::ws::post(params); + NewClosure(reply, SIGNAL(finished()), this, + SLOT(GetTokenReplyFinished(QNetworkReply*)), reply); +} + +void LastFMService::GetTokenReplyFinished(QNetworkReply* reply) { + reply->deleteLater(); + + // Parse the reply + lastfm::XmlQuery lfm(lastfm::compat::EmptyXmlQuery()); + if (lastfm::compat::ParseQuery(reply->readAll(), &lfm)) { + QString token = lfm["token"].text(); + + emit TokenReceived(true, token); + } else { + emit TokenReceived(false, lfm["error"].text().trimmed()); + } +} + +void LastFMService::Authenticate(const QString& token) { + QMap params; + params["method"] = "auth.getSession"; + params["token"] = token; QNetworkReply* reply = lastfm::ws::post(params); NewClosure(reply, SIGNAL(finished()), this, @@ -141,17 +163,6 @@ void LastFMService::Authenticate(const QString& username, // If we need more detailed error reporting, handle error(NetworkError) signal } -void LastFMService::SignOut() { - lastfm::ws::Username.clear(); - lastfm::ws::SessionKey.clear(); - - QSettings settings; - settings.beginGroup(kSettingsGroup); - - settings.setValue("Username", QString()); - settings.setValue("Session", QString()); -} - void LastFMService::AuthenticateReplyFinished(QNetworkReply* reply) { reply->deleteLater(); @@ -181,6 +192,17 @@ void LastFMService::AuthenticateReplyFinished(QNetworkReply* reply) { emit AuthenticationComplete(true, QString()); } +void LastFMService::SignOut() { + lastfm::ws::Username.clear(); + lastfm::ws::SessionKey.clear(); + + QSettings settings; + settings.beginGroup(kSettingsGroup); + + settings.setValue("Username", QString()); + settings.setValue("Session", QString()); +} + void LastFMService::UpdateSubscriberStatus() { QMap params; params["method"] = "user.getInfo"; diff --git a/src/internet/lastfm/lastfmservice.h b/src/internet/lastfm/lastfmservice.h index 3f8af4627..d777be976 100644 --- a/src/internet/lastfm/lastfmservice.h +++ b/src/internet/lastfm/lastfmservice.h @@ -54,6 +54,7 @@ class LastFMService : public Scrobbler { static const char* kAudioscrobblerClientId; static const char* kApiKey; static const char* kSecret; + static const char* kAuthLoginUrl; void ReloadSettings(); @@ -68,7 +69,8 @@ class LastFMService : public Scrobbler { bool PreferAlbumArtist() const { return prefer_albumartist_; } bool HasConnectionProblems() const { return connection_problems_; } - void Authenticate(const QString& username, const QString& password); + void GetToken(); + void Authenticate(const QString& token); void SignOut(); void UpdateSubscriberStatus(); @@ -81,6 +83,7 @@ class LastFMService : public Scrobbler { void ToggleScrobbling(); signals: + void TokenReceived(bool success, const QString& token); void AuthenticationComplete(bool success, const QString& error_message); void ScrobblingEnabledChanged(bool value); void ButtonVisibilityChanged(bool value); @@ -94,6 +97,7 @@ class LastFMService : public Scrobbler { void SavedItemsChanged(); private slots: + void GetTokenReplyFinished(QNetworkReply* reply); void AuthenticateReplyFinished(QNetworkReply* reply); void UpdateSubscriberStatusFinished(QNetworkReply* reply); diff --git a/src/internet/lastfm/lastfmsettingspage.cpp b/src/internet/lastfm/lastfmsettingspage.cpp index 016a78a91..7e79bad2b 100644 --- a/src/internet/lastfm/lastfmsettingspage.cpp +++ b/src/internet/lastfm/lastfmsettingspage.cpp @@ -24,6 +24,7 @@ #include +#include #include #include @@ -42,17 +43,16 @@ LastFMSettingsPage::LastFMSettingsPage(SettingsDialog* dialog) // Icons setWindowIcon(IconLoader::Load("lastfm", IconLoader::Provider)); + connect(service_, SIGNAL(TokenReceived(bool,QString)), + SLOT(TokenReceived(bool,QString))); connect(service_, SIGNAL(AuthenticationComplete(bool, QString)), SLOT(AuthenticationComplete(bool, QString))); connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(Logout())); connect(ui_->login_state, SIGNAL(LoginClicked()), SLOT(Login())); connect(ui_->login, SIGNAL(clicked()), SLOT(Login())); - ui_->login_state->AddCredentialField(ui_->username); - ui_->login_state->AddCredentialField(ui_->password); - ui_->login_state->AddCredentialGroup(ui_->groupBox); + ui_->login_state->AddCredentialGroup(ui_->login_container); - ui_->username->setMinimumWidth(QFontMetrics(QFont()).width("WWWWWWWWWWWW")); resize(sizeHint()); } @@ -62,7 +62,22 @@ void LastFMSettingsPage::Login() { waiting_for_auth_ = true; ui_->login_state->SetLoggedIn(LoginStateWidget::LoginInProgress); - service_->Authenticate(ui_->username->text(), ui_->password->text()); + service_->GetToken(); +} + +void LastFMSettingsPage::TokenReceived(bool success, const QString &token) { + if (!success) { + QMessageBox::warning(this, tr("Last.fm authentication failed"), token); + return; + } + + QString url = QString(LastFMService::kAuthLoginUrl).arg(LastFMService::kApiKey, token); + QDesktopServices::openUrl(QUrl(url)); + + QMessageBox::information(this, tr("Last.fm authentication"), + tr("Click Ok once you authenticated Clementine in your last.fm account.")); + + service_->Authenticate(token); } void LastFMSettingsPage::AuthenticationComplete(bool success, @@ -72,8 +87,6 @@ void LastFMSettingsPage::AuthenticationComplete(bool success, waiting_for_auth_ = false; if (success) { - // Clear password just to be sure - ui_->password->clear(); // Save settings Save(); } else { @@ -109,8 +122,6 @@ void LastFMSettingsPage::Save() { } void LastFMSettingsPage::Logout() { - ui_->username->clear(); - ui_->password->clear(); RefreshControls(false); service_->SignOut(); diff --git a/src/internet/lastfm/lastfmsettingspage.h b/src/internet/lastfm/lastfmsettingspage.h index 24001bc44..225cb407c 100644 --- a/src/internet/lastfm/lastfmsettingspage.h +++ b/src/internet/lastfm/lastfmsettingspage.h @@ -38,6 +38,7 @@ class LastFMSettingsPage : public SettingsPage { private slots: void Login(); + void TokenReceived(bool success, const QString& token); void AuthenticationComplete(bool success, const QString& error_message); void Logout(); diff --git a/src/internet/lastfm/lastfmsettingspage.ui b/src/internet/lastfm/lastfmsettingspage.ui index cf8f865b6..dbc675411 100644 --- a/src/internet/lastfm/lastfmsettingspage.ui +++ b/src/internet/lastfm/lastfmsettingspage.ui @@ -18,26 +18,19 @@ - - - Account details - - - - QFormLayout::AllNonFixedFieldsGrow + + + + 28 - - - - Last.fm username - - - - + + 0 + + + 0 + + - - - @@ -45,19 +38,28 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - + + - Last.fm password + Clicking the Login button will open a web browser. You should return to Clementine after you have logged in. - - - - - - QLineEdit::Password + + true @@ -112,6 +114,9 @@ Qt::Vertical + + QSizePolicy::MinimumExpanding + 20 @@ -131,9 +136,6 @@ - username - password - login scrobble love_ban_ scrobble_button