diff options
author | Guido Günther <agx@sigxcpu.org> | 2014-02-05 08:38:23 +0100 |
---|---|---|
committer | Guido Günther <agx@sigxcpu.org> | 2014-02-05 08:38:23 +0100 |
commit | dc645b92b9a7db3076ae34986ac219d01677d124 (patch) | |
tree | 963a5d6ad150a88a2a8ab6d994d79d539e19383a /src/mm-auth-provider.c | |
parent | 87bd9deec22af69bb27226254803ac5c63b18d78 (diff) |
Imported Upstream version 0.4+git.20100624t180933.6e79d15upstream/0.4+git.20100624t180933.6e79d15
Diffstat (limited to 'src/mm-auth-provider.c')
-rw-r--r-- | src/mm-auth-provider.c | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/src/mm-auth-provider.c b/src/mm-auth-provider.c new file mode 100644 index 0000000..ceff9ad --- /dev/null +++ b/src/mm-auth-provider.c @@ -0,0 +1,300 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#include <string.h> + +#include "mm-marshal.h" +#include "mm-auth-provider.h" + +GObject *mm_auth_provider_new (void); + +G_DEFINE_TYPE (MMAuthProvider, mm_auth_provider, G_TYPE_OBJECT) + +#define MM_AUTH_PROVIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_AUTH_PROVIDER, MMAuthProviderPrivate)) + +typedef struct { + GHashTable *requests; + guint process_id; +} MMAuthProviderPrivate; + +enum { + PROP_0, + PROP_NAME, + LAST_PROP +}; + +/*****************************************************************************/ + +GObject * +mm_auth_provider_new (void) +{ + return g_object_new (MM_TYPE_AUTH_PROVIDER, NULL); +} + +/*****************************************************************************/ + +static void +remove_requests (MMAuthProvider *self, GSList *remove) +{ + MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self); + MMAuthRequest *req; + + while (remove) { + req = MM_AUTH_REQUEST (remove->data); + g_hash_table_remove (priv->requests, req); + remove = g_slist_remove (remove, req); + } +} + +void +mm_auth_provider_cancel_request (MMAuthProvider *provider, MMAuthRequest *req) +{ + MMAuthProviderPrivate *priv; + + g_return_if_fail (provider != NULL); + g_return_if_fail (MM_IS_AUTH_PROVIDER (provider)); + g_return_if_fail (req != NULL); + + priv = MM_AUTH_PROVIDER_GET_PRIVATE (provider); + + g_return_if_fail (g_hash_table_lookup (priv->requests, req) != NULL); + g_hash_table_remove (priv->requests, req); +} + +void +mm_auth_provider_cancel_for_owner (MMAuthProvider *self, GObject *owner) +{ + MMAuthProviderPrivate *priv; + GHashTableIter iter; + MMAuthRequest *req; + gpointer value; + GSList *remove = NULL; + + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_AUTH_PROVIDER (self)); + + /* Find all requests from this owner */ + priv = MM_AUTH_PROVIDER_GET_PRIVATE (self); + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + req = MM_AUTH_REQUEST (value); + if (mm_auth_request_get_owner (req) == owner) + remove = g_slist_prepend (remove, req); + } + + /* And cancel/remove them */ + remove_requests (self, remove); +} + +/*****************************************************************************/ + + +static MMAuthRequest * +real_create_request (MMAuthProvider *provider, + const char *authorization, + GObject *owner, + DBusGMethodInvocation *context, + MMAuthRequestCb callback, + gpointer callback_data, + GDestroyNotify notify) +{ + return (MMAuthRequest *) mm_auth_request_new (0, + authorization, + owner, + context, + callback, + callback_data, + notify); +} + +static gboolean +process_complete_requests (gpointer user_data) +{ + MMAuthProvider *self = MM_AUTH_PROVIDER (user_data); + MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self); + GHashTableIter iter; + gpointer value; + GSList *remove = NULL; + MMAuthRequest *req; + + priv->process_id = 0; + + /* Call finished request's callbacks */ + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, &value)) { + req = MM_AUTH_REQUEST (value); + + if (mm_auth_request_get_authorization (req) != MM_AUTH_RESULT_UNKNOWN) { + mm_auth_request_callback (req); + remove = g_slist_prepend (remove, req); + } + } + + /* And remove those requests from our pending request list */ + remove_requests (self, remove); + + return FALSE; +} + +static void +auth_result_cb (MMAuthRequest *req, gpointer user_data) +{ + MMAuthProvider *self = MM_AUTH_PROVIDER (user_data); + MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self); + + /* Process results from an idle handler */ + if (priv->process_id == 0) + priv->process_id = g_idle_add (process_complete_requests, self); +} + +#define RESULT_SIGID_TAG "result-sigid" + +MMAuthRequest * +mm_auth_provider_request_auth (MMAuthProvider *self, + const char *authorization, + GObject *owner, + DBusGMethodInvocation *context, + MMAuthRequestCb callback, + gpointer callback_data, + GDestroyNotify notify, + GError **error) +{ + MMAuthProviderPrivate *priv; + MMAuthRequest *req; + guint32 sigid; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (MM_IS_AUTH_PROVIDER (self), 0); + g_return_val_if_fail (authorization != NULL, 0); + g_return_val_if_fail (callback != NULL, 0); + + priv = MM_AUTH_PROVIDER_GET_PRIVATE (self); + + req = MM_AUTH_PROVIDER_GET_CLASS (self)->create_request (self, + authorization, + owner, + context, + callback, + callback_data, + notify); + g_assert (req); + + sigid = g_signal_connect (req, "result", G_CALLBACK (auth_result_cb), self); + g_object_set_data (G_OBJECT (req), RESULT_SIGID_TAG, GUINT_TO_POINTER (sigid)); + + g_hash_table_insert (priv->requests, req, req); + if (!mm_auth_request_authenticate (req, error)) { + /* Error */ + g_hash_table_remove (priv->requests, req); + return NULL; + } + + return req; +} + +/*****************************************************************************/ + +static void +dispose_auth_request (gpointer data) +{ + MMAuthRequest *req = MM_AUTH_REQUEST (data); + guint sigid; + + sigid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (req), RESULT_SIGID_TAG)); + if (sigid) + g_signal_handler_disconnect (req, sigid); + mm_auth_request_dispose (req); + g_object_unref (req); +} + +static void +mm_auth_provider_init (MMAuthProvider *self) +{ + MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (self); + + priv->requests = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + dispose_auth_request); +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_NAME: + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +#define NULL_PROVIDER "open" + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, NULL_PROVIDER); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + MMAuthProviderPrivate *priv = MM_AUTH_PROVIDER_GET_PRIVATE (object); + + if (priv->process_id) + g_source_remove (priv->process_id); + g_hash_table_destroy (priv->requests); + + G_OBJECT_CLASS (mm_auth_provider_parent_class)->dispose (object); +} + +static void +mm_auth_provider_class_init (MMAuthProviderClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + mm_auth_provider_parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (MMAuthProviderPrivate)); + + /* Virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + class->create_request = real_create_request; + + /* Properties */ + g_object_class_install_property (object_class, PROP_NAME, + g_param_spec_string (MM_AUTH_PROVIDER_NAME, + "Name", + "Provider name", + NULL_PROVIDER, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + |