[epiphany/wip/notification-permissions: 6/8] permissions-manager: operate on security origins, not hosts



commit 4ad6f2e0a77340a82f2bf5d61cb494ec770bc701
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 ++--
 lib/ephy-profile-utils.h                           |    2 +-
 src/profile-migrator/ephy-profile-migrator.c       |   15 ++++
 8 files changed, 107 insertions(+), 66 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 740183f..4f433f4 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -733,10 +733,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_object_weak_unref (G_OBJECT (info_bar), (GWeakNotify)form_auth_save_confirmation_info_bar_destroyed_cb, 
data);
@@ -1370,11 +1370,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);
   }
 
   g_object_weak_unref (G_OBJECT (info_bar), (GWeakNotify)permission_request_info_bar_destroyed_cb, data);
@@ -1480,6 +1480,7 @@ permission_request_cb (WebKitWebView           *web_view,
                        WebKitPermissionRequest *decision)
 {
   const char *address;
+  char *origin;
   EphyEmbedShell *shell;
   EphyPermissionsManager *permissions_manager;
   EphyPermission permission;
@@ -1506,10 +1507,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 99e9b6f..1fcab52 100644
--- a/embed/web-extension/ephy-web-extension.c
+++ b/embed/web-extension/ephy-web-extension.c
@@ -378,16 +378,20 @@ should_store_cb (const char *username,
   SoupURI *uri;
   char *uri_string;
   char *password_field_value = NULL;
+  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.");
@@ -429,6 +433,8 @@ should_store_cb (const char *username,
 out:
   if (password_field_value)
     g_free (password_field_value);
+  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..3642f66 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_for_uri (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/lib/ephy-profile-utils.h b/lib/ephy-profile-utils.h
index 81873f9..db6c660 100644
--- a/lib/ephy-profile-utils.h
+++ b/lib/ephy-profile-utils.h
@@ -24,7 +24,7 @@
 
 G_BEGIN_DECLS
 
-#define EPHY_PROFILE_MIGRATION_VERSION 13
+#define EPHY_PROFILE_MIGRATION_VERSION 14
 
 #define EPHY_BOOKMARKS_FILE     "bookmarks.gvdb"
 #define EPHY_HISTORY_FILE       "ephy-history.db"
diff --git a/src/profile-migrator/ephy-profile-migrator.c b/src/profile-migrator/ephy-profile-migrator.c
index b9d65ae..8f486d5 100644
--- a/src/profile-migrator/ephy-profile-migrator.c
+++ b/src/profile-migrator/ephy-profile-migrator.c
@@ -710,6 +710,20 @@ migrate_initial_state (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
@@ -736,6 +750,7 @@ const EphyProfileMigrator migrators[] = {
   migrate_bookmarks,
   migrate_adblock_filters,
   migrate_initial_state,
+  migrate_permissions
 };
 
 static gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]