[gnome-online-accounts] oauth2provider: Don't display an error message if user denied access



commit 06079452f0adb93e14b390cc1d4a219b0c59f051
Author: Debarshi Ray <debarshir gnome org>
Date:   Thu Jul 12 19:17:21 2012 +0200

    oauth2provider: Don't display an error message if user denied access
    
    If the user deliberately denied access by clicking the appropriate
    HTMLButtonElement or HTMLInputElement in the embedded browser, then
    no error message should be displayed.
    
    Added a is_deny_node pure virtual method to GoaOAuth2Provider to let
    the providers indicate those HTML nodes that can be used for denial.
    
    Fixes: https://bugzilla.gnome.org/670298

 src/goabackend/goafacebookprovider.c    |   27 +++++++++++++++
 src/goabackend/goaoauth2provider.c      |   55 ++++++++++++++++++++++++++++++-
 src/goabackend/goaoauth2provider.h      |   10 +++++-
 src/goabackend/goawindowsliveprovider.c |   27 +++++++++++++++
 4 files changed, 117 insertions(+), 2 deletions(-)
---
diff --git a/src/goabackend/goafacebookprovider.c b/src/goabackend/goafacebookprovider.c
index bc44380..40fcebb 100644
--- a/src/goabackend/goafacebookprovider.c
+++ b/src/goabackend/goafacebookprovider.c
@@ -247,6 +247,32 @@ get_identity_sync (GoaOAuth2Provider  *provider,
   return ret;
 }
 
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+is_deny_node (GoaOAuth2Provider *provider, WebKitDOMNode *node)
+{
+  WebKitDOMHTMLButtonElement *button_element;
+  gboolean ret;
+  gchar *name;
+
+  name = NULL;
+  ret = FALSE;
+
+  if (!WEBKIT_DOM_IS_HTML_BUTTON_ELEMENT (node))
+    goto out;
+
+  button_element = WEBKIT_DOM_HTML_BUTTON_ELEMENT (node);
+  name = webkit_dom_html_button_element_get_name (button_element);
+  if (g_strcmp0 (name, "cancel_clicked") != 0)
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  g_free (name);
+  return ret;
+}
 
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -379,6 +405,7 @@ goa_facebook_provider_class_init (GoaFacebookProviderClass *klass)
   oauth2_class->get_client_secret        = get_client_secret;
   oauth2_class->get_authentication_cookie = get_authentication_cookie;
   oauth2_class->get_identity_sync        = get_identity_sync;
+  oauth2_class->is_deny_node             = is_deny_node;
   oauth2_class->get_use_external_browser = get_use_external_browser;
   oauth2_class->add_account_key_values   = add_account_key_values;
 }
diff --git a/src/goabackend/goaoauth2provider.c b/src/goabackend/goaoauth2provider.c
index a895f6e..fd2a636 100644
--- a/src/goabackend/goaoauth2provider.c
+++ b/src/goabackend/goaoauth2provider.c
@@ -27,7 +27,6 @@
 
 #include <rest/oauth2-proxy.h>
 #include <libsoup/soup.h>
-#include <webkit/webkit.h>
 #include <json-glib/json-glib.h>
 
 #include "goalogging.h"
@@ -436,6 +435,30 @@ goa_oauth2_provider_get_identity_sync (GoaOAuth2Provider    *provider,
   return GOA_OAUTH2_PROVIDER_GET_CLASS (provider)->get_identity_sync (provider, access_token, out_presentation_identity, cancellable, error);
 }
 
+/**
+ * goa_oauth2_provider_is_deny_node:
+ * @provider: A #GoaOAuth2Provider.
+ * @node: A #WebKitDOMNode.
+ *
+ * Checks whether @node is the HTML UI element that the user can use
+ * to deny permission to access his account. Usually they are either a
+ * #WebKitDOMHTMLButtonElement or a #WebKitDOMHTMLInputElement.
+ *
+ * Please note that providers may have multiple such elements in their
+ * UI and this method should catch all of them.
+ *
+ * This is a pure virtual method - a subclass must provide an
+ * implementation.
+ *
+ * Returns: %TRUE if the @node can be used to deny permission.
+ */
+gboolean
+goa_oauth2_provider_is_deny_node (GoaOAuth2Provider *provider, WebKitDOMNode *node)
+{
+  g_return_val_if_fail (GOA_IS_OAUTH2_PROVIDER (provider), FALSE);
+  return GOA_OAUTH2_PROVIDER_GET_CLASS (provider)->is_deny_node (provider, node);
+}
+
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gchar *
@@ -627,18 +650,48 @@ check_cookie (SoupCookie *cookie, gpointer user_data)
 }
 
 static void
+on_dom_node_click (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data)
+{
+  IdentifyData *data = user_data;
+  gtk_dialog_response (data->dialog, GTK_RESPONSE_CANCEL);
+}
+
+static void
 on_web_view_document_load_finished (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data)
 {
   IdentifyData *data = user_data;
   GSList *slist;
+  GoaOAuth2Provider *provider = data->provider;
   SoupCookieJar *cookie_jar;
   SoupSession *session;
+  WebKitDOMDocument *document;
+  WebKitDOMNodeList *elements;
+  gulong element_count;
+  gulong i;
 
   session = webkit_get_default_session ();
   cookie_jar = SOUP_COOKIE_JAR (soup_session_get_feature (session, SOUP_TYPE_COOKIE_JAR));
   slist = soup_cookie_jar_all_cookies (cookie_jar);
   g_slist_foreach (slist, (GFunc) check_cookie, data);
   g_slist_free_full (slist, (GDestroyNotify) soup_cookie_free);
+
+  document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (web_view));
+  elements = webkit_dom_document_get_elements_by_tag_name (document, "*");
+  element_count = webkit_dom_node_list_get_length (elements);
+
+  for (i = 0; i < element_count; i++)
+    {
+      WebKitDOMNode *element = webkit_dom_node_list_item (elements, i);
+
+      if (!goa_oauth2_provider_is_deny_node (provider, element))
+        continue;
+
+      webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (element),
+                                                  "click",
+                                                  G_CALLBACK (on_dom_node_click),
+                                                  false,
+                                                  data);
+    }
 }
 
 static gboolean
diff --git a/src/goabackend/goaoauth2provider.h b/src/goabackend/goaoauth2provider.h
index 3089476..d7cdc13 100644
--- a/src/goabackend/goaoauth2provider.h
+++ b/src/goabackend/goaoauth2provider.h
@@ -28,6 +28,7 @@
 #define __GOA_OAUTH2_PROVIDER_H__
 
 #include <goabackend/goabackendtypes.h>
+#include <webkit/webkit.h>
 
 G_BEGIN_DECLS
 
@@ -70,6 +71,7 @@ struct _GoaOAuth2Provider
  * @get_use_external_browser: Virtual function for goa_oauth2_provider_get_use_external_browser().
  * @get_use_mobile_browser: Virtual function for goa_oauth2_provider_get_use_mobile_browser().
  * @add_account_key_values: Virtual function for goa_oauth2_provider_add_account_key_values().
+ * @is_deny_node: Virtual function for goa_oauth2_provider_is_deny_node().
  *
  * Class structure for #GoaOAuth2Provider.
  */
@@ -102,9 +104,13 @@ struct _GoaOAuth2ProviderClass
   void         (*add_account_key_values)   (GoaOAuth2Provider  *provider,
                                             GVariantBuilder    *builder);
 
+  /* pure virtual */
+  gboolean     (*is_deny_node)             (GoaOAuth2Provider  *provider,
+                                            WebKitDOMNode      *node);
+
   /*< private >*/
   /* Padding for future expansion */
-  gpointer goa_reserved[32];
+  gpointer goa_reserved[31];
 };
 
 GType        goa_oauth2_provider_get_type                 (void) G_GNUC_CONST;
@@ -120,6 +126,8 @@ gchar       *goa_oauth2_provider_get_identity_sync        (GoaOAuth2Provider  *p
                                                            gchar             **out_presentation_identity,
                                                            GCancellable       *cancellable,
                                                            GError            **error);
+gboolean     goa_oauth2_provider_is_deny_node             (GoaOAuth2Provider  *provider,
+                                                           WebKitDOMNode      *node);
 gchar       *goa_oauth2_provider_get_access_token_sync    (GoaOAuth2Provider  *provider,
                                                            GoaObject          *object,
                                                            gboolean            force_refresh,
diff --git a/src/goabackend/goawindowsliveprovider.c b/src/goabackend/goawindowsliveprovider.c
index 757d64e..04c13f2 100644
--- a/src/goabackend/goawindowsliveprovider.c
+++ b/src/goabackend/goawindowsliveprovider.c
@@ -236,6 +236,32 @@ get_identity_sync (GoaOAuth2Provider  *provider,
   return ret;
 }
 
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+is_deny_node (GoaOAuth2Provider *provider, WebKitDOMNode *node)
+{
+  WebKitDOMHTMLInputElement *input_element;
+  gboolean ret;
+  gchar *name;
+
+  name = NULL;
+  ret = FALSE;
+
+  if (!WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (node))
+    goto out;
+
+  input_element = WEBKIT_DOM_HTML_INPUT_ELEMENT (node);
+  name = webkit_dom_html_input_element_get_name (input_element);
+  if (g_strcmp0 (name, "submitNo") != 0)
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  g_free (name);
+  return ret;
+}
 
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -402,6 +428,7 @@ goa_windows_live_provider_class_init (GoaWindowsLiveProviderClass *klass)
   oauth2_class->get_client_secret        = get_client_secret;
   oauth2_class->get_authentication_cookie = get_authentication_cookie;
   oauth2_class->get_identity_sync        = get_identity_sync;
+  oauth2_class->is_deny_node             = is_deny_node;
   oauth2_class->get_use_external_browser = get_use_external_browser;
   oauth2_class->add_account_key_values   = add_account_key_values;
 }



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