From 6e5db70ee56aaca2224686bbea53708d1e1bc6f5 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 26 Sep 2017 10:47:57 +0200 Subject: [PATCH] better oauth workflow. --- src/miscellaneous/databasequeries.cpp | 19 +++++++++++++++ src/miscellaneous/databasequeries.h | 1 + src/network-web/oauth2service.cpp | 24 ++++++++++++------- src/network-web/oauth2service.h | 8 +++++-- .../gui/formeditinoreaderaccount.cpp | 20 +++++++++------- .../inoreader/gui/formeditinoreaderaccount.h | 1 + .../network/inoreadernetworkfactory.cpp | 2 +- 7 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/miscellaneous/databasequeries.cpp b/src/miscellaneous/databasequeries.cpp index e1e1869c8..1f08e20df 100755 --- a/src/miscellaneous/databasequeries.cpp +++ b/src/miscellaneous/databasequeries.cpp @@ -1521,6 +1521,25 @@ Assignment DatabaseQueries::getInoreaderFeeds(QSqlDatabase db, int account_id, b return feeds; } +bool DatabaseQueries::storeNewInoreaderTokens(QSqlDatabase db, const QString& access_token, const QString& refresh_token, int account_id) { + QSqlQuery query(db); + + query.prepare("UPDATE InoreaderAccounts " + "SET access_token = :access_token, refresh_token = :refresh_token " + "WHERE id = :id;"); + query.bindValue(QSL(":access_token"), access_token); + query.bindValue(QSL(":refresh_token"), refresh_token); + query.bindValue(QSL(":id"), account_id); + + if (query.exec()) { + return true; + } + else { + qWarning("Inoreader: Updating tokens in DB failed: '%s'.", qPrintable(query.lastError().text())); + return false; + } +} + QList DatabaseQueries::getInoreaderAccounts(QSqlDatabase db, bool* ok) { QSqlQuery query(db); diff --git a/src/miscellaneous/databasequeries.h b/src/miscellaneous/databasequeries.h index 63a6b6675..434697023 100755 --- a/src/miscellaneous/databasequeries.h +++ b/src/miscellaneous/databasequeries.h @@ -81,6 +81,7 @@ class DatabaseQueries { // Inoreader account. #if defined(USE_WEBENGINE) static Assignment getInoreaderFeeds(QSqlDatabase db, int account_id, bool* ok = nullptr); + static bool storeNewInoreaderTokens(QSqlDatabase db, const QString& access_token, const QString& refresh_token, int account_id); static QList getInoreaderAccounts(QSqlDatabase db, bool* ok = nullptr); static bool overwriteInoreaderAccount(QSqlDatabase db, const QString& username, const QString& access_token, const QString& refresh_token, int batch_size, int account_id); diff --git a/src/network-web/oauth2service.cpp b/src/network-web/oauth2service.cpp index a651487a7..21526bc84 100755 --- a/src/network-web/oauth2service.cpp +++ b/src/network-web/oauth2service.cpp @@ -136,15 +136,20 @@ void OAuth2Service::tokenRequestFinished(QNetworkReply* networkReply) { QString error_description = rootObject.value("error_description").toString(); cleanTokens(); + login(); - emit tokenRetrieveError(error, error_description); + emit tokensRetrieveError(error, error_description); } else { - m_accessToken = rootObject.value("access_token").toString(); - m_refreshToken = rootObject.value("refresh_token").toString(); + m_accessToken = rootObject.value(QL1S("access_token")).toString(); + m_refreshToken = rootObject.value(QL1S("refresh_token")).toString(); + + 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" << expire_date; // TODO: Start timer to refresh tokens. - emit tokensReceived(m_accessToken, m_refreshToken, rootObject.value("expires_in").toInt()); } @@ -160,11 +165,12 @@ void OAuth2Service::setRefreshToken(const QString& refresh_token) { } void OAuth2Service::login() { - // TODO: ted se rovnou vola autorizace (prihlasovaci dialog) - // ale vylepsit a v pripade ze je zadan refresh token,, - // tak nejdříve zkusit obnovit? a začátek procesu - // volat jen když je to fakt potřeba. - retrieveAuthCode(); + if (!m_refreshToken.isEmpty()) { + refreshAccessToken(); + } + else { + retrieveAuthCode(); + } } void OAuth2Service::retrieveAuthCode() { diff --git a/src/network-web/oauth2service.h b/src/network-web/oauth2service.h index d91555e6b..a9709a4ed 100755 --- a/src/network-web/oauth2service.h +++ b/src/network-web/oauth2service.h @@ -65,7 +65,7 @@ class OAuth2Service : public QObject { signals: void tokensReceived(QString access_token, QString refresh_token, int expires_in); - void tokenRetrieveError(QString error, QString error_description); + void tokensRetrieveError(QString error, QString error_description); // User failed to authenticate or rejected it. void authFailed(); @@ -74,11 +74,15 @@ class OAuth2Service : public QObject { void authCodeObtained(QString auth_code); public slots: - void login(); void retrieveAuthCode(); void retrieveAccessToken(QString auth_code); void refreshAccessToken(QString refresh_token = QString()); + // Performs login if needed. If some refresh token is set, then + // the initial "auth" step is skipped and attempt to refresh + // access token is made. + void login(); + private slots: void cleanTokens(); void tokenRequestFinished(QNetworkReply* networkReply); diff --git a/src/services/inoreader/gui/formeditinoreaderaccount.cpp b/src/services/inoreader/gui/formeditinoreaderaccount.cpp index cdffbb525..0bb33d1c7 100755 --- a/src/services/inoreader/gui/formeditinoreaderaccount.cpp +++ b/src/services/inoreader/gui/formeditinoreaderaccount.cpp @@ -46,20 +46,15 @@ FormEditInoreaderAccount::FormEditInoreaderAccount(QWidget* parent) : QDialog(pa m_ui.m_spinLimitMessages->setSuffix(QSL(" ") + tr("messages")); } }); - connect(m_ui.m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, [this](QString text) { - if (text.isEmpty()) { - m_ui.m_txtUsername->setStatus(WidgetWithStatus::StatusType::Error, tr("No username entered.")); - } - else { - m_ui.m_txtUsername->setStatus(WidgetWithStatus::StatusType::Ok, tr("Some username entered.")); - } - }); + connect(m_ui.m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditInoreaderAccount::checkUsername); connect(m_ui.m_btnTestSetup, &QPushButton::clicked, this, &FormEditInoreaderAccount::testSetup); connect(m_ui.m_buttonBox, &QDialogButtonBox::accepted, this, &FormEditInoreaderAccount::onClickedOk); connect(m_ui.m_buttonBox, &QDialogButtonBox::rejected, this, &FormEditInoreaderAccount::onClickedCancel); m_ui.m_spinLimitMessages->setValue(INOREADER_DEFAULT_BATCH_SIZE); m_ui.m_spinLimitMessages->setMinimum(INOREADER_UNLIMITED_BATCH_SIZE); + + checkUsername(m_ui.m_txtUsername->lineEdit()->text()); } FormEditInoreaderAccount::~FormEditInoreaderAccount() {} @@ -103,6 +98,15 @@ void FormEditInoreaderAccount::onClickedCancel() { reject(); } +void FormEditInoreaderAccount::checkUsername(const QString& username) { + if (username.isEmpty()) { + m_ui.m_txtUsername->setStatus(WidgetWithStatus::StatusType::Error, tr("No username entered.")); + } + else { + m_ui.m_txtUsername->setStatus(WidgetWithStatus::StatusType::Ok, tr("Some username entered.")); + } +} + void FormEditInoreaderAccount::hookNetwork() { connect(m_network, &InoreaderNetworkFactory::accessGranted, [this]() { m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok, diff --git a/src/services/inoreader/gui/formeditinoreaderaccount.h b/src/services/inoreader/gui/formeditinoreaderaccount.h index be69f5824..063f4fe58 100755 --- a/src/services/inoreader/gui/formeditinoreaderaccount.h +++ b/src/services/inoreader/gui/formeditinoreaderaccount.h @@ -46,6 +46,7 @@ class FormEditInoreaderAccount : public QDialog { void testSetup(); void onClickedOk(); void onClickedCancel(); + void checkUsername(const QString& username); private: void hookNetwork(); diff --git a/src/services/inoreader/network/inoreadernetworkfactory.cpp b/src/services/inoreader/network/inoreadernetworkfactory.cpp index 3678162e8..13cff6044 100755 --- a/src/services/inoreader/network/inoreadernetworkfactory.cpp +++ b/src/services/inoreader/network/inoreadernetworkfactory.cpp @@ -66,7 +66,7 @@ void InoreaderNetworkFactory::login() { } void InoreaderNetworkFactory::initializeOauth() { - connect(m_oauth2, &OAuth2Service::tokenRetrieveError, [](QString error, QString error_description) { + connect(m_oauth2, &OAuth2Service::tokensRetrieveError, [](QString error, QString error_description) { qApp->showGuiMessage("Authentication error - Inoreader", error_description, QSystemTrayIcon::Critical); }); }