[gnome-online-accounts] oauth2: Allow providers to optionally offer a PasswordBased interface
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts] oauth2: Allow providers to optionally offer a PasswordBased interface
- Date: Sun, 4 Nov 2012 22:21:14 +0000 (UTC)
commit 6f86c7f419e126b14840c1ca56f94add1b442863
Author: Debarshi Ray <debarshir gnome org>
Date: Sun Nov 4 18:05:09 2012 +0100
oauth2: Allow providers to optionally offer a PasswordBased interface
Added a is_password_node virtual method to GoaOAuth2Provider to let the
providers indicate which HTML node is used to enter the password. The
default implementation returns FALSE.
Providers can optionally choose to do so by doing the following:
* Implement ensure_credentials_sync to verify that the password is
still valid, and chain up to the method in the parent class.
* Implement is_password_node.
* Create a GoaPasswordBased and set it on the GoaObject in the
build_object method.
* Handle the GetPassword D-Bus method.
Fixes: https://bugzilla.gnome.org/687578
src/goabackend/goaoauth2provider.c | 85 ++++++++++++++++++++++++++++++++++++
src/goabackend/goaoauth2provider.h | 9 +++-
2 files changed, 93 insertions(+), 1 deletions(-)
---
diff --git a/src/goabackend/goaoauth2provider.c b/src/goabackend/goaoauth2provider.c
index 0d631df..682c9d9 100644
--- a/src/goabackend/goaoauth2provider.c
+++ b/src/goabackend/goaoauth2provider.c
@@ -150,6 +150,35 @@ goa_oauth2_provider_get_use_mobile_browser (GoaOAuth2Provider *provider)
/* ---------------------------------------------------------------------------------------------------- */
+static gboolean
+goa_oauth2_provider_is_password_node_default (GoaOAuth2Provider *provider, WebKitDOMHTMLInputElement *element)
+{
+ return FALSE;
+}
+
+/**
+ * goa_oauth2_provider_is_password_node:
+ * @provider: A #GoaOAuth2Provider.
+ * @element: A WebKitDOMHTMLInputElement
+ *
+ * Checks whether @element is the HTML UI element that the user can
+ * use to enter her password.
+ *
+ * This is a virtual method where the default implementation returns
+ * %FALSE.
+ *
+ * Returns: %TRUE if @element can be used to enter the password.
+ */
+gboolean
+goa_oauth2_provider_is_password_node (GoaOAuth2Provider *provider, WebKitDOMHTMLInputElement *element)
+{
+ g_return_val_if_fail (GOA_IS_OAUTH2_PROVIDER (provider), FALSE);
+ g_return_val_if_fail (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element), FALSE);
+ return GOA_OAUTH2_PROVIDER_GET_CLASS (provider)->is_password_node (provider, element);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
static void
goa_oauth2_provider_add_account_key_values_default (GoaOAuth2Provider *provider,
GVariantBuilder *builder)
@@ -634,6 +663,9 @@ typedef struct
GError *error;
GMainLoop *loop;
+ WebKitDOMHTMLInputElement *password_node;
+ gchar *password;
+
gchar *authorization_code;
gchar *access_token;
gint access_token_expires_in;
@@ -680,6 +712,18 @@ on_dom_node_click (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_
}
static void
+on_form_submit (WebKitDOMNode *element, WebKitDOMEvent *event, gpointer user_data)
+{
+ IdentifyData *data = user_data;
+
+ if (data->password_node == NULL)
+ return;
+
+ data->password = webkit_dom_html_input_element_get_value (data->password_node);
+ data->password_node = NULL;
+}
+
+static void
on_web_view_document_load_finished (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data)
{
IdentifyData *data = user_data;
@@ -722,6 +766,23 @@ on_web_view_document_load_finished (WebKitWebView *web_view, WebKitWebFrame *fra
data->existing_identity);
webkit_dom_html_input_element_set_read_only (WEBKIT_DOM_HTML_INPUT_ELEMENT (element), TRUE);
}
+ else if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT (element)
+ && goa_oauth2_provider_is_password_node (provider, WEBKIT_DOM_HTML_INPUT_ELEMENT (element)))
+ {
+ WebKitDOMHTMLFormElement *form;
+
+ form = webkit_dom_html_input_element_get_form (WEBKIT_DOM_HTML_INPUT_ELEMENT (element));
+ if (form != NULL)
+ {
+ data->password_node = WEBKIT_DOM_HTML_INPUT_ELEMENT (element);
+ g_clear_pointer (&data->password, g_free);
+ webkit_dom_event_target_add_event_listener (WEBKIT_DOM_EVENT_TARGET (form),
+ "submit",
+ G_CALLBACK (on_form_submit),
+ FALSE,
+ data);
+ }
+ }
}
}
@@ -860,6 +921,7 @@ get_tokens_and_identity (GoaOAuth2Provider *provider,
gchar **out_refresh_token,
gchar **out_identity,
gchar **out_presentation_identity,
+ gchar **out_password,
GError **error)
{
gboolean ret;
@@ -1047,6 +1109,8 @@ get_tokens_and_identity (GoaOAuth2Provider *provider,
*out_identity = g_strdup (data.identity);
if (out_presentation_identity != NULL)
*out_presentation_identity = g_strdup (data.presentation_identity);
+ if (out_password != NULL)
+ *out_password = g_strdup (data.password);
}
else
{
@@ -1054,6 +1118,7 @@ get_tokens_and_identity (GoaOAuth2Provider *provider,
g_propagate_error (error, data.error);
}
+ g_free (data.password);
g_free (data.identity);
g_free (data.presentation_identity);
g_free (url);
@@ -1127,6 +1192,7 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
gchar *authorization_code;
gchar *access_token;
gint access_token_expires_in;
+ gchar *password;
gchar *refresh_token;
gchar *identity;
gchar *presentation_identity;
@@ -1143,6 +1209,7 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
ret = NULL;
authorization_code = NULL;
access_token = NULL;
+ password = NULL;
refresh_token = NULL;
identity = NULL;
presentation_identity = NULL;
@@ -1161,6 +1228,7 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
&refresh_token,
&identity,
&presentation_identity,
+ &password,
&data.error))
goto out;
@@ -1183,6 +1251,8 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
if (refresh_token != NULL)
g_variant_builder_add (&credentials, "{sv}", "refresh_token", g_variant_new_string (refresh_token));
+ if (password != NULL)
+ g_variant_builder_add (&credentials, "{sv}", "password", g_variant_new_string (password));
g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}"));
goa_oauth2_provider_add_account_key_values (provider, &details);
@@ -1218,6 +1288,7 @@ goa_oauth2_provider_add_account (GoaProvider *_provider,
g_free (identity);
g_free (presentation_identity);
+ g_free (password);
g_free (refresh_token);
g_free (access_token);
g_free (authorization_code);
@@ -1242,6 +1313,7 @@ goa_oauth2_provider_refresh_account (GoaProvider *_provider,
gchar *authorization_code;
gchar *access_token;
gint access_token_expires_in;
+ gchar *password;
gchar *refresh_token;
gchar *identity;
const gchar *existing_identity;
@@ -1257,6 +1329,7 @@ goa_oauth2_provider_refresh_account (GoaProvider *_provider,
authorization_code = NULL;
access_token = NULL;
+ password = NULL;
refresh_token = NULL;
identity = NULL;
@@ -1289,6 +1362,7 @@ goa_oauth2_provider_refresh_account (GoaProvider *_provider,
&refresh_token,
&identity,
NULL, /* out_presentation_identity */
+ &password,
error))
goto out;
@@ -1317,6 +1391,8 @@ goa_oauth2_provider_refresh_account (GoaProvider *_provider,
g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
if (refresh_token != NULL)
g_variant_builder_add (&builder, "{sv}", "refresh_token", g_variant_new_string (refresh_token));
+ if (password != NULL)
+ g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password));
if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider),
object,
g_variant_builder_end (&builder),
@@ -1336,6 +1412,7 @@ goa_oauth2_provider_refresh_account (GoaProvider *_provider,
g_free (identity);
g_free (access_token);
g_free (authorization_code);
+ g_free (password);
g_free (refresh_token);
return ret;
}
@@ -1397,6 +1474,7 @@ goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider,
gint access_token_expires_in;
gchar *refresh_token;
gchar *old_refresh_token;
+ gchar *password;
gboolean success;
GVariantBuilder builder;
gchar *ret;
@@ -1413,6 +1491,7 @@ goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider,
access_token = NULL;
refresh_token = NULL;
old_refresh_token = NULL;
+ password = NULL;
access_token_expires_in = 0;
success = FALSE;
@@ -1460,6 +1539,8 @@ goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider,
refresh_token = g_variant_dup_string (value, NULL);
else if (g_strcmp0 (key, "authorization_code") == 0)
authorization_code = g_variant_dup_string (value, NULL);
+ else if (g_strcmp0 (key, "password") == 0)
+ password = g_variant_dup_string (value, NULL);
g_variant_unref (value);
}
@@ -1533,6 +1614,8 @@ goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider,
g_variant_new_int64 (duration_to_abs_usec (access_token_expires_in)));
if (refresh_token != NULL)
g_variant_builder_add (&builder, "{sv}", "refresh_token", g_variant_new_string (refresh_token));
+ if (password != NULL)
+ g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password));
if (!goa_utils_store_credentials_for_object_sync (GOA_PROVIDER (provider),
object,
@@ -1564,6 +1647,7 @@ goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider,
g_free (access_token);
g_free (refresh_token);
g_free (old_refresh_token);
+ g_free (password);
if (credentials != NULL)
g_variant_unref (credentials);
@@ -1698,6 +1782,7 @@ goa_oauth2_provider_class_init (GoaOAuth2ProviderClass *klass)
klass->get_token_uri = goa_oauth2_provider_get_token_uri_default;
klass->get_use_external_browser = goa_oauth2_provider_get_use_external_browser_default;
klass->get_use_mobile_browser = goa_oauth2_provider_get_use_mobile_browser_default;
+ klass->is_password_node = goa_oauth2_provider_is_password_node_default;
klass->add_account_key_values = goa_oauth2_provider_add_account_key_values_default;
}
diff --git a/src/goabackend/goaoauth2provider.h b/src/goabackend/goaoauth2provider.h
index 64ac8db..980f512 100644
--- a/src/goabackend/goaoauth2provider.h
+++ b/src/goabackend/goaoauth2provider.h
@@ -73,6 +73,7 @@ struct _GoaOAuth2Provider
* @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().
* @is_identity_node: Virtual function for goa_oauth2_provider_is_identity_node().
+ * @is_password_node: Virtual function for goa_oauth2_provider_is_password_node().
*
* Class structure for #GoaOAuth2Provider.
*/
@@ -111,9 +112,13 @@ struct _GoaOAuth2ProviderClass
gboolean (*is_identity_node) (GoaOAuth2Provider *provider,
WebKitDOMHTMLInputElement *element);
+ /* virtual but with default implementation */
+ gboolean (*is_password_node) (GoaOAuth2Provider *provider,
+ WebKitDOMHTMLInputElement *element);
+
/*< private >*/
/* Padding for future expansion */
- gpointer goa_reserved[30];
+ gpointer goa_reserved[29];
};
GType goa_oauth2_provider_get_type (void) G_GNUC_CONST;
@@ -133,6 +138,8 @@ gboolean goa_oauth2_provider_is_deny_node (GoaOAuth2Provider *p
WebKitDOMNode *node);
gboolean goa_oauth2_provider_is_identity_node (GoaOAuth2Provider *provider,
WebKitDOMHTMLInputElement *element);
+gboolean goa_oauth2_provider_is_password_node (GoaOAuth2Provider *provider,
+ WebKitDOMHTMLInputElement *element);
gchar *goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider,
GoaObject *object,
gboolean force_refresh,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]