From 29be179ea1fd8b2617b699f3d851c3807ec4819f Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 17 Oct 2017 14:00:30 +0200 Subject: [PATCH] Added gmail edit acc dialog. --- rssguard.pro | 9 +- src/definitions/definitions.h | 1 + src/network-web/oauth2service.cpp | 2 +- src/services/gmail/definitions.h | 3 + .../gmail/gui/formeditgmailaccount.cpp | 204 ++++++++++++++++++ src/services/gmail/gui/formeditgmailaccount.h | 63 ++++++ .../gmail/gui/formeditgmailaccount.ui | 190 ++++++++++++++++ src/services/inoreader/definitions.h | 1 - .../gui/formeditinoreaderaccount.cpp | 2 +- 9 files changed, 469 insertions(+), 6 deletions(-) create mode 100755 src/services/gmail/gui/formeditgmailaccount.cpp create mode 100755 src/services/gmail/gui/formeditgmailaccount.h create mode 100755 src/services/gmail/gui/formeditgmailaccount.ui diff --git a/rssguard.pro b/rssguard.pro index c9f92e49a..bf98289d2 100755 --- a/rssguard.pro +++ b/rssguard.pro @@ -504,7 +504,8 @@ equals(USE_WEBENGINE, true) { src/services/gmail/gmailentrypoint.h \ src/services/gmail/gmailserviceroot.h \ src/services/gmail/gmailfeed.h \ - src/services/gmail/network/gmailnetworkfactory.h + src/services/gmail/network/gmailnetworkfactory.h \ + src/services/gmail/gui/formeditgmailaccount.h SOURCES += src/gui/locationlineedit.cpp \ src/gui/webviewer.cpp \ @@ -523,7 +524,8 @@ equals(USE_WEBENGINE, true) { src/services/gmail/gmailentrypoint.cpp \ src/services/gmail/gmailserviceroot.cpp \ src/services/gmail/gmailfeed.cpp \ - src/services/gmail/network/gmailnetworkfactory.cpp + src/services/gmail/network/gmailnetworkfactory.cpp \ + src/services/gmail/gui/formeditgmailaccount.cpp # Add AdBlock sources. HEADERS += src/network-web/adblock/adblockaddsubscriptiondialog.h \ @@ -558,7 +560,8 @@ equals(USE_WEBENGINE, true) { FORMS += src/network-web/adblock/adblockaddsubscriptiondialog.ui \ src/network-web/adblock/adblockdialog.ui \ src/services/inoreader/gui/formeditinoreaderaccount.ui \ - src/gui/dialogs/oauthlogin.ui + src/gui/dialogs/oauthlogin.ui \ + src/services/gmail/gui/formeditgmailaccount.ui } else { HEADERS += src/gui/messagepreviewer.h \ diff --git a/src/definitions/definitions.h b/src/definitions/definitions.h index 622a2b4ed..b08274b9a 100755 --- a/src/definitions/definitions.h +++ b/src/definitions/definitions.h @@ -29,6 +29,7 @@ #define ARGUMENTS_LIST_SEPARATOR "\n" +#define LOCALHOST_ADDRESS "http://localhost" #define ADBLOCK_ADBLOCKED_PAGE "adblockedpage" #define ADBLOCK_HOWTO_FILTERS "http://adblockplus.org/en/filters" #define ADBLOCK_UPDATE_DAYS_INTERVAL 5 diff --git a/src/network-web/oauth2service.cpp b/src/network-web/oauth2service.cpp index 4ca6a50c3..e25389110 100755 --- a/src/network-web/oauth2service.cpp +++ b/src/network-web/oauth2service.cpp @@ -55,7 +55,7 @@ OAuth2Service::OAuth2Service(QString authUrl, QString tokenUrl, QString clientId QString clientSecret, QString scope, QObject* parent) : QObject(parent), m_timerId(-1), m_tokensExpireIn(QDateTime()) { - m_redirectUrl = QSL(INOREADER_OAUTH_CLI_REDIRECT); + m_redirectUrl = QSL(LOCALHOST_ADDRESS); m_tokenGrantType = QSL("authorization_code"); m_tokenUrl = QUrl(tokenUrl); m_authUrl = authUrl; diff --git a/src/services/gmail/definitions.h b/src/services/gmail/definitions.h index 1dbe99c41..e048f9f08 100755 --- a/src/services/gmail/definitions.h +++ b/src/services/gmail/definitions.h @@ -22,6 +22,9 @@ #define GMAIL_OAUTH_AUTH_URL "https://accounts.google.com/o/oauth2/auth" #define GMAIL_OAUTH_TOKEN_URL "https://accounts.google.com/o/oauth2/token" #define GMAIL_OAUTH_SCOPE "https://mail.google.com/" + #define GMAIL_DEFAULT_BATCH_SIZE 100 +#define GMAIL_MAX_BATCH_SIZE 999 +#define GMAIL_MIN_BATCH_SIZE 20 #endif // GMAIL_DEFINITIONS_H diff --git a/src/services/gmail/gui/formeditgmailaccount.cpp b/src/services/gmail/gui/formeditgmailaccount.cpp new file mode 100755 index 000000000..64470a586 --- /dev/null +++ b/src/services/gmail/gui/formeditgmailaccount.cpp @@ -0,0 +1,204 @@ +// This file is part of RSS Guard. + +// +// Copyright (C) 2011-2017 by Martin Rotter +// +// RSS Guard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// RSS Guard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with RSS Guard. If not, see . + +#include "services/gmail/gui/formeditgmailaccount.h" + +#include "gui/guiutilities.h" +#include "miscellaneous/application.h" +#include "miscellaneous/iconfactory.h" +#include "network-web/oauth2service.h" +#include "services/gmail/definitions.h" +#include "services/gmail/gmailserviceroot.h" + +FormEditGmailAccount::FormEditGmailAccount(QWidget* parent) : QDialog(parent), + m_oauth(new OAuth2Service(GMAIL_OAUTH_AUTH_URL, GMAIL_OAUTH_TOKEN_URL, + QString(), QString(), GMAIL_OAUTH_SCOPE)), m_editableRoot(nullptr) { + m_ui.setupUi(this); + + GuiUtilities::setLabelAsNotice(*m_ui.m_lblAuthInfo, true); + GuiUtilities::applyDialogProperties(*this, qApp->icons()->miscIcon(QSL("gmail"))); + + m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Information, + tr("Not tested yet."), + tr("Not tested yet.")); + m_ui.m_lblTestResult->label()->setWordWrap(true); + m_ui.m_txtUsername->lineEdit()->setPlaceholderText(tr("User-visible username")); + + setTabOrder(m_ui.m_txtUsername->lineEdit(), m_ui.m_txtAppId); + setTabOrder(m_ui.m_txtAppId, m_ui.m_txtAppKey); + setTabOrder(m_ui.m_txtAppKey, m_ui.m_txtRedirectUrl); + setTabOrder(m_ui.m_txtRedirectUrl, m_ui.m_spinLimitMessages); + setTabOrder(m_ui.m_spinLimitMessages, m_ui.m_btnTestSetup); + setTabOrder(m_ui.m_btnTestSetup, m_ui.m_buttonBox); + + connect(m_ui.m_txtAppId->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkOAuthValue); + connect(m_ui.m_txtAppKey->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkOAuthValue); + connect(m_ui.m_txtRedirectUrl->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkOAuthValue); + connect(m_ui.m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, this, &FormEditGmailAccount::checkUsername); + connect(m_ui.m_btnTestSetup, &QPushButton::clicked, this, &FormEditGmailAccount::testSetup); + connect(m_ui.m_buttonBox, &QDialogButtonBox::accepted, this, &FormEditGmailAccount::onClickedOk); + connect(m_ui.m_buttonBox, &QDialogButtonBox::rejected, this, &FormEditGmailAccount::onClickedCancel); + + m_ui.m_spinLimitMessages->setValue(GMAIL_DEFAULT_BATCH_SIZE); + m_ui.m_spinLimitMessages->setMinimum(GMAIL_MIN_BATCH_SIZE); + m_ui.m_spinLimitMessages->setMaximum(GMAIL_MAX_BATCH_SIZE); + + checkUsername(m_ui.m_txtUsername->lineEdit()->text()); + hookNetwork(); +} + +FormEditGmailAccount::~FormEditGmailAccount() {} + +void FormEditGmailAccount::testSetup() { + if (m_oauth->clientId() != m_ui.m_txtAppId->lineEdit()->text() || + m_oauth->clientSecret() != m_ui.m_txtAppKey->lineEdit()->text() || + m_oauth->redirectUrl() != m_ui.m_txtRedirectUrl->lineEdit()->text()) { + // User changed some important settings. Log out. + m_oauth->logout(); + } + + m_oauth->setClientId(m_ui.m_txtAppId->lineEdit()->text()); + m_oauth->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text()); + m_oauth->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text()); + + if (m_oauth->login()) { + m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Ok, + tr("You are already logged in."), + tr("Access granted. \ + ")); + } +} + +void FormEditGmailAccount::onClickedOk() { + bool editing_account = true; + + if (m_editableRoot == nullptr) { + // We want to confirm newly created account. + // So save new account into DB, setup its properties. + m_editableRoot = new GmailServiceRoot(nullptr); + editing_account = false; + } + + // We copy credentials from testing OAuth to live OAuth. + m_editableRoot->network()->oauth()->setAccessToken(m_oauth->accessToken()); + m_editableRoot->network()->oauth()->setRefreshToken(m_oauth->refreshToken()); + m_editableRoot->network()->oauth()->setTokensExpireIn(m_oauth->tokensExpireIn()); + + m_editableRoot->network()->oauth()->setClientId(m_ui.m_txtAppId->lineEdit()->text()); + m_editableRoot->network()->oauth()->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text()); + m_editableRoot->network()->oauth()->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text()); + + m_editableRoot->network()->setUsername(m_ui.m_txtUsername->lineEdit()->text()); + m_editableRoot->network()->setBatchSize(m_ui.m_spinLimitMessages->value()); + m_editableRoot->saveAccountDataToDatabase(); + accept(); + + if (editing_account) { + m_editableRoot->completelyRemoveAllData(); + m_editableRoot->syncIn(); + } +} + +void FormEditGmailAccount::onClickedCancel() { + reject(); +} + +void FormEditGmailAccount::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 FormEditGmailAccount::onAuthFailed() { + m_ui.m_lblTestResult->setStatus(WidgetWithStatus::StatusType::Error, + tr("You did not grant access."), + tr("There was error during testing.")); +} + +void FormEditGmailAccount::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 FormEditGmailAccount::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 FormEditGmailAccount::hookNetwork() { + connect(m_oauth, &OAuth2Service::tokensReceived, this, &FormEditGmailAccount::onAuthGranted); + connect(m_oauth, &OAuth2Service::tokensRetrieveError, this, &FormEditGmailAccount::onAuthError); + connect(m_oauth, &OAuth2Service::authFailed, this, &FormEditGmailAccount::onAuthFailed); +} + +GmailServiceRoot* FormEditGmailAccount::execForCreate() { + setWindowTitle(tr("Add new Gmail account")); + + m_ui.m_txtAppId->lineEdit()->clear(); + m_ui.m_txtAppKey->lineEdit()->clear(); + m_ui.m_txtRedirectUrl->lineEdit()->setText(LOCALHOST_ADDRESS); + + exec(); + + return m_editableRoot; +} + +void FormEditGmailAccount::execForEdit(GmailServiceRoot* existing_root) { + setWindowTitle(tr("Edit existing Gmail account")); + m_editableRoot = existing_root; + + // We copy settings from existing OAuth to our testing OAuth. + m_oauth->setClientId(existing_root->network()->oauth()->clientId()); + m_oauth->setClientSecret(existing_root->network()->oauth()->clientSecret()); + m_oauth->setRedirectUrl(existing_root->network()->oauth()->redirectUrl()); + m_oauth->setRefreshToken(existing_root->network()->oauth()->refreshToken()); + m_oauth->setAccessToken(existing_root->network()->oauth()->accessToken()); + m_oauth->setTokensExpireIn(existing_root->network()->oauth()->tokensExpireIn()); + + // Setup the GUI. + m_ui.m_txtAppId->lineEdit()->setText(existing_root->network()->oauth()->clientId()); + m_ui.m_txtAppKey->lineEdit()->setText(existing_root->network()->oauth()->clientSecret()); + m_ui.m_txtRedirectUrl->lineEdit()->setText(existing_root->network()->oauth()->redirectUrl()); + + m_ui.m_txtUsername->lineEdit()->setText(existing_root->network()->userName()); + m_ui.m_spinLimitMessages->setValue(existing_root->network()->batchSize()); + + exec(); +} + +void FormEditGmailAccount::checkOAuthValue(const QString& value) { + LineEditWithStatus* line_edit = qobject_cast(sender()->parent()); + + if (line_edit != nullptr) { + if (value.isEmpty()) { + line_edit->setStatus(WidgetWithStatus::Error, tr("Empty value is entered.")); + } + else { + line_edit->setStatus(WidgetWithStatus::Ok, tr("Some value is entered.")); + } + } +} diff --git a/src/services/gmail/gui/formeditgmailaccount.h b/src/services/gmail/gui/formeditgmailaccount.h new file mode 100755 index 000000000..e4ad8cbd1 --- /dev/null +++ b/src/services/gmail/gui/formeditgmailaccount.h @@ -0,0 +1,63 @@ +// This file is part of RSS Guard. + +// +// Copyright (C) 2011-2017 by Martin Rotter +// +// RSS Guard is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// RSS Guard is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with RSS Guard. If not, see . + +#ifndef FORMEDITINOREADERACCOUNT_H +#define FORMEDITINOREADERACCOUNT_H + +#include + +#include "ui_formeditgmailaccount.h" + +#include "services/gmail/network/gmailnetworkfactory.h" + +namespace Ui { + class FormEditGmailAccount; +} + +class GmailServiceRoot; + +class FormEditGmailAccount : public QDialog { + Q_OBJECT + + public: + explicit FormEditGmailAccount(QWidget* parent = nullptr); + virtual ~FormEditGmailAccount(); + + GmailServiceRoot* execForCreate(); + + void execForEdit(GmailServiceRoot* existing_root); + + private slots: + void testSetup(); + void onClickedOk(); + void onClickedCancel(); + void checkOAuthValue(const QString& value); + void checkUsername(const QString& username); + void onAuthFailed(); + void onAuthError(const QString& error, const QString& detailed_description); + void onAuthGranted(); + + private: + void hookNetwork(); + + Ui::FormEditGmailAccount m_ui; + OAuth2Service* m_oauth; + GmailServiceRoot* m_editableRoot; +}; + +#endif // FORMEDITINOREADERACCOUNT_H diff --git a/src/services/gmail/gui/formeditgmailaccount.ui b/src/services/gmail/gui/formeditgmailaccount.ui new file mode 100755 index 000000000..24662262e --- /dev/null +++ b/src/services/gmail/gui/formeditgmailaccount.ui @@ -0,0 +1,190 @@ + + + FormEditGmailAccount + + + + 0 + 0 + 542 + 363 + + + + + + + + + Username + + + + + + + + + + OAuth 2.0 settings + + + + + + Application ID + + + + + + + + + + Application key + + + + + + + + + + Redirect URL + + + + + + + + + + Predefined settings DO NOT have to be changed from their default values. Change these values only of you are advanced user and you know what you are doing! + + + true + + + + + + + + + + + + Only download newest X messages per feed + + + + + + + + 140 + 16777215 + + + + message(s) + + + + + + + + + + + &Login + + + + + + + + 0 + 1 + + + + Qt::RightToLeft + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + LineEditWithStatus + QWidget +
lineeditwithstatus.h
+ 1 +
+ + LabelWithStatus + QWidget +
labelwithstatus.h
+ 1 +
+
+ + m_spinLimitMessages + m_btnTestSetup + + + + + m_buttonBox + accepted() + FormEditGmailAccount + accept() + + + 248 + 254 + + + 157 + 274 + + + + + m_buttonBox + rejected() + FormEditGmailAccount + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/src/services/inoreader/definitions.h b/src/services/inoreader/definitions.h index 1056fa7c1..743ec9fab 100755 --- a/src/services/inoreader/definitions.h +++ b/src/services/inoreader/definitions.h @@ -23,7 +23,6 @@ #define INOREADER_OAUTH_TOKEN_URL "https://www.inoreader.com/oauth2/token" #define INOREADER_OAUTH_AUTH_URL "https://www.inoreader.com/oauth2/auth" -#define INOREADER_OAUTH_CLI_REDIRECT "http://localhost" #define INOREADER_OAUTH_CLI_ID "1000000604" #define INOREADER_OAUTH_CLI_KEY "gsStoZ3aAoQJCgQxoFSuXkWI7Sly87yK" diff --git a/src/services/inoreader/gui/formeditinoreaderaccount.cpp b/src/services/inoreader/gui/formeditinoreaderaccount.cpp index c07004014..0f5b89b3f 100755 --- a/src/services/inoreader/gui/formeditinoreaderaccount.cpp +++ b/src/services/inoreader/gui/formeditinoreaderaccount.cpp @@ -157,7 +157,7 @@ InoreaderServiceRoot* FormEditInoreaderAccount::execForCreate() { m_ui.m_txtAppId->lineEdit()->setText(INOREADER_OAUTH_CLI_ID); m_ui.m_txtAppKey->lineEdit()->setText(INOREADER_OAUTH_CLI_KEY); - m_ui.m_txtRedirectUrl->lineEdit()->setText(INOREADER_OAUTH_CLI_REDIRECT); + m_ui.m_txtRedirectUrl->lineEdit()->setText(LOCALHOST_ADDRESS); exec();