[PolicyKit-gnome] Support multiple outstanding authentication requests
- From: David Zeuthen <davidz src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [PolicyKit-gnome] Support multiple outstanding authentication requests
- Date: Tue, 10 Nov 2009 14:35:52 +0000 (UTC)
commit f32cb7faa7197b9db55b569677732742c3c7fdc1
Author: David Zeuthen <davidz redhat com>
Date: Tue Nov 10 09:30:05 2009 -0500
Support multiple outstanding authentication requests
Simply queue up authentication requests and process them one by
one. We could have done this in parallel but that's probably not a
very good user experience.
This feature was requested here
https://bugzilla.redhat.com/show_bug.cgi?id=526053
and while it's a sign of bad design to be in a situation where
multiple outstanding requests are pending, this is not the right place
to fix it.
One example of this feature is that you can now run 'pkexec bash' from
two different terminals and you get two authentication requests right
after each other.
src/polkitgnomeauthenticator.c | 8 ++++-
src/polkitgnomelistener.c | 67 ++++++++++++++++++++++++----------------
2 files changed, 47 insertions(+), 28 deletions(-)
---
diff --git a/src/polkitgnomeauthenticator.c b/src/polkitgnomeauthenticator.c
index 8fd15cd..019388c 100644
--- a/src/polkitgnomeauthenticator.c
+++ b/src/polkitgnomeauthenticator.c
@@ -485,7 +485,13 @@ polkit_gnome_authenticator_cancel (PolkitGnomeAuthenticator *authenticator)
authenticator->was_cancelled = TRUE;
if (authenticator->session != NULL)
- polkit_agent_session_cancel (authenticator->session);
+ {
+ polkit_agent_session_cancel (authenticator->session);
+ }
+ else
+ {
+ g_signal_emit_by_name (authenticator, "completed", FALSE);
+ }
}
const gchar *
diff --git a/src/polkitgnomelistener.c b/src/polkitgnomelistener.c
index c85b63e..f09bef9 100644
--- a/src/polkitgnomelistener.c
+++ b/src/polkitgnomelistener.c
@@ -31,8 +31,10 @@ struct _PolkitGnomeListener
{
PolkitAgentListener parent_instance;
- /* we only support a single active authenticator right now */
- PolkitGnomeAuthenticator *the_authenticator;
+ /* we support multiple authenticators - they are simply queued up */
+ GList *authenticators;
+
+ PolkitGnomeAuthenticator *active_authenticator;
};
struct _PolkitGnomeListenerClass
@@ -97,6 +99,8 @@ polkit_gnome_listener_new (void)
typedef struct
{
PolkitGnomeListener *listener;
+ PolkitGnomeAuthenticator *authenticator;
+
GSimpleAsyncResult *simple;
GCancellable *cancellable;
@@ -105,6 +109,7 @@ typedef struct
static AuthData *
auth_data_new (PolkitGnomeListener *listener,
+ PolkitGnomeAuthenticator *authenticator,
GSimpleAsyncResult *simple,
GCancellable *cancellable)
{
@@ -112,6 +117,7 @@ auth_data_new (PolkitGnomeListener *listener,
data = g_new0 (AuthData, 1);
data->listener = g_object_ref (listener);
+ data->authenticator = g_object_ref (authenticator);
data->simple = g_object_ref (simple);
data->cancellable = g_object_ref (cancellable);
return data;
@@ -121,6 +127,7 @@ static void
auth_data_free (AuthData *data)
{
g_object_unref (data->listener);
+ g_object_unref (data->authenticator);
g_object_unref (data->simple);
if (data->cancellable != NULL && data->cancel_id > 0)
g_signal_handler_disconnect (data->cancellable, data->cancel_id);
@@ -129,20 +136,33 @@ auth_data_free (AuthData *data)
}
static void
+maybe_initiate_next_authenticator (PolkitGnomeListener *listener)
+{
+ if (listener->active_authenticator == NULL && listener->authenticators != NULL)
+ {
+ polkit_gnome_authenticator_initiate (POLKIT_GNOME_AUTHENTICATOR (listener->authenticators->data));
+ listener->active_authenticator = listener->authenticators->data;
+ }
+}
+
+static void
authenticator_completed (PolkitGnomeAuthenticator *authenticator,
gboolean gained_authorization,
gpointer user_data)
{
AuthData *data = user_data;
- g_warn_if_fail (authenticator == data->listener->the_authenticator);
+ data->listener->authenticators = g_list_remove (data->listener->authenticators, authenticator);
+ if (authenticator == data->listener->active_authenticator)
+ data->listener->active_authenticator = NULL;
- g_object_unref (data->listener->the_authenticator);
- data->listener->the_authenticator = NULL;
+ g_object_unref (authenticator);
g_simple_async_result_complete (data->simple);
g_object_unref (data->simple);
+ maybe_initiate_next_authenticator (data->listener);
+
auth_data_free (data);
}
@@ -152,7 +172,7 @@ cancelled_cb (GCancellable *cancellable,
{
AuthData *data = user_data;
- polkit_gnome_authenticator_cancel (data->listener->the_authenticator);
+ polkit_gnome_authenticator_cancel (data->authenticator);
}
static void
@@ -169,6 +189,7 @@ polkit_gnome_listener_initiate_authentication (PolkitAgentListener *agent_liste
{
PolkitGnomeListener *listener = POLKIT_GNOME_LISTENER (agent_listener);
GSimpleAsyncResult *simple;
+ PolkitGnomeAuthenticator *authenticator;
AuthData *data;
simple = g_simple_async_result_new (G_OBJECT (listener),
@@ -176,35 +197,25 @@ polkit_gnome_listener_initiate_authentication (PolkitAgentListener *agent_liste
user_data,
polkit_gnome_listener_initiate_authentication);
- if (listener->the_authenticator != NULL)
+ authenticator = polkit_gnome_authenticator_new (action_id,
+ message,
+ icon_name,
+ details,
+ cookie,
+ identities);
+ if (authenticator == NULL)
{
g_simple_async_result_set_error (simple,
POLKIT_ERROR,
POLKIT_ERROR_FAILED,
- "Authentication is already in progress for another action");
+ "Error creating authentication object");
g_simple_async_result_complete (simple);
goto out;
}
- listener->the_authenticator = polkit_gnome_authenticator_new (action_id,
- message,
- icon_name,
- details,
- cookie,
- identities);
- if (listener->the_authenticator == NULL)
- {
- g_simple_async_result_set_error (simple,
- POLKIT_ERROR,
- POLKIT_ERROR_FAILED,
- "Authentication is already in progress for another action");
- g_simple_async_result_complete (simple);
- goto out;
- }
+ data = auth_data_new (listener, authenticator, simple, cancellable);
- data = auth_data_new (listener, simple, cancellable);
-
- g_signal_connect (listener->the_authenticator,
+ g_signal_connect (authenticator,
"completed",
G_CALLBACK (authenticator_completed),
data);
@@ -217,7 +228,9 @@ polkit_gnome_listener_initiate_authentication (PolkitAgentListener *agent_liste
data);
}
- polkit_gnome_authenticator_initiate (listener->the_authenticator);
+ listener->authenticators = g_list_append (listener->authenticators, authenticator);
+
+ maybe_initiate_next_authenticator (listener);
out:
;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]