From eeedf8b1a50ea199c56dfc9f7d29126a962fbc8f Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 16 Mar 2023 15:02:06 +0100 Subject: [PATCH] work on #909 --- src/librssguard/database/databasequeries.cpp | 1 - .../network-web/networkfactory.cpp | 30 ++++++--- src/librssguard/network-web/networkfactory.h | 6 +- src/librssguard/network-web/oauth2service.cpp | 8 ++- src/librssguard/services/abstract/feed.h | 2 + .../abstract/gui/authenticationdetails.cpp | 63 +++++++++++++------ .../abstract/gui/authenticationdetails.h | 9 ++- .../abstract/gui/authenticationdetails.ui | 28 ++++++--- .../owncloud/owncloudnetworkfactory.cpp | 21 ++++--- .../standard/gui/formstandardfeeddetails.cpp | 37 +++++++---- .../standard/gui/standardfeeddetails.cpp | 6 +- .../standard/gui/standardfeeddetails.h | 2 + .../services/standard/standardfeed.cpp | 21 ++++--- .../services/standard/standardfeed.h | 26 ++++---- .../standardfeedsimportexportmodel.cpp | 1 + .../services/standard/standardserviceroot.cpp | 2 +- .../tt-rss/gui/formttrssfeeddetails.cpp | 39 ++++++------ .../services/tt-rss/ttrssnetworkfactory.cpp | 30 +++++---- 18 files changed, 214 insertions(+), 118 deletions(-) diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index 4fcd7abd6..59ab18132 100644 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -60,7 +60,6 @@ QVariantHash DatabaseQueries::deserializeCustomData(const QString& data) { } else { auto json = QJsonDocument::fromJson(data.toUtf8()); - auto json_obj = json.object(); return json.object().toVariantHash(); } diff --git a/src/librssguard/network-web/networkfactory.cpp b/src/librssguard/network-web/networkfactory.cpp index 5a008b014..01ba996b2 100644 --- a/src/librssguard/network-web/networkfactory.cpp +++ b/src/librssguard/network-web/networkfactory.cpp @@ -44,16 +44,30 @@ QStringList NetworkFactory::extractFeedLinksFromHtmlPage(const QUrl& url, const return feeds; } -QPair NetworkFactory::generateBasicAuthHeader(const QString& username, +QPair NetworkFactory::generateBasicAuthHeader(Feed::Protection protection, + const QString& username, const QString& password) { - if (username.isEmpty()) { - return QPair(QByteArray(), QByteArray()); - } - else { - QString basic_value = username + QSL(":") + password; - QString header_value = QSL("Basic ") + QString(basic_value.toUtf8().toBase64()); + switch (protection) { + case Feed::Protection::NoProtection: + return {}; - return QPair(HTTP_HEADERS_AUTHORIZATION, header_value.toLocal8Bit()); + case Feed::Protection::BasicProtection: { + if (username.isEmpty()) { + return {}; + } + else { + QString basic_value = username + QSL(":") + password; + QString header_value = QSL("Basic ") + QString(basic_value.toUtf8().toBase64()); + + return QPair(HTTP_HEADERS_AUTHORIZATION, header_value.toLocal8Bit()); + } + } + + case Feed::Protection::TokenProtection: { + QString header_value = QSL("Bearer ") + username; + + return QPair(HTTP_HEADERS_AUTHORIZATION, header_value.toLocal8Bit()); + } } } diff --git a/src/librssguard/network-web/networkfactory.h b/src/librssguard/network-web/networkfactory.h index 5e364b07b..bae312342 100644 --- a/src/librssguard/network-web/networkfactory.h +++ b/src/librssguard/network-web/networkfactory.h @@ -5,6 +5,8 @@ #include "network-web/httpresponse.h" +#include "services/abstract/feed.h" + #include #include #include @@ -37,7 +39,9 @@ class NetworkFactory { public: static QStringList extractFeedLinksFromHtmlPage(const QUrl& url, const QString& html); - static QPair generateBasicAuthHeader(const QString& username, const QString& password); + static QPair generateBasicAuthHeader(Feed::Protection protection, + const QString& username, + const QString& password); // Returns human readable text for given network error. static QString networkErrorText(QNetworkReply::NetworkError error_code); diff --git a/src/librssguard/network-web/oauth2service.cpp b/src/librssguard/network-web/oauth2service.cpp index b82c78ddb..4ea0ef064 100644 --- a/src/librssguard/network-web/oauth2service.cpp +++ b/src/librssguard/network-web/oauth2service.cpp @@ -175,7 +175,9 @@ void OAuth2Service::retrieveAccessToken(const QString& auth_code) { network_request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/x-www-form-urlencoded"); if (m_useHttpBasicAuthWithClientData) { - auto basic_auth = NetworkFactory::generateBasicAuthHeader(properClientId(), properClientSecret()); + auto basic_auth = NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, + properClientId(), + properClientSecret()); network_request.setRawHeader(basic_auth.first, basic_auth.second); } @@ -203,7 +205,9 @@ void OAuth2Service::refreshAccessToken(const QString& refresh_token) { network_request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/x-www-form-urlencoded"); if (m_useHttpBasicAuthWithClientData) { - auto basic_auth = NetworkFactory::generateBasicAuthHeader(properClientId(), properClientSecret()); + auto basic_auth = NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, + properClientId(), + properClientSecret()); network_request.setRawHeader(basic_auth.first, basic_auth.second); } diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index 7522f2ac0..d7b229a16 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -19,6 +19,8 @@ class Feed : public RootItem { // Specifies the auto-download strategy for the feed. enum class AutoUpdateType { DontAutoUpdate = 0, DefaultAutoUpdate = 1, SpecificAutoUpdate = 2 }; + enum class Protection { NoProtection = 0, BasicProtection = 1, TokenProtection = 2 }; + // Specifies the actual "status" of the feed. // For example if it has new messages, error // occurred, and so on. diff --git a/src/librssguard/services/abstract/gui/authenticationdetails.cpp b/src/librssguard/services/abstract/gui/authenticationdetails.cpp index 7c2ac7d87..9d32dd4f3 100644 --- a/src/librssguard/services/abstract/gui/authenticationdetails.cpp +++ b/src/librssguard/services/abstract/gui/authenticationdetails.cpp @@ -2,7 +2,7 @@ #include "services/abstract/gui/authenticationdetails.h" -AuthenticationDetails::AuthenticationDetails(QWidget* parent) : QWidget(parent) { +AuthenticationDetails::AuthenticationDetails(bool only_basic, QWidget* parent) : QWidget(parent) { setupUi(this); // Set text boxes. @@ -12,37 +12,64 @@ AuthenticationDetails::AuthenticationDetails(QWidget* parent) : QWidget(parent) m_txtPassword->lineEdit()->setPlaceholderText(tr("Password")); m_txtPassword->lineEdit()->setToolTip(tr("Set password to access the feed.")); + m_cbAuthType->addItem(tr("No authentication"), QVariant::fromValue(Feed::Protection::NoProtection)); + m_cbAuthType->addItem(tr("HTTP Basic"), QVariant::fromValue(Feed::Protection::BasicProtection)); + + if (!only_basic) { + m_cbAuthType->addItem(tr("Token"), QVariant::fromValue(Feed::Protection::TokenProtection)); + } + connect(m_txtUsername->lineEdit(), &BaseLineEdit::textChanged, this, &AuthenticationDetails::onUsernameChanged); connect(m_txtPassword->lineEdit(), &BaseLineEdit::textChanged, this, &AuthenticationDetails::onPasswordChanged); - connect(m_gbAuthentication, &QGroupBox::toggled, this, &AuthenticationDetails::onAuthenticationSwitched); + connect(m_cbAuthType, &QComboBox::currentIndexChanged, this, &AuthenticationDetails::onAuthenticationSwitched); - onUsernameChanged(QString()); - onPasswordChanged(QString()); + onAuthenticationSwitched(); +} + +void AuthenticationDetails::setAuthenticationType(Feed::Protection protect) { + auto fnd = m_cbAuthType->findData(QVariant::fromValue(protect)); + + if (fnd >= 0) { + m_cbAuthType->setCurrentIndex(fnd); + } +} + +Feed::Protection AuthenticationDetails::authenticationType() const { + return m_cbAuthType->currentData().value(); } void AuthenticationDetails::onUsernameChanged(const QString& new_username) { - bool is_username_ok = !m_gbAuthentication->isChecked() || !new_username.simplified().isEmpty(); + bool is_username_ok = authenticationType() == Feed::Protection::NoProtection || !new_username.simplified().isEmpty(); - m_txtUsername->setStatus(is_username_ok ? - LineEditWithStatus::StatusType::Ok : - LineEditWithStatus::StatusType::Warning, - is_username_ok ? - tr("Username is ok or it is not needed.") : - tr("Username is empty.")); + m_txtUsername->setStatus(is_username_ok ? LineEditWithStatus::StatusType::Ok + : LineEditWithStatus::StatusType::Warning, + is_username_ok ? tr("Username/token is ok or it is not needed.") + : tr("Username/token is empty.")); } void AuthenticationDetails::onPasswordChanged(const QString& new_password) { - bool is_password_ok = !m_gbAuthentication->isChecked() || !new_password.simplified().isEmpty(); + bool is_password_ok = authenticationType() == Feed::Protection::NoProtection || !new_password.simplified().isEmpty(); - m_txtPassword->setStatus(is_password_ok ? - LineEditWithStatus::StatusType::Ok : - LineEditWithStatus::StatusType::Warning, - is_password_ok ? - tr("Password is ok or it is not needed.") : - tr("Password is empty.")); + m_txtPassword->setStatus(is_password_ok ? LineEditWithStatus::StatusType::Ok + : LineEditWithStatus::StatusType::Warning, + is_password_ok ? tr("Password is ok or it is not needed.") : tr("Password is empty.")); } void AuthenticationDetails::onAuthenticationSwitched() { onUsernameChanged(m_txtUsername->lineEdit()->text()); onPasswordChanged(m_txtPassword->lineEdit()->text()); + + auto prot = authenticationType(); + + m_lblPassword->setVisible(prot != Feed::Protection::TokenProtection); + m_txtPassword->setVisible(prot != Feed::Protection::TokenProtection); + + if (prot == Feed::Protection::TokenProtection) { + m_lblUsername->setText(tr("Access token")); + } + else { + m_lblUsername->setText(tr("Username")); + } + + m_gbAuthentication->setEnabled(prot != Feed::Protection::NoProtection); } diff --git a/src/librssguard/services/abstract/gui/authenticationdetails.h b/src/librssguard/services/abstract/gui/authenticationdetails.h index 7e8eb29e7..bc9bfc937 100644 --- a/src/librssguard/services/abstract/gui/authenticationdetails.h +++ b/src/librssguard/services/abstract/gui/authenticationdetails.h @@ -7,11 +7,16 @@ #include "ui_authenticationdetails.h" +#include "services/abstract/feed.h" + class AuthenticationDetails : public QWidget, public Ui::AuthenticationDetails { - Q_OBJECT + Q_OBJECT public: - explicit AuthenticationDetails(QWidget* parent = nullptr); + explicit AuthenticationDetails(bool only_basic, QWidget* parent = nullptr); + + void setAuthenticationType(Feed::Protection protect); + Feed::Protection authenticationType() const; private slots: void onUsernameChanged(const QString& new_username); diff --git a/src/librssguard/services/abstract/gui/authenticationdetails.ui b/src/librssguard/services/abstract/gui/authenticationdetails.ui index ee6e38413..050b6302d 100644 --- a/src/librssguard/services/abstract/gui/authenticationdetails.ui +++ b/src/librssguard/services/abstract/gui/authenticationdetails.ui @@ -14,26 +14,23 @@ Form - + Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported. - Requires HTTP authentication + Credentials false - - true - false - + Username @@ -46,7 +43,7 @@ - + Password @@ -61,6 +58,19 @@ + + + + Authentication type + + + m_cbAuthType + + + + + + @@ -71,6 +81,10 @@ 1 + + m_cbAuthType + m_gbAuthentication + diff --git a/src/librssguard/services/owncloud/owncloudnetworkfactory.cpp b/src/librssguard/services/owncloud/owncloudnetworkfactory.cpp index 2c395c90c..8c4277696 100644 --- a/src/librssguard/services/owncloud/owncloudnetworkfactory.cpp +++ b/src/librssguard/services/owncloud/owncloudnetworkfactory.cpp @@ -79,7 +79,7 @@ OwnCloudStatusResponse OwnCloudNetworkFactory::status(const QNetworkProxy& custo QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlStatus, @@ -111,7 +111,7 @@ OwnCloudGetFeedsCategoriesResponse OwnCloudNetworkFactory::feedsCategories(const QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFolders, @@ -166,7 +166,7 @@ bool OwnCloudNetworkFactory::deleteFeed(const QString& feed_id, const QNetworkPr QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url, @@ -210,7 +210,7 @@ bool OwnCloudNetworkFactory::createFeed(const QString& url, int parent_id, const QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFeeds, @@ -248,7 +248,7 @@ bool OwnCloudNetworkFactory::renameFeed(const QString& new_name, QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url, @@ -287,7 +287,7 @@ OwnCloudGetMessagesResponse OwnCloudNetworkFactory::getMessages(int feed_id, con QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url, @@ -318,7 +318,7 @@ QNetworkReply::NetworkError OwnCloudNetworkFactory::triggerFeedUpdate(int feed_i QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFeedsUpdate.arg(authUsername(), QString::number(feed_id)), @@ -365,7 +365,7 @@ NetworkResult OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus stat QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); QByteArray output; @@ -411,7 +411,7 @@ NetworkResult OwnCloudNetworkFactory::markMessagesStarred(RootItem::Importance i QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, OWNCLOUD_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); QByteArray output; @@ -614,7 +614,8 @@ QList OwnCloudGetMessagesResponse::messages() const { enclosure.m_mimeType = QSL("image/png"); } - if (!message_map[QSL("enclosureMime")].toString().isEmpty() || !enclosure_link.startsWith(QSL("https://www.youtube.com/v/"))) { + if (!message_map[QSL("enclosureMime")].toString().isEmpty() || + !enclosure_link.startsWith(QSL("https://www.youtube.com/v/"))) { msg.m_enclosures.append(enclosure); } } diff --git a/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp b/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp index df6d0fa51..ed10e40c8 100644 --- a/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp +++ b/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp @@ -22,18 +22,25 @@ #include #include -FormStandardFeedDetails::FormStandardFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select, - const QString& url, QWidget* parent) +FormStandardFeedDetails::FormStandardFeedDetails(ServiceRoot* service_root, + RootItem* parent_to_select, + const QString& url, + QWidget* parent) : FormFeedDetails(service_root, parent), m_standardFeedDetails(new StandardFeedDetails(this)), - m_authDetails(new AuthenticationDetails(this)), m_parentToSelect(parent_to_select), m_urlToProcess(url) { + m_authDetails(new AuthenticationDetails(false, this)), m_parentToSelect(parent_to_select), m_urlToProcess(url) { insertCustomTab(m_standardFeedDetails, tr("General"), 0); insertCustomTab(m_authDetails, tr("Network"), 2); activateTab(0); - connect(m_standardFeedDetails->m_ui.m_btnFetchMetadata, &QPushButton::clicked, this, &FormStandardFeedDetails::guessFeed); + connect(m_standardFeedDetails->m_ui.m_btnFetchMetadata, + &QPushButton::clicked, + this, + &FormStandardFeedDetails::guessFeed); connect(m_standardFeedDetails->m_actionFetchIcon, &QAction::triggered, this, &FormStandardFeedDetails::guessIconOnly); - connect(m_standardFeedDetails->m_ui.m_txtTitle->lineEdit(), &QLineEdit::textChanged, - this, &FormStandardFeedDetails::onTitleChanged); + connect(m_standardFeedDetails->m_ui.m_txtTitle->lineEdit(), + &QLineEdit::textChanged, + this, + &FormStandardFeedDetails::onTitleChanged); onTitleChanged(m_standardFeedDetails->m_ui.m_txtTitle->lineEdit()->text()); } @@ -42,6 +49,7 @@ void FormStandardFeedDetails::guessFeed() { m_standardFeedDetails->guessFeed(m_standardFeedDetails->sourceType(), m_standardFeedDetails->m_ui.m_txtSource->textEdit()->toPlainText(), m_standardFeedDetails->m_ui.m_txtPostProcessScript->textEdit()->toPlainText(), + m_authDetails->authenticationType(), m_authDetails->m_txtUsername->lineEdit()->text(), m_authDetails->m_txtPassword->lineEdit()->text(), m_serviceRoot->networkProxy()); @@ -51,6 +59,7 @@ void FormStandardFeedDetails::guessIconOnly() { m_standardFeedDetails->guessIconOnly(m_standardFeedDetails->sourceType(), m_standardFeedDetails->m_ui.m_txtSource->textEdit()->toPlainText(), m_standardFeedDetails->m_ui.m_txtPostProcessScript->textEdit()->toPlainText(), + m_authDetails->authenticationType(), m_authDetails->m_txtUsername->lineEdit()->text(), m_authDetails->m_txtPassword->lineEdit()->text(), m_serviceRoot->networkProxy()); @@ -65,11 +74,14 @@ void FormStandardFeedDetails::apply() { auto* std_feed = feed(); RootItem* parent = - static_cast(m_standardFeedDetails->m_ui.m_cmbParentCategory->itemData( - m_standardFeedDetails->m_ui.m_cmbParentCategory->currentIndex()).value()); + static_cast(m_standardFeedDetails->m_ui.m_cmbParentCategory + ->itemData(m_standardFeedDetails->m_ui.m_cmbParentCategory->currentIndex()) + .value()); StandardFeed::Type type = - static_cast(m_standardFeedDetails->m_ui.m_cmbType->itemData(m_standardFeedDetails->m_ui.m_cmbType->currentIndex()).value()); + static_cast(m_standardFeedDetails->m_ui.m_cmbType + ->itemData(m_standardFeedDetails->m_ui.m_cmbType->currentIndex()) + .value()); // Setup data for new_feed. std_feed->setTitle(m_standardFeedDetails->m_ui.m_txtTitle->lineEdit()->text().simplified()); @@ -83,7 +95,8 @@ void FormStandardFeedDetails::apply() { std_feed->setType(type); std_feed->setSourceType(m_standardFeedDetails->sourceType()); std_feed->setPostProcessScript(m_standardFeedDetails->m_ui.m_txtPostProcessScript->textEdit()->toPlainText()); - std_feed->setPasswordProtected(m_authDetails->m_gbAuthentication->isChecked()); + + std_feed->setProtection(m_authDetails->authenticationType()); std_feed->setUsername(m_authDetails->m_txtUsername->lineEdit()->text()); std_feed->setPassword(m_authDetails->m_txtPassword->lineEdit()->text()); @@ -97,7 +110,7 @@ void FormStandardFeedDetails::apply() { } m_serviceRoot->requestItemReassignment(m_feed, parent); - m_serviceRoot->itemChanged({ m_feed }); + m_serviceRoot->itemChanged({m_feed}); } void FormStandardFeedDetails::loadFeedData() { @@ -108,7 +121,7 @@ void FormStandardFeedDetails::loadFeedData() { // Load categories. m_standardFeedDetails->loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot); - m_authDetails->m_gbAuthentication->setChecked(std_feed->passwordProtected()); + m_authDetails->setAuthenticationType(std_feed->protection()); m_authDetails->m_txtUsername->lineEdit()->setText(std_feed->username()); m_authDetails->m_txtPassword->lineEdit()->setText(std_feed->password()); diff --git a/src/librssguard/services/standard/gui/standardfeeddetails.cpp b/src/librssguard/services/standard/gui/standardfeeddetails.cpp index 23adf1e9a..14f58bf2c 100644 --- a/src/librssguard/services/standard/gui/standardfeeddetails.cpp +++ b/src/librssguard/services/standard/gui/standardfeeddetails.cpp @@ -131,12 +131,13 @@ StandardFeedDetails::StandardFeedDetails(QWidget* parent) : QWidget(parent) { void StandardFeedDetails::guessIconOnly(StandardFeed::SourceType source_type, const QString& source, const QString& post_process_script, + Feed::Protection protection, const QString& username, const QString& password, const QNetworkProxy& custom_proxy) { try { StandardFeed* metadata = - StandardFeed::guessFeed(source_type, source, post_process_script, username, password, custom_proxy); + StandardFeed::guessFeed(source_type, source, post_process_script, protection, username, password, custom_proxy); // Icon or whole feed was guessed. m_ui.m_btnIcon->setIcon(metadata->icon()); @@ -167,12 +168,13 @@ void StandardFeedDetails::guessIconOnly(StandardFeed::SourceType source_type, void StandardFeedDetails::guessFeed(StandardFeed::SourceType source_type, const QString& source, const QString& post_process_script, + Feed::Protection protection, const QString& username, const QString& password, const QNetworkProxy& custom_proxy) { try { StandardFeed* metadata = - StandardFeed::guessFeed(source_type, source, post_process_script, username, password, custom_proxy); + StandardFeed::guessFeed(source_type, source, post_process_script, protection, username, password, custom_proxy); // Icon or whole feed was guessed. m_ui.m_btnIcon->setIcon(metadata->icon()); diff --git a/src/librssguard/services/standard/gui/standardfeeddetails.h b/src/librssguard/services/standard/gui/standardfeeddetails.h index 3ceec3346..006edae0d 100644 --- a/src/librssguard/services/standard/gui/standardfeeddetails.h +++ b/src/librssguard/services/standard/gui/standardfeeddetails.h @@ -28,12 +28,14 @@ class StandardFeedDetails : public QWidget { void guessIconOnly(StandardFeed::SourceType source_type, const QString& source, const QString& post_process_script, + Feed::Protection protection, const QString& username, const QString& password, const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy); void guessFeed(StandardFeed::SourceType source_type, const QString& source, const QString& post_process_script, + Feed::Protection protection, const QString& username, const QString& password, const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy); diff --git a/src/librssguard/services/standard/standardfeed.cpp b/src/librssguard/services/standard/standardfeed.cpp index 991ac98f1..008f56309 100644 --- a/src/librssguard/services/standard/standardfeed.cpp +++ b/src/librssguard/services/standard/standardfeed.cpp @@ -42,7 +42,7 @@ StandardFeed::StandardFeed(RootItem* parent_item) : Feed(parent_item) { m_sourceType = SourceType::Url; m_encoding = m_postProcessScript = QString(); - m_passwordProtected = false; + m_protection = Protection::NoProtection; m_username = QString(); m_password = QString(); } @@ -52,7 +52,7 @@ StandardFeed::StandardFeed(const StandardFeed& other) : Feed(other) { m_postProcessScript = other.postProcessScript(); m_sourceType = other.sourceType(); m_encoding = other.encoding(); - m_passwordProtected = other.passwordProtected(); + m_protection = other.protection(); m_username = other.username(); m_password = other.password(); } @@ -95,12 +95,12 @@ bool StandardFeed::deleteViaGui() { } } -bool StandardFeed::passwordProtected() const { - return m_passwordProtected; +StandardFeed::Protection StandardFeed::protection() const { + return m_protection; } -void StandardFeed::setPasswordProtected(bool passwordProtected) { - m_passwordProtected = passwordProtected; +void StandardFeed::setProtection(Protection protect) { + m_protection = protect; } QString StandardFeed::username() const { @@ -126,7 +126,7 @@ QVariantHash StandardFeed::customDatabaseData() const { data[QSL("type")] = int(type()); data[QSL("encoding")] = encoding(); data[QSL("post_process")] = postProcessScript(); - data[QSL("protected")] = passwordProtected(); + data[QSL("protected")] = int(protection()); data[QSL("username")] = username(); data[QSL("password")] = TextFactory::encrypt(password()); @@ -138,7 +138,7 @@ void StandardFeed::setCustomDatabaseData(const QVariantHash& data) { setType(Type(data[QSL("type")].toInt())); setEncoding(data[QSL("encoding")].toString()); setPostProcessScript(data[QSL("post_process")].toString()); - setPasswordProtected(data[QSL("protected")].toBool()); + setProtection(Protection(data[QSL("protected")].toInt())); setUsername(data[QSL("username")].toString()); setPassword(TextFactory::decrypt(data[QSL("password")].toString())); } @@ -184,6 +184,7 @@ void StandardFeed::fetchMetadataForItself() { StandardFeed* metadata = guessFeed(sourceType(), source(), postProcessScript(), + protection(), username(), password(), getParentServiceRoot()->networkProxy()); @@ -230,6 +231,7 @@ void StandardFeed::setSourceType(SourceType source_type) { StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type, const QString& source, const QString& post_process_script, + Feed::Protection protection, const QString& username, const QString& password, const QNetworkProxy& custom_proxy) { @@ -238,7 +240,8 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type, QString content_type; if (source_type == StandardFeed::SourceType::Url) { - QList> headers = {NetworkFactory::generateBasicAuthHeader(username, password)}; + QList> headers = { + NetworkFactory::generateBasicAuthHeader(protection, username, password)}; NetworkResult network_result = NetworkFactory::performNetworkOperation(source, timeout, diff --git a/src/librssguard/services/standard/standardfeed.h b/src/librssguard/services/standard/standardfeed.h index 50d22131a..0538af3e2 100644 --- a/src/librssguard/services/standard/standardfeed.h +++ b/src/librssguard/services/standard/standardfeed.h @@ -17,21 +17,17 @@ class StandardServiceRoot; // Represents BASE class for feeds contained in FeedsModel. // NOTE: This class should be derived to create PARTICULAR feed types. class StandardFeed : public Feed { - Q_OBJECT + Q_OBJECT - friend class StandardCategory; + friend class StandardCategory; public: - enum class SourceType { - Url = 0, - Script = 1, - LocalFile = 2 - }; + enum class SourceType { Url = 0, Script = 1, LocalFile = 2 }; enum class Type { Rss0X = 0, Rss2X = 1, - Rdf = 2, // Sometimes denoted as RSS 1.0. + Rdf = 2, // Sometimes denoted as RSS 1.0. Atom10 = 3, Json = 4 }; @@ -62,8 +58,8 @@ class StandardFeed : public Feed { QString postProcessScript() const; void setPostProcessScript(const QString& post_process_script); - bool passwordProtected() const; - void setPasswordProtected(bool passwordProtected); + Protection protection() const; + void setProtection(Protection protect); QString username() const; void setUsername(const QString& username); @@ -79,6 +75,7 @@ class StandardFeed : public Feed { static StandardFeed* guessFeed(SourceType source_type, const QString& url, const QString& post_process_script, + Protection protection, const QString& username = QString(), const QString& password = QString(), const QNetworkProxy& custom_proxy = QNetworkProxy::ProxyType::DefaultProxy); @@ -93,8 +90,11 @@ class StandardFeed : public Feed { static QString postProcessFeedFileWithScript(const QString& execution_line, const QString& raw_feed_data, int run_timeout); - static QString runScriptProcess(const QStringList& cmd_args, const QString& working_directory, - int run_timeout, bool provide_input, const QString& input = {}); + static QString runScriptProcess(const QStringList& cmd_args, + const QString& working_directory, + int run_timeout, + bool provide_input, + const QString& input = {}); public slots: void fetchMetadataForItself(); @@ -108,7 +108,7 @@ class StandardFeed : public Feed { Type m_type; QString m_postProcessScript; QString m_encoding; - bool m_passwordProtected{}; + Protection m_protection = Protection::NoProtection; QString m_username; QString m_password; }; diff --git a/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp b/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp index a3b0de700..bb9c0e1ad 100644 --- a/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp +++ b/src/librssguard/services/standard/standardfeedsimportexportmodel.cpp @@ -184,6 +184,7 @@ bool FeedsImportExportModel::produceFeed(const FeedLookup& feed_lookup) { new_feed = StandardFeed::guessFeed(StandardFeed::SourceType::Url, feed_lookup.url, feed_lookup.post_process_script, + Feed::Protection::NoProtection, {}, {}, feed_lookup.custom_proxy); diff --git a/src/librssguard/services/standard/standardserviceroot.cpp b/src/librssguard/services/standard/standardserviceroot.cpp index 24763c457..f7014739b 100644 --- a/src/librssguard/services/standard/standardserviceroot.cpp +++ b/src/librssguard/services/standard/standardserviceroot.cpp @@ -165,7 +165,7 @@ QList StandardServiceRoot::obtainNewMessages(Feed* feed, QByteArray feed_contents; QList> headers; - headers << NetworkFactory::generateBasicAuthHeader(f->username(), f->password()); + headers << NetworkFactory::generateBasicAuthHeader(f->protection(), f->username(), f->password()); auto network_result = NetworkFactory::performNetworkOperation(feed->source(), download_timeout, diff --git a/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp b/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp index 28ec35b13..b843a6ae7 100644 --- a/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp +++ b/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp @@ -16,11 +16,12 @@ #include #include -FormTtRssFeedDetails::FormTtRssFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select, - const QString& url, QWidget* parent) +FormTtRssFeedDetails::FormTtRssFeedDetails(ServiceRoot* service_root, + RootItem* parent_to_select, + const QString& url, + QWidget* parent) : FormFeedDetails(service_root, parent), m_feedDetails(new TtRssFeedDetails(this)), - m_authDetails(new AuthenticationDetails(this)), m_parentToSelect(parent_to_select), - m_urlToProcess(url) {} + m_authDetails(new AuthenticationDetails(true, this)), m_parentToSelect(parent_to_select), m_urlToProcess(url) {} void FormTtRssFeedDetails::apply() { if (!m_creatingNew) { @@ -29,25 +30,25 @@ void FormTtRssFeedDetails::apply() { FormFeedDetails::apply(); } else { - RootItem* parent = static_cast(m_feedDetails->ui.m_cmbParentCategory->itemData( - m_feedDetails->ui.m_cmbParentCategory->currentIndex()).value()); + RootItem* parent = static_cast(m_feedDetails->ui.m_cmbParentCategory + ->itemData(m_feedDetails->ui.m_cmbParentCategory->currentIndex()) + .value()); auto* root = qobject_cast(parent->getParentServiceRoot()); - const int category_id = parent->kind() == RootItem::Kind::ServiceRoot ? - 0 : - parent->customId().toInt(); - const TtRssSubscribeToFeedResponse response = root->network()->subscribeToFeed(m_feedDetails->ui.m_txtUrl->lineEdit()->text(), - category_id, - m_serviceRoot->networkProxy(), - m_authDetails->m_gbAuthentication->isChecked(), - m_authDetails->m_txtUsername->lineEdit()->text(), - m_authDetails->m_txtPassword->lineEdit()->text()); + const int category_id = parent->kind() == RootItem::Kind::ServiceRoot ? 0 : parent->customId().toInt(); + const TtRssSubscribeToFeedResponse response = + root->network()->subscribeToFeed(m_feedDetails->ui.m_txtUrl->lineEdit()->text(), + category_id, + m_serviceRoot->networkProxy(), + m_authDetails->authenticationType() == Feed::Protection::BasicProtection, + m_authDetails->m_txtUsername->lineEdit()->text(), + m_authDetails->m_txtPassword->lineEdit()->text()); if (response.code() == STF_INSERTED) { // Feed was added online. - qApp->showGuiMessage(Notification::Event::GeneralEvent, { - tr("Feed added"), - tr("Feed was added, obtaining new tree of feeds now."), - QSystemTrayIcon::MessageIcon::Information }); + qApp->showGuiMessage(Notification::Event::GeneralEvent, + {tr("Feed added"), + tr("Feed was added, obtaining new tree of feeds now."), + QSystemTrayIcon::MessageIcon::Information}); QTimer::singleShot(300, root, &TtRssServiceRoot::syncIn); } else { diff --git a/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp b/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp index 8a59d3742..ef52fb68f 100644 --- a/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp +++ b/src/librssguard/services/tt-rss/ttrssnetworkfactory.cpp @@ -87,7 +87,7 @@ TtRssLoginResponse TtRssNetworkFactory::login(const QNetworkProxy& proxy) { QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -126,7 +126,9 @@ TtRssResponse TtRssNetworkFactory::logout(const QNetworkProxy& proxy) { QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, + m_authUsername, + m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -171,7 +173,7 @@ TtRssGetLabelsResponse TtRssNetworkFactory::getLabels(const QNetworkProxy& proxy QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -222,7 +224,7 @@ TtRssResponse TtRssNetworkFactory::shareToPublished(const TtRssNoteToPublish& no QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -275,7 +277,7 @@ TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories(const QN QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -335,7 +337,7 @@ TtRssGetCompactHeadlinesResponse TtRssNetworkFactory::getCompactHeadlines(int fe QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -397,7 +399,7 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getArticle(const QStringList& art QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -464,7 +466,7 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -522,7 +524,7 @@ TtRssResponse TtRssNetworkFactory::setArticleLabel(const QStringList& article_id QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -581,7 +583,7 @@ TtRssUpdateArticleResponse TtRssNetworkFactory::updateArticles(const QStringList QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -645,7 +647,7 @@ TtRssSubscribeToFeedResponse TtRssNetworkFactory::subscribeToFeed(const QString& QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -697,7 +699,7 @@ TtRssUnsubscribeFeedResponse TtRssNetworkFactory::unsubscribeFeed(int feed_id, c QList> headers; headers << QPair(HTTP_HEADERS_CONTENT_TYPE, TTRSS_CONTENT_TYPE_JSON); - headers << NetworkFactory::generateBasicAuthHeader(m_authUsername, m_authPassword); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, m_authUsername, m_authPassword); NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_fullUrl, @@ -947,7 +949,9 @@ RootItem* TtRssGetFeedsCategoriesResponse::feedsCategories(TtRssNetworkFactory* QList> headers; if (network->authIsUsed()) { - headers << NetworkFactory::generateBasicAuthHeader(network->authUsername(), network->authPassword()); + headers << NetworkFactory::generateBasicAuthHeader(Feed::Protection::BasicProtection, + network->authUsername(), + network->authPassword()); } auto res =