[epiphany/wip/security-origins: 6/8] permissions-manager: operate on security origins, not hosts
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [epiphany/wip/security-origins: 6/8] permissions-manager: operate on security origins, not hosts
- Date: Fri, 30 Dec 2016 17:19:16 +0000 (UTC)
commit 946a6005e084d674a2ef38c6dd1598eb6e591d41
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Thu Dec 29 16:34:43 2016 -0600
permissions-manager: operate on security origins, not hosts
data/Makefile.am | 2 +-
... => org.gnome.epiphany.permissions.gschema.xml} | 14 ++--
embed/ephy-web-view.c | 30 +++++---
embed/web-extension/ephy-web-extension.c | 14 +++-
lib/ephy-permissions-manager.c | 78 ++++++++++++--------
lib/ephy-permissions-manager.h | 18 ++--
src/profile-migrator/ephy-profile-migrator.c | 15 ++++
7 files changed, 106 insertions(+), 65 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index d6aa63e..77c4753 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -10,7 +10,7 @@ $(desktop_DATA): $(desktop_in_files)
gsettings_ENUM_NAMESPACE = org.gnome.Epiphany
gsettings_ENUM_FILES = $(top_srcdir)/lib/ephy-prefs.h
-gsettings_SCHEMAS = org.gnome.epiphany.gschema.xml org.gnome.epiphany.host.gschema.xml
+gsettings_SCHEMAS = org.gnome.epiphany.gschema.xml org.gnome.epiphany.permissions.gschema.xml
@GSETTINGS_RULES@
appstream_in_files = org.gnome.Epiphany.appdata.xml.in
diff --git a/data/org.gnome.epiphany.host.gschema.xml b/data/org.gnome.epiphany.permissions.gschema.xml
similarity index 91%
rename from data/org.gnome.epiphany.host.gschema.xml
rename to data/org.gnome.epiphany.permissions.gschema.xml
index 2d5a153..22bbdd2 100644
--- a/data/org.gnome.epiphany.host.gschema.xml
+++ b/data/org.gnome.epiphany.permissions.gschema.xml
@@ -1,32 +1,32 @@
<schemalist>
- <enum id="org.gnome.Epiphany.host.permissions">
+ <enum id="org.gnome.Epiphany.Permissions.Permission">
<value nick="undecided" value="-1"/>
<value nick="deny" value="0"/>
<value nick="allow" value="1"/>
</enum>
- <schema id="org.gnome.Epiphany.host" gettext-domain="">
- <key name="audio-device-permission" enum="org.gnome.Epiphany.host.permissions">
+ <schema id="org.gnome.Epiphany.Permissions" gettext-domain="">
+ <key name="audio-device-permission" enum="org.gnome.Epiphany.Permissions.Permission">
<default>"undecided"</default>
<summary>Decision to apply when microphone permission is requested for this host</summary>
<description>This option is used to save whether a given host has been given permission to access the
user’s microphone. The “undecided” default means the browser needs to ask the user for permission, while
“allow” and “deny” tell it to automatically make the decision upon request.</description>
</key>
- <key name="geolocation-permission" enum="org.gnome.Epiphany.host.permissions">
+ <key name="geolocation-permission" enum="org.gnome.Epiphany.Permissions.Permission">
<default>"undecided"</default>
<summary>Decision to apply when geolocation permission is requested for this host</summary>
<description>This option is used to save whether a given host has been given permission to access the
user’s location. The “undecided” default means the browser needs to ask the user for permission, while
“allow” and “deny” tell it to automatically make the decision upon request.</description>
</key>
- <key name="notifications-permission" enum="org.gnome.Epiphany.host.permissions">
+ <key name="notifications-permission" enum="org.gnome.Epiphany.Permissions.Permission">
<default>"undecided"</default>
<summary>Decision to apply when notification permission is requested for this host</summary>
<description>This option is used to save whether a given host has been given permission to show
notifications. The “undecided” default means the browser needs to ask the user for permission, while “allow”
and “deny” tell it to automatically make the decision upon request.</description>
</key>
- <key name="save-password-permission" enum="org.gnome.Epiphany.host.permissions">
+ <key name="save-password-permission" enum="org.gnome.Epiphany.Permissions.Permission">
<default>"undecided"</default>
<summary>Decision to apply when save password permission is requested for this host</summary>
<description>This option is used to save whether a given host has been given permission to save
passwords. The “undecided” default means the browser needs to ask the user for permission, while “allow” and
“deny” tell it to automatically make the decision upon request.</description>
</key>
- <key name="video-device-permission" enum="org.gnome.Epiphany.host.permissions">
+ <key name="video-device-permission" enum="org.gnome.Epiphany.Permissions.Permission">
<default>"undecided"</default>
<summary>Decision to apply when webcam permission is requested for this host</summary>
<description>This option is used to save whether a given host has been given permission to access the
user’s webcam. The “undecided” default means the browser needs to ask the user for permission, while “allow”
and “deny” tell it to automatically make the decision upon request.</description>
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index bbe6492..f379d31 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -703,10 +703,10 @@ form_auth_data_save_confirmation_response (GtkInfoBar *info_bar,
EphyEmbedShell *shell = ephy_embed_shell_get_default ();
EphyPermissionsManager *manager = ephy_embed_shell_get_permissions_manager (shell);
- ephy_permissions_manager_set_permission_for_address (manager,
- EPHY_PERMISSION_TYPE_SAVE_PASSWORD,
- data->origin,
- EPHY_PERMISSION_DENY);
+ ephy_permissions_manager_set_permission (manager,
+ EPHY_PERMISSION_TYPE_SAVE_PASSWORD,
+ data->origin,
+ EPHY_PERMISSION_DENY);
}
g_free (data->origin);
@@ -1317,11 +1317,11 @@ decide_on_permission_request (GtkWidget *info_bar,
shell = ephy_embed_shell_get_default ();
permissions_manager = ephy_embed_shell_get_permissions_manager (shell);
- ephy_permissions_manager_set_permission_for_address (permissions_manager,
- permission_type,
- data->origin,
- response == GTK_RESPONSE_YES ? EPHY_PERMISSION_ALLOW
- :
EPHY_PERMISSION_DENY);
+ ephy_permissions_manager_set_permission (permissions_manager,
+ permission_type,
+ data->origin,
+ response == GTK_RESPONSE_YES ? EPHY_PERMISSION_ALLOW
+ : EPHY_PERMISSION_DENY);
}
gtk_widget_destroy (info_bar);
@@ -1430,6 +1430,7 @@ permission_request_cb (WebKitWebView *web_view,
WebKitPermissionRequest *decision)
{
const char *address;
+ char *origin;
EphyEmbedShell *shell;
EphyPermissionsManager *permissions_manager;
EphyPermission permission;
@@ -1456,10 +1457,15 @@ permission_request_cb (WebKitWebView *web_view,
}
address = ephy_web_view_get_address (EPHY_WEB_VIEW (web_view));
+ origin = ephy_uri_to_security_origin (address);
+ if (origin == NULL)
+ return FALSE;
+
permissions_manager = ephy_embed_shell_get_permissions_manager (ephy_embed_shell_get_default ());
- permission = ephy_permissions_manager_get_permission_for_address (permissions_manager,
- permission_type,
- address);
+ permission = ephy_permissions_manager_get_permission (permissions_manager,
+ permission_type,
+ origin);
+ g_free (origin);
switch (permission) {
case EPHY_PERMISSION_ALLOW:
diff --git a/embed/web-extension/ephy-web-extension.c b/embed/web-extension/ephy-web-extension.c
index b3bb597..ea6d3c2 100644
--- a/embed/web-extension/ephy-web-extension.c
+++ b/embed/web-extension/ephy-web-extension.c
@@ -377,16 +377,20 @@ should_store_cb (const char *username,
EphyPermission permission;
SoupURI *uri;
char *uri_string;
+ char *origin = NULL;
uri = ephy_embed_form_auth_get_uri (form_auth);
uri_string = soup_uri_to_string (uri, FALSE);
- if (!uri_string)
+ if (uri_string == NULL)
return;
+ origin = ephy_uri_to_security_origin (uri_string);
+ if (origin == NULL)
+ goto out;
web_extension = ephy_web_extension_get ();
- permission = ephy_permissions_manager_get_permission_for_address (web_extension->permissions_manager,
- EPHY_PERMISSION_TYPE_SAVE_PASSWORD,
- uri_string);
+ permission = ephy_permissions_manager_get_permission (web_extension->permissions_manager,
+ EPHY_PERMISSION_TYPE_SAVE_PASSWORD,
+ origin);
if (permission == EPHY_PERMISSION_DENY) {
LOG ("User/password storage permission previously denied. Not asking about storing.");
@@ -428,6 +432,8 @@ should_store_cb (const char *username,
}
out:
+ if (origin != NULL)
+ g_free (origin);
g_free (uri_string);
}
diff --git a/lib/ephy-permissions-manager.c b/lib/ephy-permissions-manager.c
index 274d7aa..1f62fe0 100644
--- a/lib/ephy-permissions-manager.c
+++ b/lib/ephy-permissions-manager.c
@@ -27,12 +27,14 @@
#define G_SETTINGS_ENABLE_BACKEND 1
#include <gio/gsettingsbackend.h>
+#include <string.h>
+#include <webkit2/webkit2.h>
struct _EphyPermissionsManager
{
GObject parent_instance;
- GHashTable *hosts_mapping;
+ GHashTable *origins_mapping;
GHashTable *settings_mapping;
};
@@ -41,7 +43,7 @@ G_DEFINE_TYPE (EphyPermissionsManager, ephy_permissions_manager, G_TYPE_OBJECT)
static void
ephy_permissions_manager_init (EphyPermissionsManager *manager)
{
- manager->hosts_mapping = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+ manager->origins_mapping = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
manager->settings_mapping = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
}
@@ -50,7 +52,7 @@ ephy_permissions_manager_dispose (GObject *object)
{
EphyPermissionsManager *manager = EPHY_PERMISSIONS_MANAGER (object);
- g_clear_pointer (&manager->hosts_mapping, g_hash_table_destroy);
+ g_clear_pointer (&manager->origins_mapping, g_hash_table_destroy);
g_clear_pointer (&manager->settings_mapping, g_hash_table_destroy);
G_OBJECT_CLASS (ephy_permissions_manager_parent_class)->dispose (object);
@@ -65,36 +67,48 @@ ephy_permissions_manager_class_init (EphyPermissionsManagerClass *klass)
}
static GSettings *
-ephy_permissions_manager_get_settings_for_address (EphyPermissionsManager *manager,
- const char *address)
+ephy_permissions_manager_get_settings_for_origin (EphyPermissionsManager *manager,
+ const char *origin)
{
- char *host = ephy_string_get_host_name (address);
- char *key_file = NULL;
- char *host_path = NULL;
- GSettingsBackend* backend = NULL;
+ char *key_file;
+ char *origin_path;
+ char *trimmed_protocol;
+ GSettingsBackend* backend;
GSettings *settings;
+ WebKitSecurityOrigin *security_origin;
+ char *pos;
- g_assert (host != NULL);
+ g_assert (origin != NULL);
- settings = g_hash_table_lookup (manager->hosts_mapping, host);
- if (settings) {
- g_free (host);
+ settings = g_hash_table_lookup (manager->origins_mapping, origin);
+ if (settings)
return settings;
- }
- key_file = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "hosts.ini", ephy_dot_dir ());
- backend = g_keyfile_settings_backend_new (key_file, "/", "Hosts");
+ key_file = g_build_filename (ephy_dot_dir (), "permissions.ini", NULL);
+ backend = g_keyfile_settings_backend_new (key_file, "/", NULL);
g_free (key_file);
- host_path = g_strdup_printf ("/org/gnome/epiphany/hosts/%s/", host);
-
- settings = g_settings_new_with_backend_and_path ("org.gnome.Epiphany.host", backend, host_path);
-
- g_free (host_path);
+ /* Cannot contain consecutive slashes in GSettings path... */
+ security_origin = webkit_security_origin_new_from_string (origin);
+ trimmed_protocol = g_strdup (webkit_security_origin_get_protocol (security_origin));
+ pos = strchr (trimmed_protocol, '/');
+ if (pos != NULL)
+ *pos = '\0';
+
+ origin_path = g_strdup_printf ("/org/gnome/epiphany/permissions/%s/%s/%u/",
+ trimmed_protocol,
+ webkit_security_origin_get_host (security_origin),
+ webkit_security_origin_get_port (security_origin));
+
+ settings = g_settings_new_with_backend_and_path ("org.gnome.Epiphany.Permissions", backend, origin_path);
+ g_free (trimmed_protocol);
+ g_free (origin_path);
g_object_unref (backend);
+ webkit_security_origin_unref (security_origin);
- g_hash_table_insert (manager->hosts_mapping, host, settings);
- g_hash_table_insert (manager->settings_mapping, settings, host);
+ /* Note that settings is owned only by the first hash table! */
+ g_hash_table_insert (manager->origins_mapping, g_strdup (origin), settings);
+ g_hash_table_insert (manager->settings_mapping, settings, g_strdup (origin));
return settings;
}
@@ -125,20 +139,20 @@ permission_type_to_string (EphyPermissionType type)
}
EphyPermission
-ephy_permissions_manager_get_permission_for_address (EphyPermissionsManager *manager,
- EphyPermissionType type,
- const char *address)
+ephy_permissions_manager_get_permission (EphyPermissionsManager *manager,
+ EphyPermissionType type,
+ const char *origin)
{
- GSettings *settings = ephy_permissions_manager_get_settings_for_address (manager, address);
+ GSettings *settings = ephy_permissions_manager_get_settings_for_origin (manager, origin);
return g_settings_get_enum (settings, permission_type_to_string (type));
}
void
-ephy_permissions_manager_set_permission_for_address (EphyPermissionsManager *manager,
- EphyPermissionType type,
- const char *address,
- EphyPermission permission)
+ephy_permissions_manager_set_permission (EphyPermissionsManager *manager,
+ EphyPermissionType type,
+ const char *origin,
+ EphyPermission permission)
{
- GSettings *settings = ephy_permissions_manager_get_settings_for_address (manager, address);
+ GSettings *settings = ephy_permissions_manager_get_settings_for_origin (manager, origin);
g_settings_set_enum (settings, permission_type_to_string (type), permission);
}
diff --git a/lib/ephy-permissions-manager.h b/lib/ephy-permissions-manager.h
index 75fe2bf..fbad3a0 100644
--- a/lib/ephy-permissions-manager.h
+++ b/lib/ephy-permissions-manager.h
@@ -43,13 +43,13 @@ typedef enum {
EPHY_PERMISSION_TYPE_ACCESS_WEBCAM
} EphyPermissionType;
-EphyPermissionsManager *ephy_permissions_manager_new (void);
-
-EphyPermission ephy_permissions_manager_get_permission_for_address (EphyPermissionsManager *manager,
- EphyPermissionType type,
- const char
*address);
-void ephy_permissions_manager_set_permission_for_address (EphyPermissionsManager *manager,
- EphyPermissionType type,
- const char *address,
- EphyPermission
permission);
+EphyPermissionsManager *ephy_permissions_manager_new (void);
+
+EphyPermission ephy_permissions_manager_get_permission (EphyPermissionsManager *manager,
+ EphyPermissionType type,
+ const char *origin);
+void ephy_permissions_manager_set_permission (EphyPermissionsManager *manager,
+ EphyPermissionType type,
+ const char *origin,
+ EphyPermission permission);
G_END_DECLS
diff --git a/src/profile-migrator/ephy-profile-migrator.c b/src/profile-migrator/ephy-profile-migrator.c
index f4bd2a8..7e207fe 100644
--- a/src/profile-migrator/ephy-profile-migrator.c
+++ b/src/profile-migrator/ephy-profile-migrator.c
@@ -605,6 +605,20 @@ migrate_bookmarks (void)
}
static void
+migrate_permissions (void)
+{
+ char *filename;
+ GFile *file;
+
+ filename = g_build_filename (ephy_dot_dir (), "hosts.ini", NULL);
+ file = g_file_new_for_path (filename);
+ g_free (filename);
+
+ g_file_delete (file, NULL, NULL);
+ g_object_unref (file);
+}
+
+static void
migrate_nothing (void)
{
/* Used to replace migrators that have been removed. Only remove migrators
@@ -627,6 +641,7 @@ const EphyProfileMigrator migrators[] = {
migrate_form_passwords_to_libsecret,
migrate_app_desktop_file_categories,
migrate_bookmarks,
+ migrate_permissions
};
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]