[epiphany/wip/tingping/profile-migration: 50/58] Store web extension settings in a keyfile
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/tingping/profile-migration: 50/58] Store web extension settings in a keyfile
- Date: Sun, 6 Jan 2019 18:31:56 +0000 (UTC)
commit 4201fa00f8a786fdd8a5e5bc76e4b1c465ffd464
Author: Patrick Griffis <pgriffis igalia com>
Date: Mon Dec 17 09:08:07 2018 -0500
Store web extension settings in a keyfile
When the WebKitGTK sandbox is enabled the web processes
will not have access to DConf so these will not work.
They do however have read access to our private directories
so we can simply write a keyfile there and load them from the
web extensions.
The keyfile is simply kept in sync with the host DConf so all
previous usage continues to work as expected.
embed/web-extension/ephy-uri-tester.c | 6 +-
embed/web-extension/ephy-web-extension.c | 6 +-
lib/ephy-settings.c | 111 +++++++++++++++++++++++++++++++
lib/ephy-settings.h | 19 +++---
4 files changed, 128 insertions(+), 14 deletions(-)
---
diff --git a/embed/web-extension/ephy-uri-tester.c b/embed/web-extension/ephy-uri-tester.c
index 5158dcb3a..76ea56f60 100644
--- a/embed/web-extension/ephy-uri-tester.c
+++ b/embed/web-extension/ephy-uri-tester.c
@@ -634,7 +634,7 @@ ephy_uri_tester_begin_loading_adblock_filters (EphyUriTester *tester,
{
char **filters;
- filters = g_settings_get_strv (EPHY_SETTINGS_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
+ filters = g_settings_get_strv (EPHY_SETTINGS_WEB_EXTENSION_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
tester->adblock_filters_to_load = g_strv_length (filters);
for (guint i = 0; filters[i]; i++) {
GFile *filter_file;
@@ -852,7 +852,7 @@ ephy_uri_tester_load (EphyUriTester *tester)
g_assert (EPHY_IS_URI_TESTER (tester));
- if (!g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
+ if (!g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
tester->adblock_loaded = TRUE;
if (tester->adblock_loaded)
@@ -871,6 +871,6 @@ ephy_uri_tester_load (EphyUriTester *tester)
G_CALLBACK (ephy_uri_tester_enable_adblock_changed_cb), tester);
/* GSettings never emits the changed signal until after we read the setting
* the first time after connecting the handler... work around this.*/
- trash = g_settings_get_strv (EPHY_SETTINGS_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
+ trash = g_settings_get_strv (EPHY_SETTINGS_WEB_EXTENSION_MAIN, EPHY_PREFS_ADBLOCK_FILTERS);
g_strfreev (trash);
}
diff --git a/embed/web-extension/ephy-web-extension.c b/embed/web-extension/ephy-web-extension.c
index b49559309..0da9815b5 100644
--- a/embed/web-extension/ephy-web-extension.c
+++ b/embed/web-extension/ephy-web-extension.c
@@ -103,7 +103,7 @@ should_use_adblocker (const char *request_uri,
const char *page_uri,
const char *redirected_request_uri)
{
- if (!g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
+ if (!g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
return FALSE;
/* Always load the main resource... */
@@ -150,7 +150,7 @@ web_page_send_request (WebKitWebPage *web_page,
page_uri = webkit_web_page_get_uri (web_page);
redirected_response_uri = redirected_response ? webkit_uri_response_get_uri (redirected_response) : NULL;
- if (g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
+ if (g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
SoupMessageHeaders *headers = webkit_uri_request_get_http_headers (request);
if (headers) {
/* Do Not Track header. '1' means 'opt-out'. See:
@@ -275,7 +275,7 @@ web_page_form_controls_associated (WebKitWebPage *web_page,
G_TYPE_STRING, 2,
G_TYPE_UINT64, G_TYPE_BOOLEAN);
remember_passwords = !extension->is_private_profile &&
- g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
+ g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB,
EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
js_result = jsc_value_object_invoke_method (js_ephy,
"formControlsAssociated",
G_TYPE_UINT64, webkit_web_page_get_id (web_page),
diff --git a/lib/ephy-settings.c b/lib/ephy-settings.c
index 8c415a607..82f172efa 100644
--- a/lib/ephy-settings.c
+++ b/lib/ephy-settings.c
@@ -28,6 +28,9 @@
#include <glib.h>
#include <gio/gio.h>
+#define G_SETTINGS_ENABLE_BACKEND
+#include <gio/gsettingsbackend.h>
+
static GHashTable *settings = NULL;
static void
@@ -98,4 +101,112 @@ ephy_settings_get (const char *schema)
return gsettings;
}
+static void
+on_settings_changed (GSettings *settings,
+ char *key,
+ gpointer user_data)
+{
+ g_autoptr(GVariant) value = g_settings_get_user_value (settings, key);
+ if (value != NULL)
+ g_settings_set_value (user_data, key, value);
+ else
+ g_settings_reset (user_data, key);
+}
+
+/*
+ * This is to sync a host dconf settings schema with a keyfile based schema.
+ * The reason this is done is to continue supporting dconf usage on the host
+ * transparently.
+ */
+static void
+sync_settings (GSettings *original,
+ GSettings *new)
+{
+ g_autoptr(GSettingsSchema) schema = NULL;
+ g_auto(GStrv) keys = NULL;
+
+ g_object_get (original, "settings-schema", &schema, NULL);
+ keys = g_settings_schema_list_keys (schema);
+
+ for (size_t i = 0; keys[i] != NULL; ++i) {
+ const char *key = keys[i];
+ g_autoptr(GVariant) value = g_settings_get_user_value (original, key);
+
+ if (value != NULL)
+ g_settings_set_value (new, key, value);
+ }
+
+ g_signal_connect_object (original, "changed", G_CALLBACK (on_settings_changed), new, 0);
+}
+
+static char *
+get_relocatable_path (const char *schema)
+{
+ for (size_t i = 0; i < G_N_ELEMENTS (ephy_prefs_relocatable_schemas); i++) {
+ if (g_strcmp0 (ephy_prefs_relocatable_schemas[i].schema, schema) == 0)
+ return g_build_path ("/", "/org/gnome/epiphany/", ephy_prefs_relocatable_schemas[i].path, NULL);
+ }
+ return NULL;
+}
+
+/**
+ * ephy_settings_get_for_web_extension:
+ *
+ * Equivalent to ephy_settings_get() except it ensures that the
+ * settings backend is always keyfile based instead of using DConf.
+ *
+ * This is required because the WebKitGTK sandbox will not grant
+ * access to DConf but we do have access to our local directories.
+ *
+ * It is also assumed this will only be used as read-only.
+ *
+ * Returns: (transfer none): #GSettings
+ */
+GSettings *
+ephy_settings_get_for_web_extension (const char *schema)
+{
+ GSettings *gsettings = NULL;
+ g_autofree char *key_name = NULL;
+
+ ephy_settings_init ();
+
+ // Web apps can't work with the sandbox anyway
+ const char *web_app_name = strstr (ephy_dot_dir (), EPHY_WEB_APP_PREFIX);
+ if (web_app_name != NULL)
+ return ephy_settings_get (schema);
+
+ key_name = g_strdup_printf ("keyfile-%s", schema);
+ gsettings = g_hash_table_lookup (settings, key_name);
+
+ if (gsettings == NULL) {
+ g_autoptr(GSettingsBackend) backend = NULL;
+ gsettings = ephy_settings_get (schema);
+ g_assert (gsettings != NULL);
+
+ // GLib inside Flatpak will default to this backend in the future
+ // so we don't need to do anything extra
+ g_object_get (gsettings, "backend", &backend, NULL);
+ // G_IS_KEYFILE_SETTINGS_BACKEND () is private API
+ if (!g_strcmp0 (g_type_name (G_TYPE_FROM_INSTANCE (backend)), "GKeyfileSettingsBackend")) {
+ g_hash_table_insert (settings, g_steal_pointer (&key_name), g_object_ref (gsettings));
+ return gsettings;
+ }
+
+ g_autofree char *keyfile_path = g_build_filename (ephy_dot_dir (), "web-extension-settings.ini", NULL);
+ backend = g_keyfile_settings_backend_new (keyfile_path, "/", "/");
+
+ GSettings *web_gsettings;
+ g_autofree char *path = get_relocatable_path (schema);
+ if (path != NULL)
+ web_gsettings = g_settings_new_with_backend_and_path (schema, backend, path);
+ else
+ web_gsettings = g_settings_new_with_backend (schema, backend);
+
+ sync_settings (gsettings, web_gsettings);
+ g_hash_table_insert (settings, g_steal_pointer (&key_name), web_gsettings);
+
+ return web_gsettings;
+ }
+ return gsettings;
+}
diff --git a/lib/ephy-settings.h b/lib/ephy-settings.h
index 48ed7fcc2..5c95f70d2 100644
--- a/lib/ephy-settings.h
+++ b/lib/ephy-settings.h
@@ -27,16 +27,19 @@
G_BEGIN_DECLS
-#define EPHY_SETTINGS_MAIN ephy_settings_get (EPHY_PREFS_SCHEMA)
-#define EPHY_SETTINGS_UI ephy_settings_get (EPHY_PREFS_UI_SCHEMA)
-#define EPHY_SETTINGS_WEB ephy_settings_get (EPHY_PREFS_WEB_SCHEMA)
-#define EPHY_SETTINGS_LOCKDOWN ephy_settings_get (EPHY_PREFS_LOCKDOWN_SCHEMA)
-#define EPHY_SETTINGS_STATE ephy_settings_get (EPHY_PREFS_STATE_SCHEMA)
-#define EPHY_SETTINGS_SYNC ephy_settings_get (EPHY_PREFS_SYNC_SCHEMA)
-#define EPHY_SETTINGS_WEB_APP ephy_settings_get (EPHY_PREFS_WEB_APP_SCHEMA)
-#define EPHY_SETTINGS_READER ephy_settings_get (EPHY_PREFS_READER_SCHEMA)
+#define EPHY_SETTINGS_MAIN ephy_settings_get (EPHY_PREFS_SCHEMA)
+#define EPHY_SETTINGS_UI ephy_settings_get (EPHY_PREFS_UI_SCHEMA)
+#define EPHY_SETTINGS_WEB ephy_settings_get (EPHY_PREFS_WEB_SCHEMA)
+#define EPHY_SETTINGS_LOCKDOWN ephy_settings_get (EPHY_PREFS_LOCKDOWN_SCHEMA)
+#define EPHY_SETTINGS_STATE ephy_settings_get (EPHY_PREFS_STATE_SCHEMA)
+#define EPHY_SETTINGS_SYNC ephy_settings_get (EPHY_PREFS_SYNC_SCHEMA)
+#define EPHY_SETTINGS_WEB_APP ephy_settings_get (EPHY_PREFS_WEB_APP_SCHEMA)
+#define EPHY_SETTINGS_READER ephy_settings_get (EPHY_PREFS_READER_SCHEMA)
+#define EPHY_SETTINGS_WEB_EXTENSION_MAIN ephy_settings_get_for_web_extension (EPHY_PREFS_SCHEMA)
+#define EPHY_SETTINGS_WEB_EXTENSION_WEB ephy_settings_get_for_web_extension (EPHY_PREFS_WEB_SCHEMA)
GSettings *ephy_settings_get (const char *schema);
+GSettings *ephy_settings_get_for_web_extension (const char *schema);
void ephy_settings_shutdown (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]