[epiphany/carlosgc/http-auth-credential-storage: 5/5] Store HTTP Auth passwords in password manager



commit 3c0524dc169ae35894d3f7d09f076b988eb9bfb2
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Tue Jun 23 14:51:21 2020 +0200

    Store HTTP Auth passwords in password manager
    
    Use new WebKit API to disable the internal credential storage and use
    our own.
    
    Fixes: https://gitlab.gnome.org/GNOME/epiphany/-/issues/719

 embed/ephy-embed-shell.c |   1 +
 embed/ephy-web-view.c    | 107 ++++++++++++++++++++++++++++++++++++++++++-----
 meson.build              |   2 +-
 3 files changed, 99 insertions(+), 11 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index eea168a83..a7702860a 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -781,6 +781,7 @@ ephy_embed_shell_create_web_context (EphyEmbedShell *shell)
     manager = webkit_website_data_manager_new ("base-data-directory", ephy_profile_dir (),
                                                "base-cache-directory", ephy_cache_dir (),
                                                NULL);
+    webkit_website_data_manager_set_persistent_credential_storage_enabled (manager, FALSE);
   }
 
   webkit_website_data_manager_set_itp_enabled (manager,
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 60cbb85ac..5c700e0f5 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -2407,6 +2407,77 @@ reader_setting_changed_cb (GSettings   *settings,
   g_free (js_snippet);
 }
 
+typedef struct {
+  EphyWebView *web_view;
+  WebKitAuthenticationRequest *request;
+} AuthenticationData;
+
+static AuthenticationData *
+authentication_data_new (EphyWebView                 *web_view,
+                         WebKitAuthenticationRequest *request)
+{
+  AuthenticationData *data;
+
+  data = g_new (AuthenticationData, 1);
+  data->web_view = g_object_ref (web_view);
+  data->request = g_object_ref (request);
+
+  return data;
+}
+
+static void
+authentication_data_free (AuthenticationData *data)
+{
+  g_object_unref (data->web_view);
+  g_object_unref (data->request);
+  g_free (data);
+}
+
+static void
+auth_password_query_finished_cb (GList              *records,
+                                 AuthenticationData *data)
+{
+  EphyPasswordRecord *record;
+  g_autoptr (WebKitCredential) credential = NULL;
+
+  record = records && records->data ? EPHY_PASSWORD_RECORD (records->data) : NULL;
+  if (record) {
+    credential = webkit_credential_new (ephy_password_record_get_username (record),
+                                        ephy_password_record_get_password (record),
+                                        WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
+  } else {
+    /* Provide a non-empty wrong credential to force a retry */
+    credential = webkit_credential_new (" ", "", WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
+  }
+
+  webkit_authentication_request_authenticate (data->request, credential);
+  authentication_data_free (data);
+}
+
+static void
+authenticate_succeeded_cb (WebKitAuthenticationRequest *request,
+                           WebKitCredential            *credential)
+{
+  EphyPasswordManager *password_manager;
+  g_autoptr (WebKitSecurityOrigin) security_origin = NULL;
+  g_autofree char *origin = NULL;
+
+  if (webkit_credential_get_persistence (credential) != WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT)
+    return;
+
+  security_origin = webkit_authentication_request_get_security_origin (request);
+  origin = webkit_security_origin_to_string (security_origin);
+  password_manager = ephy_embed_shell_get_password_manager (ephy_embed_shell_get_default ());
+  ephy_password_manager_save (password_manager,
+                              origin,
+                              origin,
+                              webkit_credential_get_username (credential),
+                              webkit_credential_get_password (credential),
+                              "org.gnome.Epiphany.HTTPAuthCredentials.Username",
+                              "org.gnome.Epiphany.HTTPAuthCredentials.Password",
+                              TRUE);
+}
+
 static gboolean
 authenticate_cb (WebKitWebView               *web_view,
                  WebKitAuthenticationRequest *request,
@@ -2414,18 +2485,34 @@ authenticate_cb (WebKitWebView               *web_view,
 {
   EphyWebView *ephy_web_view = EPHY_WEB_VIEW (web_view);
   g_autoptr (WebKitCredential) credential = NULL;
-
-  credential = webkit_authentication_request_get_proposed_credential (request);
-
-  /* In case we have known credentials and it is the firs try, authenticate automatically */
-  if (credential && !webkit_authentication_request_is_retry (request)) {
-    webkit_authentication_request_authenticate (request, credential);
-    return TRUE;
+  EphyPasswordManager *password_manager;
+  AuthenticationData *data;
+  g_autoptr (WebKitSecurityOrigin) security_origin = NULL;
+  g_autofree char *origin = NULL;
+
+  if (webkit_authentication_request_is_retry (request)) {
+    webkit_authentication_request_set_can_save_credentials (request, TRUE);
+    g_signal_connect_object (request, "authenticated",
+                             G_CALLBACK (authenticate_succeeded_cb),
+                             ephy_web_view, 0);
+    ephy_web_view->in_auth_dialog = 1;
+    return FALSE;
   }
 
-  ephy_web_view->in_auth_dialog = 1;
-
-  return FALSE;
+  data = authentication_data_new (ephy_web_view, request);
+  security_origin = webkit_authentication_request_get_security_origin (request);
+  origin = webkit_security_origin_to_string (security_origin);
+  password_manager = ephy_embed_shell_get_password_manager (ephy_embed_shell_get_default ());
+  ephy_password_manager_query (password_manager,
+                               NULL,
+                               origin,
+                               origin,
+                               NULL,
+                               "org.gnome.Epiphany.HTTPAuthCredentials.Username",
+                               "org.gnome.Epiphany.HTTPAuthCredentials.Password",
+                               (EphyPasswordManagerQueryCallback)auth_password_query_finished_cb,
+                               data);
+  return TRUE;
 }
 
 typedef struct {
diff --git a/meson.build b/meson.build
index 4c9b8d353..bc09ac165 100644
--- a/meson.build
+++ b/meson.build
@@ -76,7 +76,7 @@ config_h = declare_dependency(
 glib_requirement = '>= 2.61.2'
 gtk_requirement = '>= 3.24.0'
 nettle_requirement = '>= 3.4'
-webkitgtk_requirement = '>= 2.29.2'
+webkitgtk_requirement = '>= 2.29.3'
 
 cairo_dep = dependency('cairo', version: '>= 1.2')
 gcr_dep = dependency('gcr-3', version: '>= 3.5.5')


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