From 947720a4af4c963e16d0276cc89a9822b7f3b61e Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 26 Sep 2017 11:12:47 +0200 Subject: [PATCH] FUrther polishments of oauth flow. --- src/network-web/oauth2service.cpp | 18 ++++--- src/network-web/oauth2service.h | 1 + .../gui/formeditinoreaderaccount.cpp | 48 ++++++++++++------- .../inoreader/gui/formeditinoreaderaccount.h | 4 ++ 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/network-web/oauth2service.cpp b/src/network-web/oauth2service.cpp index 21526bc84..9790f7814 100755 --- a/src/network-web/oauth2service.cpp +++ b/src/network-web/oauth2service.cpp @@ -52,7 +52,7 @@ OAuth2Service::OAuth2Service(QString authUrl, QString tokenUrl, QString clientId, QString clientSecret, QString scope, QObject* parent) - : QObject(parent) { + : QObject(parent), m_tokensExpireIn(QDateTime()) { m_redirectUri = QSL("http://localhost"); m_tokenGrantType = QSL("authorization_code"); m_tokenUrl = QUrl(tokenUrl); @@ -141,15 +141,15 @@ void OAuth2Service::tokenRequestFinished(QNetworkReply* networkReply) { emit tokensRetrieveError(error, error_description); } else { + int expires = rootObject.value(QL1S("expires_in")).toInt(); + m_accessToken = rootObject.value(QL1S("access_token")).toString(); m_refreshToken = rootObject.value(QL1S("refresh_token")).toString(); + m_tokensExpireIn = QDateTime::currentDateTime().addSecs(expires); - int expires = rootObject.value(QL1S("expires_in")).toInt(); - QDateTime expire_date = QDateTime::currentDateTime().addSecs(expires); + qDebug() << "Obtained refresh token" << m_refreshToken << "- expires on date/time" << m_tokensExpireIn; - qDebug() << "Obtained refresh token" << m_refreshToken << "- expires on date/time" << expire_date; - - // TODO: Start timer to refresh tokens. + // TODO: Start timer to refresh tokens? emit tokensReceived(m_accessToken, m_refreshToken, rootObject.value("expires_in").toInt()); } @@ -165,7 +165,11 @@ void OAuth2Service::setRefreshToken(const QString& refresh_token) { } void OAuth2Service::login() { - if (!m_refreshToken.isEmpty()) { + // We refresh current tokens only if: + // 1. We have some existing refresh token. + // AND + // 2. We do not know its expiration date or it passed. + if (!m_refreshToken.isEmpty() && (m_tokensExpireIn.isNull() || m_tokensExpireIn < QDateTime::currentDateTime())) { refreshAccessToken(); } else { diff --git a/src/network-web/oauth2service.h b/src/network-web/oauth2service.h index a9709a4ed..fa7f63507 100755 --- a/src/network-web/oauth2service.h +++ b/src/network-web/oauth2service.h @@ -88,6 +88,7 @@ class OAuth2Service : public QObject { void tokenRequestFinished(QNetworkReply* networkReply); private: + QDateTime m_tokensExpireIn; QString m_accessToken; QString m_refreshToken; QString m_redirectUri; diff --git a/src/services/inoreader/gui/formeditinoreaderaccount.cpp b/src/services/inoreader/gui/formeditinoreaderaccount.cpp index dec19baae..637ca833c 100755 --- a/src/services/inoreader/gui/formeditinoreaderaccount.cpp +++ b/src/services/inoreader/gui/formeditinoreaderaccount.cpp @@ -101,24 +101,36 @@ void FormEditInoreaderAccount::checkUsername(const QString& username) { } } -void FormEditInoreaderAccount::hookNetwork() { - connect(m_network->oauth(), &OAuth2Service::tokensReceived, [this]() { - m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok, - tr("Tested successfully. You may be prompted to login once more."), - tr("Your access was approved.")); - }); - connect(m_network->oauth(), &OAuth2Service::tokensRetrieveError, [this](QString error, QString error_description) { - Q_UNUSED(error) +void FormEditInoreaderAccount::onAuthFailed() { + m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error, + tr("You did not grant access."), + tr("There was error during testing.")); +} - m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error, - tr("There is error. %1").arg(error_description), - tr("There was error during testing.")); - }); - connect(m_network->oauth(), &OAuth2Service::authFailed, [this]() { - m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error, - tr("You did not grant access."), - tr("There was error during testing.")); - }); +void FormEditInoreaderAccount::onAuthError(const QString& error, const QString& detailed_description) { + Q_UNUSED(error) + + m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error, + tr("There is error. %1").arg(detailed_description), + tr("There was error during testing.")); +} + +void FormEditInoreaderAccount::onAuthGranted() { + m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok, + tr("Tested successfully. You may be prompted to login once more."), + tr("Your access was approved.")); +} + +void FormEditInoreaderAccount::hookNetwork() { + connect(m_network->oauth(), &OAuth2Service::tokensReceived, this, &FormEditInoreaderAccount::onAuthGranted); + connect(m_network->oauth(), &OAuth2Service::tokensRetrieveError, this, &FormEditInoreaderAccount::onAuthError); + connect(m_network->oauth(), &OAuth2Service::authFailed, this, &FormEditInoreaderAccount::onAuthFailed); +} + +void FormEditInoreaderAccount::unhookNetwork() { + disconnect(m_network->oauth(), &OAuth2Service::tokensReceived, this, &FormEditInoreaderAccount::onAuthGranted); + disconnect(m_network->oauth(), &OAuth2Service::tokensRetrieveError, this, &FormEditInoreaderAccount::onAuthError); + disconnect(m_network->oauth(), &OAuth2Service::authFailed, this, &FormEditInoreaderAccount::onAuthFailed); } InoreaderServiceRoot* FormEditInoreaderAccount::execForCreate() { @@ -126,6 +138,7 @@ InoreaderServiceRoot* FormEditInoreaderAccount::execForCreate() { m_network = new InoreaderNetworkFactory(this); hookNetwork(); exec(); + unhookNetwork(); return m_editableRoot; } @@ -138,4 +151,5 @@ void FormEditInoreaderAccount::execForEdit(InoreaderServiceRoot* existing_root) m_network = existing_root->network(); hookNetwork(); exec(); + unhookNetwork(); } diff --git a/src/services/inoreader/gui/formeditinoreaderaccount.h b/src/services/inoreader/gui/formeditinoreaderaccount.h index 063f4fe58..c24bc79d6 100755 --- a/src/services/inoreader/gui/formeditinoreaderaccount.h +++ b/src/services/inoreader/gui/formeditinoreaderaccount.h @@ -47,9 +47,13 @@ class FormEditInoreaderAccount : public QDialog { void onClickedOk(); void onClickedCancel(); void checkUsername(const QString& username); + void onAuthFailed(); + void onAuthError(const QString& error, const QString& detailed_description); + void onAuthGranted(); private: void hookNetwork(); + void unhookNetwork(); Ui::FormEditInoreaderAccount m_ui; InoreaderNetworkFactory* m_network;