From d1986eeae2bcd0bc4533ea448a8d4afd56ab9d74 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Sat, 1 Feb 2025 22:25:53 +0100 Subject: [PATCH] Tidal: Save token type --- src/tidal/tidalbaserequest.cpp | 4 +++- src/tidal/tidalbaserequest.h | 1 + src/tidal/tidalfavoriterequest.cpp | 8 ++++++-- src/tidal/tidalservice.cpp | 20 +++++++++++++------- src/tidal/tidalservice.h | 4 +++- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/tidal/tidalbaserequest.cpp b/src/tidal/tidalbaserequest.cpp index 1f077ab37..451c6baf1 100644 --- a/src/tidal/tidalbaserequest.cpp +++ b/src/tidal/tidalbaserequest.cpp @@ -62,7 +62,9 @@ QNetworkReply *TidalBaseRequest::CreateRequest(const QString &ressource_name, co QNetworkRequest req(url); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - if (!access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); + if (!token_type().isEmpty() && !access_token().isEmpty()) { + req.setRawHeader("Authorization", token_type().toUtf8() + " " + access_token().toUtf8()); + } QNetworkReply *reply = network_->get(req); QObject::connect(reply, &QNetworkReply::sslErrors, this, &TidalBaseRequest::HandleSSLErrors); diff --git a/src/tidal/tidalbaserequest.h b/src/tidal/tidalbaserequest.h index f9efc2926..ad33bc131 100644 --- a/src/tidal/tidalbaserequest.h +++ b/src/tidal/tidalbaserequest.h @@ -79,6 +79,7 @@ class TidalBaseRequest : public QObject { int artistssearchlimit() const { return service_->artistssearchlimit(); } int albumssearchlimit() const { return service_->albumssearchlimit(); } int songssearchlimit() const { return service_->songssearchlimit(); } + QString token_type() const { return service_->token_type(); } QString access_token() const { return service_->access_token(); } bool authenticated() const { return service_->authenticated(); } diff --git a/src/tidal/tidalfavoriterequest.cpp b/src/tidal/tidalfavoriterequest.cpp index 4341586c1..9125a60ad 100644 --- a/src/tidal/tidalfavoriterequest.cpp +++ b/src/tidal/tidalfavoriterequest.cpp @@ -147,7 +147,9 @@ void TidalFavoriteRequest::AddFavoritesRequest(const FavoriteType type, const QS QNetworkRequest req(url); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - if (!access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); + if (!token_type().isEmpty() && !access_token().isEmpty()) { + req.setRawHeader("Authorization", token_type().toUtf8() + " " + access_token().toUtf8()); + } QByteArray query = url_query.toString(QUrl::FullyEncoded).toUtf8(); QNetworkReply *reply = network_->post(req, query); QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, type, songs]() { AddFavoritesReply(reply, type, songs); }); @@ -256,7 +258,9 @@ void TidalFavoriteRequest::RemoveFavoritesRequest(const FavoriteType type, const QNetworkRequest req(url); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); - if (!access_token().isEmpty()) req.setRawHeader("authorization", "Bearer " + access_token().toUtf8()); + if (!token_type().isEmpty() && !access_token().isEmpty()) { + req.setRawHeader("Authorization", token_type().toUtf8() + " " + access_token().toUtf8()); + } QNetworkReply *reply = network_->deleteResource(req); QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, type, songs]() { RemoveFavoritesReply(reply, type, songs); }); replies_ << reply; diff --git a/src/tidal/tidalservice.cpp b/src/tidal/tidalservice.cpp index 6b46b3c75..f3336efd9 100644 --- a/src/tidal/tidalservice.cpp +++ b/src/tidal/tidalservice.cpp @@ -88,6 +88,7 @@ constexpr char kSongsTable[] = "tidal_songs"; constexpr char kUserId[] = "user_id"; constexpr char kCountryCode[] = "country_code"; +constexpr char kTokenType[] = "token_type"; constexpr char kAccessToken[] = "access_token"; constexpr char kRefreshToken[] = "refresh_token"; constexpr char kSessionId[] = "session_id"; @@ -228,12 +229,17 @@ void TidalService::LoadSession() { s.beginGroup(TidalSettings::kSettingsGroup); user_id_ = s.value(kUserId).toInt(); country_code_ = s.value(kCountryCode, u"US"_s).toString(); + token_type_ = s.value(kTokenType).toString(); access_token_ = s.value(kAccessToken).toString(); refresh_token_ = s.value(kRefreshToken).toString(); expires_in_ = s.value(kExpiresIn).toLongLong(); login_time_ = s.value(kLoginTime).toLongLong(); s.endGroup(); + if (token_type_.isEmpty()) { + token_type_ = "Bearer"_L1; + } + if (!refresh_token_.isEmpty()) { qint64 time = static_cast(expires_in_) - (QDateTime::currentSecsSinceEpoch() - static_cast(login_time_)); if (time <= 0) { @@ -316,6 +322,7 @@ void TidalService::AuthorizationUrlReceived(const QUrl &url) { Settings s; s.beginGroup(TidalSettings::kSettingsGroup); + s.setValue(kTokenType, token_type_); s.setValue(kAccessToken, access_token_); s.setValue(kRefreshToken, refresh_token_); s.setValue(kExpiresIn, expires_in_); @@ -454,16 +461,15 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) { return; } - if (!json_obj.contains("access_token"_L1) || !json_obj.contains("expires_in"_L1)) { - LoginError(u"Authentication reply from server is missing access_token or expires_in"_s, json_obj); + if (!json_obj.contains("token_type"_L1) || !json_obj.contains("access_token"_L1) || !json_obj.contains("expires_in"_L1)) { + LoginError(u"Authentication reply from server is missing token_type, access_token or expires_in"_s, json_obj); return; } + token_type_ = json_obj["token_type"_L1].toString(); access_token_ = json_obj["access_token"_L1].toString(); + refresh_token_ = json_obj["refresh_token"_L1].toString(); expires_in_ = json_obj["expires_in"_L1].toInt(); - if (json_obj.contains("refresh_token"_L1)) { - refresh_token_ = json_obj["refresh_token"_L1].toString(); - } login_time_ = QDateTime::currentSecsSinceEpoch(); if (json_obj.contains("user"_L1) && json_obj["user"_L1].isObject()) { @@ -476,6 +482,7 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) { Settings s; s.beginGroup(TidalSettings::kSettingsGroup); + s.setValue(kTokenType, token_type_); s.setValue(kAccessToken, access_token_); s.setValue(kRefreshToken, refresh_token_); s.setValue(kExpiresIn, expires_in_); @@ -483,8 +490,6 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) { s.setValue(kCountryCode, country_code_); s.setValue(kUserId, user_id_); s.remove(kSessionId); - s.remove(kUserId); - s.remove(kCountryCode); s.endGroup(); if (expires_in_ > 0) { @@ -512,6 +517,7 @@ void TidalService::Logout() { s.beginGroup(TidalSettings::kSettingsGroup); s.remove(kUserId); s.remove(kCountryCode); + s.remove(kTokenType); s.remove(kAccessToken); s.remove(kRefreshToken); s.remove(kSessionId); diff --git a/src/tidal/tidalservice.h b/src/tidal/tidalservice.h index b0a2306bd..dd86855cd 100644 --- a/src/tidal/tidalservice.h +++ b/src/tidal/tidalservice.h @@ -95,9 +95,10 @@ class TidalService : public StreamingService { TidalSettings::StreamUrlMethod stream_url_method() const { return stream_url_method_; } bool album_explicit() const { return album_explicit_; } + QString token_type() const { return token_type_; } QString access_token() const { return access_token_; } - bool authenticated() const override { return !access_token_.isEmpty(); } + bool authenticated() const override { return !token_type_.isEmpty() && !access_token_.isEmpty(); } uint GetStreamURL(const QUrl &url, QString &error); @@ -185,6 +186,7 @@ class TidalService : public StreamingService { TidalSettings::StreamUrlMethod stream_url_method_; bool album_explicit_; + QString token_type_; QString access_token_; QString refresh_token_; quint64 expires_in_;