aboutsummaryrefslogtreecommitdiff
path: root/src/webengine
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2020-04-25 22:09:13 +0300
committerAqua-sama <aqua@iserlohn-fortress.net>2020-05-26 12:50:15 +0300
commit0492a063806b6d63e4f378908b809de104a24820 (patch)
tree2e285d0c9b5067dc9395bfb751fe84bb8ac2a5f4 /src/webengine
parentlibwebengine (diff)
downloadsmolbote-0492a063806b6d63e4f378908b809de104a24820.tar.xz
Update ProfileEditor plugin
ProfileEditor: - add tests - disable read-only settings on otr profiles Add WebProfile::setHeaders and WebProfile::setCookies
Diffstat (limited to 'src/webengine')
-rw-r--r--src/webengine/meson.build2
-rw-r--r--src/webengine/test/profile.cpp145
-rw-r--r--src/webengine/webprofile.cpp18
-rw-r--r--src/webengine/webprofile.h62
-rw-r--r--src/webengine/webprofilemanager.cpp4
-rw-r--r--src/webengine/webprofilemanager.h2
6 files changed, 143 insertions, 90 deletions
diff --git a/src/webengine/meson.build b/src/webengine/meson.build
index db7bdc5..47e4adf 100644
--- a/src/webengine/meson.build
+++ b/src/webengine/meson.build
@@ -5,7 +5,7 @@ webengine_moc = mod_qt5.preprocess(
dep_webengine = declare_dependency(
include_directories: [ '.', smolbote_include ],
- link_with: static_library('webengine', dependencies: dep_qt5,
+ link_with: static_library('webengine', dependencies: [ dep_qt5, dep_spdlog ],
include_directories: smolbote_include,
sources: [ 'webprofile.cpp', 'urlinterceptor.cpp', 'webprofilemanager.cpp', 'webpage.cpp', 'webview.cpp', 'webviewcontextmenu.cpp', webengine_moc ])
)
diff --git a/src/webengine/test/profile.cpp b/src/webengine/test/profile.cpp
index 7351f66..ae3a4e3 100644
--- a/src/webengine/test/profile.cpp
+++ b/src/webengine/test/profile.cpp
@@ -22,98 +22,99 @@ TEST_CASE("loading profile settings")
delete settings;
}
-SCENARIO("loading individual profiles")
+SCENARIO("profile properties")
{
- GIVEN("no profile preset")
- {
- const QString search = GENERATE(as<QString>{}, "https://search.url/t=%1", "https://duckduckgo.com/?q=%1&ia=web", "aaabbbccc");
- const QUrl homepage = GENERATE(as<QUrl>{}, "https://homepage.net", "about:blank", "aaabbbccc");
- const QUrl newtab = GENERATE(as<QUrl>{}, "https://newtab.net", "about:blank", "aaabbbccc");
+ const QString search{ "about:blank" };
+ const QUrl homepage{ "about:blank" };
+ const QUrl newtab{ "about:blank" };
+ const QString id{ "id" };
+
+ REQUIRE(qEnvironmentVariableIsSet("PROFILE"));
- const QString id{ "id" };
- auto *settings = WebProfile::load(QString(), search, homepage, newtab);
- auto *profile = WebProfile::load(id, settings, true);
+ // create an empty settings object
+ const QString settings_path = GENERATE(as<QString>{}, QString(), qgetenv("PROFILE"));
+ auto *settings = WebProfile::load(settings_path, search, homepage, newtab);
+ // create the actual profile
+ auto *profile = WebProfile::load(id, settings, true);
- REQUIRE(profile != nullptr);
+ REQUIRE(profile != nullptr);
+ REQUIRE(profile->isOffTheRecord());
+
+ WHEN("id constant")
+ {
REQUIRE(profile->getId() == id);
REQUIRE(profile->property("id").toString() == id);
- REQUIRE(profile->name() == id);
- REQUIRE(profile->search() == search);
- REQUIRE(profile->homepage() == homepage);
- REQUIRE(profile->newtab() == newtab);
-
- REQUIRE(profile->isOffTheRecord());
- delete settings;
- delete profile;
}
- GIVEN("an off-the-record profile preset")
+ WHEN("changing profile name")
{
- REQUIRE(qEnvironmentVariableIsSet("PROFILE"));
-
- const QString id{ "id" };
- auto *settings = WebProfile::load(qgetenv("PROFILE"), QString(), QUrl(), QUrl());
- auto *profile = WebProfile::load(id, settings, true);
-
- REQUIRE(profile != nullptr);
- REQUIRE(profile->getId() == id);
- REQUIRE(profile->isOffTheRecord());
-
- WHEN("created")
+ const QString name = GENERATE(as<QString>{}, "a", "bb", "ccc");
+ profile->setName(name);
+ THEN("the name changes")
{
- THEN("uses default values")
- {
- REQUIRE(profile->name() == "Test Profile");
- REQUIRE(profile->search() == "https://duckduckgo.com/?q=%1&ia=web");
- REQUIRE(profile->homepage() == QUrl("about:blank"));
- REQUIRE(profile->newtab() == QUrl("about:blank"));
- }
+ REQUIRE(profile->name() == name);
+ REQUIRE(settings->value("name").toString() == name);
}
-
- WHEN("changing profile name")
+ }
+ WHEN("changing search")
+ {
+ const QString search = GENERATE(as<QString>{}, "a", "bb", "ccc");
+ profile->setSearch(search);
+ THEN("the search url changes")
{
- const QString name = GENERATE(as<QString>{}, "a", "bb", "ccc");
- profile->setName(name);
- THEN("the name changes")
- {
- REQUIRE(profile->name() == name);
- REQUIRE(settings->value("name").toString() == name);
- }
+ REQUIRE(profile->search() == search);
+ REQUIRE(settings->value("search").toString() == search);
}
- WHEN("changing search url")
+ }
+ WHEN("changing homepage url")
+ {
+ const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
+ profile->setHomepage(url);
+ THEN("homepage changes")
{
- const QString search = GENERATE(as<QString>{}, "a", "bb", "ccc");
- profile->setSearch(search);
- THEN("the search url changes")
- {
- REQUIRE(profile->search() == search);
- REQUIRE(settings->value("search").toString() == search);
- }
+ REQUIRE(profile->homepage() == url);
+ REQUIRE(settings->value("homepage").toUrl() == url);
}
- WHEN("changing homepage")
+ }
+ WHEN("changing newtab url")
+ {
+ const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
+ profile->setNewtab(url);
+ THEN("newtab changes")
{
- const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
- profile->setHomepage(url);
- THEN("homepage changes")
- {
- REQUIRE(profile->homepage() == url);
- REQUIRE(settings->value("homepage").toUrl() == url);
- }
+ REQUIRE(profile->newtab() == url);
+ REQUIRE(settings->value("newtab").toUrl() == url);
}
- WHEN("changing newtab")
+ }
+
+ WHEN("changing cookies")
+ {
+ auto list = profile->cookies();
+ REQUIRE(list.isEmpty());
+ list.append(QNetworkCookie("name", "value").toRawForm());
+ profile->setCookies(list);
+ THEN("new cookie list gets applied")
{
- const QUrl url = GENERATE(as<QUrl>{}, "a", "bb", "ccc");
- profile->setNewtab(url);
- THEN("newtab changes")
- {
- REQUIRE(profile->newtab() == url);
- REQUIRE(settings->value("newtab").toUrl() == url);
- }
+ // There is no event loop, so the signals cannot fire and update the cookie list
+ //REQUIRE(list == profile->cookies());
}
+ }
- delete settings;
- delete profile;
+ WHEN("changing headers")
+ {
+ QMap<QString, QVariant> headers;
+ headers.insert("Dnt", "1");
+ headers.insert("unknown", "pair");
+
+ profile->setHeaders(headers);
+ THEN("headers change")
+ {
+ REQUIRE(profile->headers() == headers);
+ }
}
+
+ delete settings;
+ delete profile;
}
int main(int argc, char **argv)
diff --git a/src/webengine/webprofile.cpp b/src/webengine/webprofile.cpp
index f0368c9..719ab34 100644
--- a/src/webengine/webprofile.cpp
+++ b/src/webengine/webprofile.cpp
@@ -7,11 +7,12 @@
*/
#include "webprofile.h"
+#include "urlinterceptor.h"
#include <QFileInfo>
#include <QSettings>
#include <QWebEngineCookieStore>
#include <QWebEngineSettings>
-#include "urlinterceptor.h"
+#include <spdlog/spdlog.h>
static WebProfile *s_profile = nullptr;
@@ -47,7 +48,7 @@ WebProfile *WebProfile::load(const QString &id, QSettings *settings, bool isOffT
{
WebProfile *profile = nullptr;
- if(isOffTheRecord || settings->value("otr", isOffTheRecord).toBool()) {
+ if(settings->value("otr", isOffTheRecord).toBool()) {
profile = new WebProfile(id, nullptr);
} else {
profile = new WebProfile(id, id, nullptr);
@@ -89,7 +90,8 @@ WebProfile *WebProfile::load(const QString &id, QSettings *settings, bool isOffT
{
// headers
settings->beginGroup("headers");
- for(const QString &key : settings->childKeys()) {
+ const auto keys = settings->childKeys();
+ for(const QString &key : keys) {
profile->setHttpHeader(key.toLatin1(), settings->value(key).toString().toLatin1());
}
settings->endGroup();
@@ -110,11 +112,14 @@ WebProfile::WebProfile(const QString &id, QObject *parent)
{
QWebEngineProfile::setUrlRequestInterceptor(new UrlRequestInterceptor(this));
connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) {
+ spdlog::debug("[{}]: +cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
m_cookies.append(cookie);
});
connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) {
- m_cookies.removeAll(cookie);
+ spdlog::debug("[{}]: -cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
+ m_cookies.removeOne(cookie);
});
+ cookieStore()->loadAllCookies();
}
// default constructor
@@ -124,9 +129,12 @@ WebProfile::WebProfile(const QString &id, const QString &storageName, QObject *p
{
QWebEngineProfile::setUrlRequestInterceptor(new UrlRequestInterceptor(this));
connect(this->cookieStore(), &QWebEngineCookieStore::cookieAdded, this, [this](const QNetworkCookie &cookie) {
+ spdlog::debug("[{}]: +cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
m_cookies.append(cookie);
});
connect(this->cookieStore(), &QWebEngineCookieStore::cookieRemoved, this, [this](const QNetworkCookie &cookie) {
- m_cookies.removeAll(cookie);
+ spdlog::debug("[{}]: -cookie {}", qUtf8Printable(m_name), qUtf8Printable(cookie.name()));
+ m_cookies.removeOne(cookie);
});
+ cookieStore()->loadAllCookies();
}
diff --git a/src/webengine/webprofile.h b/src/webengine/webprofile.h
index 180cc9d..0747638 100644
--- a/src/webengine/webprofile.h
+++ b/src/webengine/webprofile.h
@@ -11,13 +11,14 @@
#include <QMap>
#include <QNetworkCookie>
+#include <QSettings>
#include <QString>
#include <QUrl>
+#include <QVariant>
#include <QVector>
+#include <QWebEngineCookieStore>
#include <QWebEngineProfile>
#include <QWebEngineSettings>
-#include <QVariant>
-#include <QSettings>
class UrlRequestInterceptor;
class WebProfile : public QWebEngineProfile
@@ -44,6 +45,10 @@ class WebProfile : public QWebEngineProfile
Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY propertyChanged)
+ // more custom properties
+ Q_PROPERTY(QList<QVariant> cookies READ cookies WRITE setCookies NOTIFY cookiesChanged)
+ Q_PROPERTY(QMap<QString, QVariant> headers READ headers WRITE setHeaders NOTIFY headersChanged)
+
signals:
void nameChanged(const QString &name);
void searchChanged(const QString &url);
@@ -52,6 +57,9 @@ signals:
void propertyChanged(const QString &name, const QVariant &value);
void attributeChanged(QWebEngineSettings::WebAttribute attribute, bool value);
+
+ void cookiesChanged();
+ void headersChanged();
void headerChanged(const QString &name, const QString &value);
void headerRemoved(const QString &name);
@@ -60,9 +68,9 @@ public:
[[nodiscard]] static WebProfile *load(const QString &id, QSettings *settings, bool isOffTheRecord = true);
WebProfile(const WebProfile &) = delete;
- WebProfile& operator=(const WebProfile &) = delete;
+ WebProfile &operator=(const WebProfile &) = delete;
WebProfile(WebProfile &&) = delete;
- WebProfile& operator=(WebProfile &&) = delete;
+ WebProfile &operator=(WebProfile &&) = delete;
static WebProfile *defaultProfile();
static void setDefaultProfile(WebProfile *profile);
@@ -83,9 +91,13 @@ public:
emit nameChanged(name);
}
- [[nodiscard]] QVector<QNetworkCookie> cookies() const
+ [[nodiscard]] QList<QVariant> cookies() const
{
- return qAsConst(m_cookies);
+ QList<QVariant> r;
+ for(const auto &cookie : m_cookies) {
+ r.append(cookie.toRawForm());
+ }
+ return r;
}
[[nodiscard]] QString search() const
@@ -166,7 +178,16 @@ public:
emit headerRemoved(name);
}
}
-
+ [[nodiscard]] QMap<QString, QVariant> headers() const
+ {
+ QMap<QString, QVariant> r;
+ auto it = m_headers.constBegin();
+ while(it != m_headers.constEnd()) {
+ r.insert(QString(it.key()), QVariant(it.value()));
+ ++it;
+ }
+ return r;
+ }
void setSpellCheckEnabled(bool enable)
{
QWebEngineProfile::setSpellCheckEnabled(enable);
@@ -178,6 +199,29 @@ public:
m_filters.append(interceptor);
}
+public slots:
+ void setCookies(const QList<QVariant> &cookies)
+ {
+ auto *store = cookieStore();
+ store->deleteAllCookies();
+ for(const auto &data : cookies) {
+ for(const auto &cookie : QNetworkCookie::parseCookies(data.toByteArray())) {
+ store->setCookie(cookie);
+ }
+ }
+ emit cookiesChanged();
+ }
+ void setHeaders(const QMap<QString, QVariant> &headers)
+ {
+ m_headers.clear();
+ auto it = headers.constBegin();
+ while(it != headers.constEnd()) {
+ m_headers.insert(it.key().toLatin1(), it.value().toByteArray());
+ ++it;
+ }
+ emit headersChanged();
+ }
+
protected:
// off-the-record constructor
explicit WebProfile(const QString &id, QObject *parent = nullptr);
@@ -190,8 +234,8 @@ protected:
QUrl m_homepage = QUrl("about:blank");
QUrl m_newtab = QUrl("about:blank");
- QVector<QWebEngineUrlRequestInterceptor*> m_filters;
- QVector<QNetworkCookie> m_cookies;
+ QVector<QWebEngineUrlRequestInterceptor *> m_filters;
+ QList<QNetworkCookie> m_cookies;
QMap<QByteArray, QByteArray> m_headers;
};
diff --git a/src/webengine/webprofilemanager.cpp b/src/webengine/webprofilemanager.cpp
index 785251b..5cc83f8 100644
--- a/src/webengine/webprofilemanager.cpp
+++ b/src/webengine/webprofilemanager.cpp
@@ -56,7 +56,7 @@ QStringList WebProfileManager<true>::idList() const
}
template <>
-void WebProfileManager<false>::walk(std::function<void(const QString &id, WebProfile *profile, const QSettings *settings)> f) const
+void WebProfileManager<false>::walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)> f) const
{
for(auto iter = profiles.begin(); iter != profiles.end(); ++iter) {
f(iter.key(), iter.value().ptr, iter.value().settings);
@@ -64,7 +64,7 @@ void WebProfileManager<false>::walk(std::function<void(const QString &id, WebPro
}
template <>
-void WebProfileManager<true>::walk(std::function<void(const QString &id, WebProfile *profile, const QSettings *settings)> f) const
+void WebProfileManager<true>::walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)> f) const
{
s_instance->walk(f);
}
diff --git a/src/webengine/webprofilemanager.h b/src/webengine/webprofilemanager.h
index 22fb31c..91dcaf8 100644
--- a/src/webengine/webprofilemanager.h
+++ b/src/webengine/webprofilemanager.h
@@ -93,7 +93,7 @@ public:
return profiles.keys();
}
- callable_when(unconsumed) void walk(std::function<void(const QString &id, WebProfile *profile, const QSettings *settings)>) const;
+ callable_when(unconsumed) void walk(std::function<void(const QString &id, WebProfile *profile, QSettings *settings)>) const;
callable_when(unconsumed) void make_global();