From bfe019f22c280c4f26191db27a183aa26c562f3b Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 23 Mar 2021 10:07:26 +0100 Subject: [PATCH] initial non-persistent support for cookies, #391 --- src/librssguard/definitions/definitions.h | 1 + src/librssguard/librssguard.pro | 2 + src/librssguard/network-web/cookiejar.cpp | 48 +++++++++++++++++++ src/librssguard/network-web/cookiejar.h | 16 +++++++ src/librssguard/network-web/downloader.cpp | 14 ++++++ src/librssguard/network-web/webfactory.cpp | 15 +++++- src/librssguard/network-web/webfactory.h | 9 +++- .../standard/gui/formstandardfeeddetails.cpp | 18 +++++++ .../services/standard/standardfeed.cpp | 2 +- 9 files changed, 120 insertions(+), 5 deletions(-) create mode 100755 src/librssguard/network-web/cookiejar.cpp create mode 100755 src/librssguard/network-web/cookiejar.h diff --git a/src/librssguard/definitions/definitions.h b/src/librssguard/definitions/definitions.h index 98f51c8c2..97d3fca3b 100755 --- a/src/librssguard/definitions/definitions.h +++ b/src/librssguard/definitions/definitions.h @@ -78,6 +78,7 @@ #define DOWNLOADER_ICON_SIZE 48 #define ENCRYPTION_FILE_NAME "key.private" #define RELOAD_MODEL_BORDER_NUM 10 +#define COOKIE_URL_IDENTIFIER ":COOKIE:" #define GOOGLE_SEARCH_URL "https://www.google.com/search?q=%1&ie=utf-8&oe=utf-8" #define GOOGLE_SUGGEST_URL "http://suggestqueries.google.com/complete/search?output=toolbar&hl=en&q=%1" diff --git a/src/librssguard/librssguard.pro b/src/librssguard/librssguard.pro index d963ddd80..a97e3a2fb 100644 --- a/src/librssguard/librssguard.pro +++ b/src/librssguard/librssguard.pro @@ -128,6 +128,7 @@ HEADERS += core/feeddownloader.h \ miscellaneous/templates.h \ miscellaneous/textfactory.h \ network-web/basenetworkaccessmanager.h \ + network-web/cookiejar.h \ network-web/downloader.h \ network-web/downloadmanager.h \ network-web/httpresponse.h \ @@ -302,6 +303,7 @@ SOURCES += core/feeddownloader.cpp \ miscellaneous/systemfactory.cpp \ miscellaneous/textfactory.cpp \ network-web/basenetworkaccessmanager.cpp \ + network-web/cookiejar.cpp \ network-web/downloader.cpp \ network-web/downloadmanager.cpp \ network-web/httpresponse.cpp \ diff --git a/src/librssguard/network-web/cookiejar.cpp b/src/librssguard/network-web/cookiejar.cpp new file mode 100755 index 000000000..c7d349b1f --- /dev/null +++ b/src/librssguard/network-web/cookiejar.cpp @@ -0,0 +1,48 @@ +// For license of this file, see /LICENSE.md. + +#include "network-web/cookiejar.h" + +#include "definitions/definitions.h" + +#include +#include + +CookieJar::CookieJar(QObject* parent) : QNetworkCookieJar(parent) {} + +QList CookieJar::extractCookiesFromUrl(const QString& url) const { + if (!url.contains(QSL(COOKIE_URL_IDENTIFIER))) { + return {}; + } + + int index = url.lastIndexOf(QSL(COOKIE_URL_IDENTIFIER), -1, Qt::CaseSensitivity::CaseInsensitive); + QString cookies_string = url.right(url.length() - index - QSL(COOKIE_URL_IDENTIFIER).size()); + QStringList cookies_list = cookies_string.split(';'); + QList cookies; + + for (const QString& single_cookie : cookies_list) { + const QList& extracted_cookies = QNetworkCookie::parseCookies(single_cookie.toUtf8()); + + if (extracted_cookies.isEmpty()) { + continue; + } + + QNetworkCookie cookie = extracted_cookies.at(0); + QDateTime date = QDateTime::currentDateTime(); + + date = date.addYears(30); + cookie.setExpirationDate(date); + cookies.append(cookie); + } + + return cookies; +} + +bool CookieJar::insertCookies(const QList& cookies) { + bool result = true; + + for (const QNetworkCookie& cookie : cookies) { + result &= insertCookie(cookie); + } + + return result; +} diff --git a/src/librssguard/network-web/cookiejar.h b/src/librssguard/network-web/cookiejar.h new file mode 100755 index 000000000..9045c6da6 --- /dev/null +++ b/src/librssguard/network-web/cookiejar.h @@ -0,0 +1,16 @@ +// For license of this file, see /LICENSE.md. + +#ifndef COOKIEJAR_H +#define COOKIEJAR_H + +#include + +class CookieJar : public QNetworkCookieJar { + public: + explicit CookieJar(QObject* parent = nullptr); + + QList extractCookiesFromUrl(const QString& url) const; + bool insertCookies(const QList& cookies); +}; + +#endif // COOKIEJAR_H diff --git a/src/librssguard/network-web/downloader.cpp b/src/librssguard/network-web/downloader.cpp index 0a1269fd5..1bcf77255 100644 --- a/src/librssguard/network-web/downloader.cpp +++ b/src/librssguard/network-web/downloader.cpp @@ -2,10 +2,14 @@ #include "network-web/downloader.h" +#include "miscellaneous/application.h" #include "miscellaneous/iofactory.h" +#include "network-web/cookiejar.h" #include "network-web/silentnetworkaccessmanager.h" +#include "network-web/webfactory.h" #include +#include #include #include @@ -17,6 +21,9 @@ Downloader::Downloader(QObject* parent) m_timer->setInterval(DOWNLOAD_TIMEOUT); m_timer->setSingleShot(true); connect(m_timer, &QTimer::timeout, this, &Downloader::cancel); + + m_downloadManager->setCookieJar(qApp->web()->cookieJar()); + qApp->web()->cookieJar()->setParent(nullptr); } Downloader::~Downloader() { @@ -53,6 +60,13 @@ void Downloader::manipulateData(const QString& url, bool protected_contents, const QString& username, const QString& password) { + + auto cookies = qApp->web()->cookieJar()->extractCookiesFromUrl(url); + + if (!cookies.isEmpty()) { + qApp->web()->cookieJar()->setCookiesFromUrl(cookies, url); + } + QNetworkRequest request; QString non_const_url = url; QHashIterator i(m_customHeaders); diff --git a/src/librssguard/network-web/webfactory.cpp b/src/librssguard/network-web/webfactory.cpp index 0ebee1f77..9b8e70365 100644 --- a/src/librssguard/network-web/webfactory.cpp +++ b/src/librssguard/network-web/webfactory.cpp @@ -5,6 +5,7 @@ #include "gui/messagebox.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" +#include "network-web/cookiejar.h" #include #include @@ -31,6 +32,8 @@ WebFactory::WebFactory(QObject* parent) m_urlInterceptor = new NetworkUrlInterceptor(this); #endif + m_cookieJar = new CookieJar(nullptr); + #if defined(USE_WEBENGINE) #if QT_VERSION >= 0x050D00 // Qt >= 5.13.0 QWebEngineProfile::defaultProfile()->setUrlRequestInterceptor(m_urlInterceptor); @@ -46,6 +49,10 @@ WebFactory::~WebFactory() { m_engineSettings->menu()->deleteLater(); } #endif + + if (m_cookieJar != nullptr) { + m_cookieJar->deleteLater(); + } } bool WebFactory::sendMessageViaEmail(const Message& message) { @@ -223,14 +230,18 @@ void WebFactory::updateProxy() { } #if defined(USE_WEBENGINE) -AdBlockManager* WebFactory::adBlock() { +AdBlockManager* WebFactory::adBlock() const { return m_adBlock; } -NetworkUrlInterceptor* WebFactory::urlIinterceptor() { +NetworkUrlInterceptor* WebFactory::urlIinterceptor() const { return m_urlInterceptor; } +CookieJar* WebFactory::cookieJar() const { + return m_cookieJar; +} + QAction* WebFactory::engineSettingsAction() { if (m_engineSettings == nullptr) { m_engineSettings = new QAction(qApp->icons()->fromTheme(QSL("applications-internet")), tr("Web engine settings"), this); diff --git a/src/librssguard/network-web/webfactory.h b/src/librssguard/network-web/webfactory.h index a0eaae396..53c6388d1 100644 --- a/src/librssguard/network-web/webfactory.h +++ b/src/librssguard/network-web/webfactory.h @@ -19,6 +19,8 @@ class AdBlockManager; class NetworkUrlInterceptor; #endif +class CookieJar; + class WebFactory : public QObject { Q_OBJECT @@ -37,10 +39,12 @@ class WebFactory : public QObject { #if defined(USE_WEBENGINE) QAction* engineSettingsAction(); - AdBlockManager* adBlock(); - NetworkUrlInterceptor* urlIinterceptor(); + AdBlockManager* adBlock() const; + NetworkUrlInterceptor* urlIinterceptor() const; #endif + CookieJar* cookieJar() const; + void updateProxy(); bool openUrlInExternalBrowser(const QString& url) const; bool sendMessageViaEmail(const Message& message); @@ -64,6 +68,7 @@ class WebFactory : public QObject { QAction* m_engineSettings; #endif + CookieJar* m_cookieJar; QMap m_htmlNamedEntities; }; diff --git a/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp b/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp index b07fb725e..f4aa83869 100644 --- a/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp +++ b/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp @@ -7,15 +7,19 @@ #include "gui/messagebox.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" +#include "network-web/cookiejar.h" #include "network-web/networkfactory.h" +#include "network-web/webfactory.h" #include "services/abstract/category.h" #include "services/abstract/gui/authenticationdetails.h" #include "services/abstract/serviceroot.h" +#include "services/standard/definitions.h" #include "services/standard/gui/standardfeeddetails.h" #include "services/standard/standardfeed.h" #include "services/standard/standardserviceroot.h" #include +#include #include FormStandardFeedDetails::FormStandardFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select, @@ -85,6 +89,20 @@ void FormStandardFeedDetails::apply() { try { DatabaseQueries::createOverwriteFeed(database, std_feed, m_serviceRoot->accountId(), parent->id()); + + // Feed is added, save cookies. + + /*if (std_feed->sourceType() == StandardFeed::SourceType::Url) { + auto cookies = qApp->web()->cookieJar()->extractCookiesFromUrl(std_feed->source()); + + if (!cookies.isEmpty()) { + qDebugNN << LOGSEC_NETWORK + << "Detected some cookies in URL" + << QUOTE_W_SPACE_DOT(std_feed->source()); + + qApp->web()->cookieJar()->insertCookies(cookies); + } + }*/ } catch (const ApplicationException& ex) { qFatal("Cannot save feed: '%s'.", qPrintable(ex.message())); diff --git a/src/librssguard/services/standard/standardfeed.cpp b/src/librssguard/services/standard/standardfeed.cpp index 00a4a53dc..816214101 100644 --- a/src/librssguard/services/standard/standardfeed.cpp +++ b/src/librssguard/services/standard/standardfeed.cpp @@ -2,6 +2,7 @@ #include "services/standard/standardfeed.h" +#include "3rd-party/sc/simplecrypt.h" #include "core/feedsmodel.h" #include "database/databasequeries.h" #include "definitions/definitions.h" @@ -13,7 +14,6 @@ #include "gui/feedsview.h" #include "miscellaneous/iconfactory.h" #include "miscellaneous/settings.h" -#include "3rd-party/sc/simplecrypt.h" #include "miscellaneous/textfactory.h" #include "network-web/networkfactory.h" #include "services/abstract/recyclebin.h"