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



commit ff737758e41069977c6e116a86f24c1168fa3af9
Author: Debarshi Ray <debarshir gnome org>
Date:   Thu Jul 12 20:35:18 2012 +0200

    oauthprovider: 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 GoaOAuthProvider to let
    the providers indicate those HTML nodes that can be used for denial.
    
    Fixes: https://bugzilla.gnome.org/670298

 src/goabackend/goagoogleprovider.c |   28 ++++++++++++++++++
 src/goabackend/goaoauthprovider.c  |   55 +++++++++++++++++++++++++++++++++++-
 src/goabackend/goaoauthprovider.h  |   10 ++++++-
 3 files changed, 91 insertions(+), 2 deletions(-)
---
diff --git a/src/goabackend/goagoogleprovider.c b/src/goabackend/goagoogleprovider.c
index 47d9f54..270ef65 100644
--- a/src/goabackend/goagoogleprovider.c
+++ b/src/goabackend/goagoogleprovider.c
@@ -263,6 +263,33 @@ get_identity_sync (GoaOAuthProvider  *provider,
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static gboolean
+is_deny_node (GoaOAuthProvider *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, "deny") != 0)
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  g_free (name);
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static gchar *
 parse_request_token_error (GoaOAuthProvider *provider, RestProxyCall *call)
 {
@@ -563,6 +590,7 @@ goa_google_provider_class_init (GoaGoogleProviderClass *klass)
 
   oauth_class = GOA_OAUTH_PROVIDER_CLASS (klass);
   oauth_class->get_identity_sync        = get_identity_sync;
+  oauth_class->is_deny_node             = is_deny_node;
   oauth_class->get_consumer_key         = get_consumer_key;
   oauth_class->get_consumer_secret      = get_consumer_secret;
   oauth_class->get_request_uri          = get_request_uri;
diff --git a/src/goabackend/goaoauthprovider.c b/src/goabackend/goaoauthprovider.c
index 59468ec..6a85dba 100644
--- a/src/goabackend/goaoauthprovider.c
+++ b/src/goabackend/goaoauthprovider.c
@@ -26,7 +26,6 @@
 
 #include <rest/oauth-proxy.h>
 #include <libsoup/soup.h>
-#include <webkit/webkit.h>
 #include <json-glib/json-glib.h>
 
 #include "goalogging.h"
@@ -432,6 +431,30 @@ goa_oauth_provider_get_identity_sync (GoaOAuthProvider *provider,
 }
 
 /**
+ * goa_oauth_provider_is_deny_node:
+ * @provider: A #GoaOAuthProvider.
+ * @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_oauth_provider_is_deny_node (GoaOAuthProvider *provider, WebKitDOMNode *node)
+{
+  g_return_val_if_fail (GOA_IS_OAUTH_PROVIDER (provider), FALSE);
+  return GOA_OAUTH_PROVIDER_GET_CLASS (provider)->is_deny_node (provider, node);
+}
+
+/**
  * goa_oauth_provider_parse_request_token_error:
  * @provider: A #GoaOAuthProvider.
  * @call: The #RestProxyCall that was used to fetch the request token.
@@ -616,18 +639,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;
+  GoaOAuthProvider *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_oauth_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/goaoauthprovider.h b/src/goabackend/goaoauthprovider.h
index c6451cb..ceafe1b 100644
--- a/src/goabackend/goaoauthprovider.h
+++ b/src/goabackend/goaoauthprovider.h
@@ -30,6 +30,7 @@
 #include <goabackend/goabackendtypes.h>
 #include <goabackend/goaprovider.h>
 #include <rest/rest-proxy-call.h>
+#include <webkit/webkit.h>
 
 G_BEGIN_DECLS
 
@@ -74,6 +75,7 @@ struct _GoaOAuthProvider
  * @get_use_mobile_browser: Virtual function for goa_oauth_provider_get_use_mobile_browser().
  * @get_request_uri_params: Virtual function for goa_oauth_provider_get_request_uri_params().
  * @add_account_key_values: Virtual function for goa_oauth_provider_add_account_key_values().
+ * @is_deny_node: Virtual function for goa_oauth_provider_is_deny_node().
  *
  * Class structure for #GoaOAuthProvider.
  */
@@ -110,9 +112,13 @@ struct _GoaOAuthProviderClass
   void         (*add_account_key_values)   (GoaOAuthProvider  *provider,
                                             GVariantBuilder   *builder);
 
+  /* pure virtual */
+  gboolean     (*is_deny_node)             (GoaOAuthProvider  *provider,
+                                            WebKitDOMNode     *node);
+
   /*< private >*/
   /* Padding for future expansion */
-  gpointer goa_reserved[32];
+  gpointer goa_reserved[31];
 };
 
 GType        goa_oauth_provider_get_type                 (void) G_GNUC_CONST;
@@ -130,6 +136,8 @@ gchar       *goa_oauth_provider_get_identity_sync        (GoaOAuthProvider  *pro
                                                           gchar            **out_presentation_identity,
                                                           GCancellable      *cancellable,
                                                           GError           **error);
+gboolean     goa_oauth_provider_is_deny_node             (GoaOAuthProvider  *provider,
+                                                          WebKitDOMNode     *node);
 gchar       *goa_oauth_provider_parse_request_token_error (GoaOAuthProvider *provider,
                                                            RestProxyCall    *call);
 gchar       *goa_oauth_provider_get_access_token_sync    (GoaOAuthProvider  *provider,



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