summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Catanzaro <mcatanzaro@gnome.org>2016-12-30 18:21:42 -0600
committerMichael Catanzaro <mcatanzaro@gnome.org>2016-12-30 19:24:59 -0600
commit573c4bc8dff9a1614524f74c0bc60d87bef74560 (patch)
treebfe07b325e7c00cde6c7b075361ff7be23228e25
parentf03156aa2f3379e8ecc1deda0d598f1f9e393677 (diff)
downloadepiphany-wip/security-origins.tar.gz
Set initial notification permissionswip/security-origins
https://bugs.webkit.org/show_bug.cgi?id=163366
-rw-r--r--embed/ephy-embed-shell.c25
-rw-r--r--lib/ephy-permissions-manager.c142
-rw-r--r--lib/ephy-permissions-manager.h6
3 files changed, 167 insertions, 6 deletions
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 0c4f03be7..1156612ea 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -889,6 +889,24 @@ initialize_web_extensions (WebKitWebContext *web_context,
}
static void
+set_initial_notification_permissions (WebKitWebContext *web_context,
+ EphyEmbedShell *shell)
+{
+ EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
+ GList *permitted_origins;
+ GList *denied_origins;
+
+ permitted_origins = ephy_permissions_manager_get_permitted_origins (priv->permissions_manager,
+ EPHY_PERMISSION_TYPE_SHOW_NOTIFICATIONS);
+ denied_origins = ephy_permissions_manager_get_denied_origins (priv->permissions_manager,
+ EPHY_PERMISSION_TYPE_SHOW_NOTIFICATIONS);
+ webkit_web_context_set_initial_notification_permissions (web_context, permitted_origins, denied_origins);
+
+ g_list_free_full (permitted_origins, (GDestroyNotify)webkit_security_origin_unref);
+ g_list_free_full (denied_origins, (GDestroyNotify)webkit_security_origin_unref);
+}
+
+static void
web_extension_page_created (EphyWebExtensionProxy *extension,
guint64 page_id,
EphyEmbedShell *shell)
@@ -1076,6 +1094,11 @@ ephy_embed_shell_startup (GApplication *application)
G_CALLBACK (initialize_web_extensions),
shell);
+ priv->permissions_manager = ephy_permissions_manager_new ();
+ g_signal_connect (priv->web_context, "set-initial-notification-permissions",
+ G_CALLBACK (set_initial_notification_permissions),
+ shell);
+
/* Favicon Database */
favicon_db_path = g_build_filename (EPHY_EMBED_SHELL_MODE_HAS_PRIVATE_PROFILE (priv->mode) ?
ephy_dot_dir () : g_get_user_cache_dir (),
@@ -1587,7 +1610,5 @@ ephy_embed_shell_get_permissions_manager (EphyEmbedShell *shell)
{
EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
- if (!priv->permissions_manager)
- priv->permissions_manager = ephy_permissions_manager_new ();
return priv->permissions_manager;
}
diff --git a/lib/ephy-permissions-manager.c b/lib/ephy-permissions-manager.c
index 1f62fe0a0..ce691b3c7 100644
--- a/lib/ephy-permissions-manager.c
+++ b/lib/ephy-permissions-manager.c
@@ -27,6 +27,7 @@
#define G_SETTINGS_ENABLE_BACKEND 1
#include <gio/gsettingsbackend.h>
+#include <stdlib.h>
#include <string.h>
#include <webkit2/webkit2.h>
@@ -40,6 +41,8 @@ struct _EphyPermissionsManager
G_DEFINE_TYPE (EphyPermissionsManager, ephy_permissions_manager, G_TYPE_OBJECT)
+#define PERMISSIONS_FILENAME "permissions.ini"
+
static void
ephy_permissions_manager_init (EphyPermissionsManager *manager)
{
@@ -70,9 +73,9 @@ static GSettings *
ephy_permissions_manager_get_settings_for_origin (EphyPermissionsManager *manager,
const char *origin)
{
- char *key_file;
char *origin_path;
char *trimmed_protocol;
+ char *filename;
GSettingsBackend* backend;
GSettings *settings;
WebKitSecurityOrigin *security_origin;
@@ -84,9 +87,9 @@ ephy_permissions_manager_get_settings_for_origin (EphyPermissionsManager *manage
if (settings)
return settings;
- key_file = g_build_filename (ephy_dot_dir (), "permissions.ini", NULL);
- backend = g_keyfile_settings_backend_new (key_file, "/", NULL);
- g_free (key_file);
+ filename = g_build_filename (ephy_dot_dir (), PERMISSIONS_FILENAME, NULL);
+ backend = g_keyfile_settings_backend_new (filename, "/", NULL);
+ g_free (filename);
/* Cannot contain consecutive slashes in GSettings path... */
security_origin = webkit_security_origin_new_from_string (origin);
@@ -156,3 +159,134 @@ ephy_permissions_manager_set_permission (EphyPermissionsManager *manager,
GSettings *settings = ephy_permissions_manager_get_settings_for_origin (manager, origin);
g_settings_set_enum (settings, permission_type_to_string (type), permission);
}
+
+static WebKitSecurityOrigin *
+group_name_to_security_origin (const char *group)
+{
+ char **tokens;
+ WebKitSecurityOrigin *origin = NULL;
+
+ /* Should be of form org/gnome/epiphany/permissions/http/example.com/0 */
+ tokens = g_strsplit (group, "/", -1);
+ if (g_strv_length (tokens) == 7 && tokens[4] != NULL && tokens[5] != NULL && tokens[6] != NULL)
+ origin = webkit_security_origin_new (tokens[4], tokens[5], atoi (tokens[6]));
+
+ g_strfreev (tokens);
+
+ return origin;
+}
+
+static WebKitSecurityOrigin *
+origin_for_keyfile_key (GKeyFile *file,
+ const char *filename,
+ const char *group,
+ const char *key,
+ EphyPermissionType type,
+ gboolean permit)
+{
+ WebKitSecurityOrigin *origin = NULL;
+ char *value;
+ GError *error = NULL;
+
+ if (strcmp (permission_type_to_string (type), key) == 0) {
+ value = g_key_file_get_string (file, group, key, &error);
+ if (error != NULL) {
+ g_warning ("Error processing %s group %s key %s: %s",
+ filename, group, key, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ if ((permit && strcmp (value, "'allow'") == 0) ||
+ (!permit && strcmp (value, "'deny'") == 0))
+ origin = group_name_to_security_origin (group);
+
+ g_free (value);
+ }
+
+ return origin;
+}
+
+static GList *
+origins_for_keyfile_group (GKeyFile *file,
+ const char *filename,
+ const char *group,
+ EphyPermissionType type,
+ gboolean permit)
+{
+ char **keys;
+ gsize keys_length;
+ GList *origins = NULL;
+ WebKitSecurityOrigin *origin;
+ GError *error = NULL;
+
+ keys = g_key_file_get_keys (file, group, &keys_length, &error);
+ if (error != NULL) {
+ g_warning ("Error processing %s group %s: %s", filename, group, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ for (guint i = 0; i < keys_length; i++) {
+ origin = origin_for_keyfile_key (file, filename, group, keys[i], type, permit);
+ if (origin)
+ origins = g_list_prepend (origins, origin);
+ }
+
+ g_strfreev (keys);
+
+ return origins;
+}
+
+/* TODO: Consider caching this in memory. This gets called twice when
+ * starting each web process. It could be dozens or hundreds of file
+ * reads when starting the browser. It's silly to cache individual
+ * settings but not this. */
+static GList *
+ephy_permissions_manager_get_matching_origins (EphyPermissionsManager *manager,
+ EphyPermissionType type,
+ gboolean permit)
+{
+ GKeyFile *file;
+ char *filename;
+ char **groups;
+ gsize groups_length;
+ GList *origins = NULL;
+ GError *error = NULL;
+
+ file = g_key_file_new ();
+ filename = g_build_filename (ephy_dot_dir (), PERMISSIONS_FILENAME, NULL);
+
+ g_key_file_load_from_file (file, filename, G_KEY_FILE_NONE, &error);
+ if (error != NULL) {
+ if (!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND))
+ g_warning ("Error processing %s: %s", filename, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ groups = g_key_file_get_groups (file, &groups_length);
+ for (guint i = 0; i < groups_length; i++)
+ origins = g_list_concat (origins,
+ origins_for_keyfile_group (file, filename, groups[i], type, permit));
+
+ g_key_file_unref (file);
+ g_strfreev (groups);
+ g_free (filename);
+
+ return origins;
+}
+
+GList *
+ephy_permissions_manager_get_permitted_origins (EphyPermissionsManager *manager,
+ EphyPermissionType type)
+{
+ return ephy_permissions_manager_get_matching_origins (manager, type, TRUE);
+}
+
+GList *
+ephy_permissions_manager_get_denied_origins (EphyPermissionsManager *manager,
+ EphyPermissionType type)
+{
+ return ephy_permissions_manager_get_matching_origins (manager, type, FALSE);
+}
diff --git a/lib/ephy-permissions-manager.h b/lib/ephy-permissions-manager.h
index 1090a9934..eeeb8b148 100644
--- a/lib/ephy-permissions-manager.h
+++ b/lib/ephy-permissions-manager.h
@@ -52,4 +52,10 @@ void ephy_permissions_manager_set_permission (EphyPermissions
EphyPermissionType type,
const char *origin,
EphyPermission permission);
+
+GList *ephy_permissions_manager_get_permitted_origins (EphyPermissionsManager *manager,
+ EphyPermissionType type);
+GList *ephy_permissions_manager_get_denied_origins (EphyPermissionsManager *manager,
+ EphyPermissionType type);
+
G_END_DECLS