Tidal: Save token type

This commit is contained in:
Jonas Kvinge 2025-02-01 22:25:53 +01:00
parent ba354207d2
commit d1986eeae2
5 changed files with 26 additions and 11 deletions

View File

@ -62,7 +62,9 @@ QNetworkReply *TidalBaseRequest::CreateRequest(const QString &ressource_name, co
QNetworkRequest req(url); QNetworkRequest req(url);
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); 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); QNetworkReply *reply = network_->get(req);
QObject::connect(reply, &QNetworkReply::sslErrors, this, &TidalBaseRequest::HandleSSLErrors); QObject::connect(reply, &QNetworkReply::sslErrors, this, &TidalBaseRequest::HandleSSLErrors);

View File

@ -79,6 +79,7 @@ class TidalBaseRequest : public QObject {
int artistssearchlimit() const { return service_->artistssearchlimit(); } int artistssearchlimit() const { return service_->artistssearchlimit(); }
int albumssearchlimit() const { return service_->albumssearchlimit(); } int albumssearchlimit() const { return service_->albumssearchlimit(); }
int songssearchlimit() const { return service_->songssearchlimit(); } int songssearchlimit() const { return service_->songssearchlimit(); }
QString token_type() const { return service_->token_type(); }
QString access_token() const { return service_->access_token(); } QString access_token() const { return service_->access_token(); }
bool authenticated() const { return service_->authenticated(); } bool authenticated() const { return service_->authenticated(); }

View File

@ -147,7 +147,9 @@ void TidalFavoriteRequest::AddFavoritesRequest(const FavoriteType type, const QS
QNetworkRequest req(url); QNetworkRequest req(url);
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); 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(); QByteArray query = url_query.toString(QUrl::FullyEncoded).toUtf8();
QNetworkReply *reply = network_->post(req, query); QNetworkReply *reply = network_->post(req, query);
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, type, songs]() { AddFavoritesReply(reply, type, songs); }); 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); QNetworkRequest req(url);
req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); req.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
req.setHeader(QNetworkRequest::ContentTypeHeader, u"application/x-www-form-urlencoded"_s); 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); QNetworkReply *reply = network_->deleteResource(req);
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, type, songs]() { RemoveFavoritesReply(reply, type, songs); }); QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, type, songs]() { RemoveFavoritesReply(reply, type, songs); });
replies_ << reply; replies_ << reply;

View File

@ -88,6 +88,7 @@ constexpr char kSongsTable[] = "tidal_songs";
constexpr char kUserId[] = "user_id"; constexpr char kUserId[] = "user_id";
constexpr char kCountryCode[] = "country_code"; constexpr char kCountryCode[] = "country_code";
constexpr char kTokenType[] = "token_type";
constexpr char kAccessToken[] = "access_token"; constexpr char kAccessToken[] = "access_token";
constexpr char kRefreshToken[] = "refresh_token"; constexpr char kRefreshToken[] = "refresh_token";
constexpr char kSessionId[] = "session_id"; constexpr char kSessionId[] = "session_id";
@ -228,12 +229,17 @@ void TidalService::LoadSession() {
s.beginGroup(TidalSettings::kSettingsGroup); s.beginGroup(TidalSettings::kSettingsGroup);
user_id_ = s.value(kUserId).toInt(); user_id_ = s.value(kUserId).toInt();
country_code_ = s.value(kCountryCode, u"US"_s).toString(); country_code_ = s.value(kCountryCode, u"US"_s).toString();
token_type_ = s.value(kTokenType).toString();
access_token_ = s.value(kAccessToken).toString(); access_token_ = s.value(kAccessToken).toString();
refresh_token_ = s.value(kRefreshToken).toString(); refresh_token_ = s.value(kRefreshToken).toString();
expires_in_ = s.value(kExpiresIn).toLongLong(); expires_in_ = s.value(kExpiresIn).toLongLong();
login_time_ = s.value(kLoginTime).toLongLong(); login_time_ = s.value(kLoginTime).toLongLong();
s.endGroup(); s.endGroup();
if (token_type_.isEmpty()) {
token_type_ = "Bearer"_L1;
}
if (!refresh_token_.isEmpty()) { if (!refresh_token_.isEmpty()) {
qint64 time = static_cast<qint64>(expires_in_) - (QDateTime::currentSecsSinceEpoch() - static_cast<qint64>(login_time_)); qint64 time = static_cast<qint64>(expires_in_) - (QDateTime::currentSecsSinceEpoch() - static_cast<qint64>(login_time_));
if (time <= 0) { if (time <= 0) {
@ -316,6 +322,7 @@ void TidalService::AuthorizationUrlReceived(const QUrl &url) {
Settings s; Settings s;
s.beginGroup(TidalSettings::kSettingsGroup); s.beginGroup(TidalSettings::kSettingsGroup);
s.setValue(kTokenType, token_type_);
s.setValue(kAccessToken, access_token_); s.setValue(kAccessToken, access_token_);
s.setValue(kRefreshToken, refresh_token_); s.setValue(kRefreshToken, refresh_token_);
s.setValue(kExpiresIn, expires_in_); s.setValue(kExpiresIn, expires_in_);
@ -454,16 +461,15 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) {
return; return;
} }
if (!json_obj.contains("access_token"_L1) || !json_obj.contains("expires_in"_L1)) { 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 access_token or expires_in"_s, json_obj); LoginError(u"Authentication reply from server is missing token_type, access_token or expires_in"_s, json_obj);
return; return;
} }
token_type_ = json_obj["token_type"_L1].toString();
access_token_ = json_obj["access_token"_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(); 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(); login_time_ = QDateTime::currentSecsSinceEpoch();
if (json_obj.contains("user"_L1) && json_obj["user"_L1].isObject()) { if (json_obj.contains("user"_L1) && json_obj["user"_L1].isObject()) {
@ -476,6 +482,7 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) {
Settings s; Settings s;
s.beginGroup(TidalSettings::kSettingsGroup); s.beginGroup(TidalSettings::kSettingsGroup);
s.setValue(kTokenType, token_type_);
s.setValue(kAccessToken, access_token_); s.setValue(kAccessToken, access_token_);
s.setValue(kRefreshToken, refresh_token_); s.setValue(kRefreshToken, refresh_token_);
s.setValue(kExpiresIn, expires_in_); s.setValue(kExpiresIn, expires_in_);
@ -483,8 +490,6 @@ void TidalService::AccessTokenRequestFinished(QNetworkReply *reply) {
s.setValue(kCountryCode, country_code_); s.setValue(kCountryCode, country_code_);
s.setValue(kUserId, user_id_); s.setValue(kUserId, user_id_);
s.remove(kSessionId); s.remove(kSessionId);
s.remove(kUserId);
s.remove(kCountryCode);
s.endGroup(); s.endGroup();
if (expires_in_ > 0) { if (expires_in_ > 0) {
@ -512,6 +517,7 @@ void TidalService::Logout() {
s.beginGroup(TidalSettings::kSettingsGroup); s.beginGroup(TidalSettings::kSettingsGroup);
s.remove(kUserId); s.remove(kUserId);
s.remove(kCountryCode); s.remove(kCountryCode);
s.remove(kTokenType);
s.remove(kAccessToken); s.remove(kAccessToken);
s.remove(kRefreshToken); s.remove(kRefreshToken);
s.remove(kSessionId); s.remove(kSessionId);

View File

@ -95,9 +95,10 @@ class TidalService : public StreamingService {
TidalSettings::StreamUrlMethod stream_url_method() const { return stream_url_method_; } TidalSettings::StreamUrlMethod stream_url_method() const { return stream_url_method_; }
bool album_explicit() const { return album_explicit_; } bool album_explicit() const { return album_explicit_; }
QString token_type() const { return token_type_; }
QString access_token() const { return access_token_; } 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); uint GetStreamURL(const QUrl &url, QString &error);
@ -185,6 +186,7 @@ class TidalService : public StreamingService {
TidalSettings::StreamUrlMethod stream_url_method_; TidalSettings::StreamUrlMethod stream_url_method_;
bool album_explicit_; bool album_explicit_;
QString token_type_;
QString access_token_; QString access_token_;
QString refresh_token_; QString refresh_token_;
quint64 expires_in_; quint64 expires_in_;