GSignondDbusAuthSession *dbus_auth_session;
GSignondAuthSession *session;
gchar *app_context;
+ gboolean is_process_active;
GSignondSecurityContext ctx;
- /* signal handlers */
- guint state_changed_handler_id;
- guint process_result_handler_id;
- guint process_erroror_handler_id;
};
G_DEFINE_TYPE (GSignondDbusAuthSessionAdapter, gsignond_dbus_auth_session_adapter, GSIGNOND_TYPE_DISPOSABLE)
static gboolean _handle_process (GSignondDbusAuthSessionAdapter *, GDBusMethodInvocation *, const GVariant *, const gchar *, gpointer);
static gboolean _handle_cancel (GSignondDbusAuthSessionAdapter *, GDBusMethodInvocation *, gpointer);
-/* signals */
-static void _emit_state_changed (GSignondDbusAuthSessionAdapter *self, gint state, const gchar *message, gpointer user_data);
-
static void
gsignond_dbus_auth_session_adapter_set_property (GObject *object,
guint property_id,
switch (property_id) {
case PROP_SESSION: {
gpointer object = g_value_get_object (value);
- if (object) {
- if (self->priv->session) {
- g_signal_handler_disconnect (self->priv->session, self->priv->state_changed_handler_id);
- }
- self->priv->session = GSIGNOND_AUTH_SESSION ((object));
- self->priv->state_changed_handler_id =
- g_signal_connect_swapped (self->priv->session, "state-changed",
- G_CALLBACK (_emit_state_changed), self);
- }
+ self->priv->session = GSIGNOND_AUTH_SESSION ((object));
break;
}
case PROP_CONNECTION: {
GSignondDbusAuthSessionAdapter *self = GSIGNOND_DBUS_AUTH_SESSION_ADAPTER (object);
if (self->priv->session) {
- if (self->priv->state_changed_handler_id) {
- g_signal_handler_disconnect (self->priv->session, self->priv->state_changed_handler_id);
- self->priv->state_changed_handler_id = 0;
- }
- if (self->priv->process_erroror_handler_id) {
- g_signal_handler_disconnect (self->priv->session, self->priv->process_erroror_handler_id);
- self->priv->process_erroror_handler_id = 0;
- }
- if (self->priv->process_result_handler_id) {
- g_signal_handler_disconnect (self->priv->session, self->priv->process_result_handler_id);
- self->priv->process_result_handler_id = 0;
-
+ if (self->priv->is_process_active) {
gsignond_auth_session_abort_process (self->priv->session);
+ self->priv->is_process_active = FALSE;
}
g_object_unref (self->priv->session);
self->priv->connection = 0;
self->priv->session = 0;
self->priv->app_context = 0;
- self->priv->state_changed_handler_id = 0;
- self->priv->process_result_handler_id = 0;
- self->priv->process_erroror_handler_id = 0;
+ self->priv->is_process_active = FALSE;
self->priv->dbus_auth_session = gsignond_dbus_auth_session_skeleton_new ();
g_signal_connect_swapped (self->priv->dbus_auth_session,
static _AuthSessionDbusInfo*
_auth_session_dbus_info_new (GSignondDbusAuthSessionAdapter *self, GDBusMethodInvocation *invocation)
{
- _AuthSessionDbusInfo *info = g_new0 (_AuthSessionDbusInfo, 1);
+ _AuthSessionDbusInfo *info = g_slice_new0(_AuthSessionDbusInfo);
info->adapter = g_object_ref (self);
info->invocation = g_object_ref (invocation);
g_object_unref (info->adapter);
g_object_unref (info->invocation);
- g_free (info);
+ g_slice_free (_AuthSessionDbusInfo, info);
}
static void
-_on_process_result (_AuthSessionDbusInfo *info, const GSignondSessionData *data, gpointer user_data)
+_emit_state_changed (gint state, const gchar *message, gpointer user_data)
{
GSignondDbusAuthSessionAdapter *self = NULL;
- GVariant *result = NULL;
-
+ _AuthSessionDbusInfo *info = (_AuthSessionDbusInfo*) user_data;
+
if (!info) return ;
self = info->adapter;
- result = gsignond_dictionary_to_variant ((GSignondDictionary *)data);
-
- g_signal_handler_disconnect (self->priv->session, self->priv->process_erroror_handler_id);
- g_signal_handler_disconnect (self->priv->session, self->priv->process_result_handler_id);
- self->priv->process_erroror_handler_id = self->priv->process_result_handler_id = 0;
-
- gsignond_dbus_auth_session_complete_process (
- self->priv->dbus_auth_session, info->invocation, result);
-
- gsignond_disposable_set_auto_dispose (GSIGNOND_DISPOSABLE (self), TRUE);
-
- _auth_session_dbus_info_free (info);
+ gsignond_dbus_auth_session_emit_state_changed (
+ self->priv->dbus_auth_session, state, message);
}
-
static void
-_on_process_error (_AuthSessionDbusInfo *info, const GError *error, gpointer user_data)
+_on_process_done (GSignondSessionData *reply, const GError *error, gpointer user_data)
{
GSignondDbusAuthSessionAdapter *self = NULL;
+ _AuthSessionDbusInfo *info = (_AuthSessionDbusInfo*) user_data;
if (!info) return ;
self = info->adapter;
+ self->priv->is_process_active = FALSE;
- g_signal_handler_disconnect (self->priv->session, self->priv->process_erroror_handler_id);
- g_signal_handler_disconnect (self->priv->session, self->priv->process_result_handler_id);
- self->priv->process_erroror_handler_id = self->priv->process_result_handler_id = 0;
-
- g_dbus_method_invocation_return_gerror (info->invocation, error);
-
+ if (error)
+ g_dbus_method_invocation_return_gerror (info->invocation, error);
+ else {
+ GVariant *result = gsignond_dictionary_to_variant ((GSignondDictionary *)reply);
+ gsignond_dbus_auth_session_complete_process (
+ self->priv->dbus_auth_session, info->invocation, result);
+ }
gsignond_disposable_set_auto_dispose (GSIGNOND_DISPOSABLE (self), TRUE);
_auth_session_dbus_info_free (info);
g_return_val_if_fail (self && GSIGNOND_IS_DBUS_AUTH_SESSION_ADAPTER (self), FALSE);
- info = _auth_session_dbus_info_new (self, invocation);
-
- self->priv->process_erroror_handler_id =
- g_signal_connect_swapped (self->priv->session, "process-error", G_CALLBACK(_on_process_error), info);
- self->priv->process_result_handler_id =
- g_signal_connect_swapped (self->priv->session, "process-result", G_CALLBACK (_on_process_result), info);
-
PREPARE_SECURITY_CONTEXT (self, invocation);
data = (GSignondSessionData *)gsignond_dictionary_new_from_variant ((GVariant *)session_data);
- if (!gsignond_auth_session_process (self->priv->session, data, mechanisms, &self->priv->ctx, &error)) {
+ info = _auth_session_dbus_info_new (self, invocation);
+ self->priv->is_process_active = TRUE;
+ if (!gsignond_auth_session_process (self->priv->session, data, mechanisms,
+ &self->priv->ctx, _on_process_done,
+ _emit_state_changed, info, &error)) {
g_dbus_method_invocation_return_gerror (invocation, error);
g_error_free (error);
- g_signal_handler_disconnect (self->priv->session, self->priv->process_erroror_handler_id);
- g_signal_handler_disconnect (self->priv->session, self->priv->process_result_handler_id);
-
- self->priv->process_erroror_handler_id = self->priv->process_result_handler_id = 0;
-
_auth_session_dbus_info_free (info);
+
+ self->priv->is_process_active = FALSE;
gsignond_disposable_set_keep_in_use (GSIGNOND_DISPOSABLE(self));
}
return TRUE;
}
-static void
-_emit_state_changed (GSignondDbusAuthSessionAdapter *self, gint state, const gchar *message, gpointer user_data)
-{
- gsignond_dbus_auth_session_emit_state_changed (self->priv->dbus_auth_session, state, message);
-}
-
const gchar *
gsignond_dbus_auth_session_adapter_get_object_path (GSignondDbusAuthSessionAdapter *self)
{
static GParamSpec *properties[N_PROPERTIES];
enum {
- SIG_PROCESS_RESULT,
- SIG_PROCESS_ERROR,
SIG_PROCESS_STORE,
SIG_PROCESS_USER_ACTION_REQUIRED,
SIG_PROCESS_REFRESHED,
- SIG_PROCESS_STATE_CHANGED,
-
+
SIG_MAX
};
static guint signals[SIG_MAX] = { 0 };
+typedef struct {
+ GSignondAuthSession *self;
+ ProcessReadyCb ready_cb;
+ StateChangeCb state_change_cb;
+ gpointer userdata;
+} _ProcessData;
+
struct _GSignondAuthSessionPrivate
{
gchar *method;
GSignondSessionData *session_data,
const gchar *mechanism,
const GSignondSecurityContext *ctx,
+ ProcessReadyCb ready_cb,
+ StateChangeCb state_change_cb,
+ gpointer userdata,
GError **error)
{
if (!self || !GSIGNOND_IS_AUTH_SESSION (self)) {
}
}
+ _ProcessData * data = g_slice_new0 (_ProcessData);
+ data->self = self;
+ data->ready_cb = ready_cb;
+ data->state_change_cb = state_change_cb;
+ data->userdata = userdata;
gsignond_plugin_proxy_process(self->priv->proxy, self, session_data,
- mechanism);
+ mechanism, data);
return TRUE;
}
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
- signals[SIG_PROCESS_RESULT] = g_signal_new ("process-result",
- GSIGNOND_TYPE_AUTH_SESSION,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 1,
- GSIGNOND_TYPE_SESSION_DATA);
-
- signals[SIG_PROCESS_ERROR] = g_signal_new ("process-error",
- GSIGNOND_TYPE_AUTH_SESSION,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 1,
- G_TYPE_ERROR);
-
signals[SIG_PROCESS_STORE] = g_signal_new ("process-store",
GSIGNOND_TYPE_AUTH_SESSION,
G_SIGNAL_RUN_LAST,
G_TYPE_NONE,
1,
GSIGNOND_TYPE_SIGNONUI_DATA);
-
- signals[SIG_PROCESS_STATE_CHANGED] = g_signal_new (
- "state-changed",
- GSIGNOND_TYPE_AUTH_SESSION,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 2,
- G_TYPE_INT, G_TYPE_STRING);
-
}
/**
void
gsignond_auth_session_notify_process_result (GSignondAuthSession *iface,
- GSignondSessionData *result)
+ GSignondSessionData *result,
+ gpointer userdata)
{
- g_signal_emit (iface, signals[SIG_PROCESS_RESULT], 0, result);
+ if (!userdata) {
+ WARN("assert (userdata)");
+ return ;
+ }
+ _ProcessData *data = (_ProcessData *)userdata;
+
+ if (data->ready_cb) data->ready_cb (result, NULL, data->userdata);
+
+ g_slice_free (_ProcessData, data);
}
void
gsignond_auth_session_notify_process_error (GSignondAuthSession *iface,
- const GError *error)
+ const GError *error,
+ gpointer userdata)
+{
+ if (!userdata) {
+ WARN("assert (userdata)");
+ return ;
+ }
+ _ProcessData *data = (_ProcessData *)userdata;
+
+ if (data->ready_cb) data->ready_cb (NULL, error, data->userdata);
+
+ g_slice_free (_ProcessData, data);
+}
+
+void
+gsignond_auth_session_notify_state_changed (GSignondAuthSession *self,
+ gint state,
+ const gchar *message,
+ gpointer userdata)
{
- g_signal_emit (iface, signals[SIG_PROCESS_ERROR], 0, error);
+ if (!userdata) {
+ WARN("assert (userdata)");
+ return ;
+ }
+ _ProcessData *data = (_ProcessData *)userdata;
+
+ if (data->state_change_cb) data->state_change_cb (state, message, data->userdata);
}
void
g_signal_emit (self, signals[SIG_PROCESS_REFRESHED], 0, ui_data);
}
-void
-gsignond_auth_session_notify_state_changed (GSignondAuthSession *self,
- gint state,
- const gchar *message)
-{
- g_signal_emit (self, signals[SIG_PROCESS_STATE_CHANGED], 0, state, message);
-}
/**
* gsignond_auth_session_new:
typedef struct _GSignondAuthSession GSignondAuthSession;
typedef struct _GSignondAuthSessionClass GSignondAuthSessionClass;
typedef struct _GSignondAuthSessionPrivate GSignondAuthSessionPrivate;
+typedef void (*ProcessReadyCb) (GSignondSessionData *results, const GError *error, gpointer user_data);
+typedef void (*StateChangeCb) (gint state, const gchar *message, gpointer userdata);
struct _GSignondAuthSession
{
GSignondSessionData *session_data,
const gchar *mechanism,
const GSignondSecurityContext *ctx,
+ ProcessReadyCb ready_cb,
+ StateChangeCb state_change_cb,
+ gpointer userdata,
GError **error);
gboolean
gsignond_auth_session_cancel (GSignondAuthSession *self,
void
gsignond_auth_session_notify_process_result (GSignondAuthSession *iface,
- GSignondSessionData *result);
+ GSignondSessionData *result,
+ gpointer userdata);
void
gsignond_auth_session_notify_process_error (GSignondAuthSession *iface,
- const GError *error);
+ const GError *error,
+ gpointer userdata);
+void
+gsignond_auth_session_notify_state_changed (GSignondAuthSession *self,
+ gint state,
+ const gchar *message,
+ gpointer userdata);
void
gsignond_auth_session_notify_store (GSignondAuthSession *self,
gsignond_auth_session_notify_refreshed (GSignondAuthSession *self,
GSignondSignonuiData *ui_data);
-void
-gsignond_auth_session_notify_state_changed (GSignondAuthSession *self,
- gint state,
- const gchar *message);
-
GSignondAuthSession *
gsignond_auth_session_new (GSignondIdentityInfo *info,
const gchar *method);
G_END_DECLS
-#endif /* _GSGINOND_AUTH_SESSION_H_ */
+#endif /* _GSIGNOND_AUTH_SESSION_H_ */
GSignondPlugin* plugin;
GQueue* session_queue;
GSignondAuthSession* active_session;
+ gpointer active_process_userdata;
gboolean expecting_request;
};
GSignondAuthSession* auth_session;
GSignondSessionData* session_data;
gchar* mechanism;
+ gpointer userdata;
} GSignondProcessData;
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
static GSignondProcessData*
gsignond_process_data_new (GSignondAuthSession* auth_session,
GSignondSessionData *session_data,
- const gchar* mechanism)
+ const gchar* mechanism,
+ gpointer userdata)
{
GSignondProcessData* data = g_slice_new0 (GSignondProcessData);
g_object_ref (auth_session);
data->auth_session = auth_session;
data->session_data = gsignond_dictionary_copy (session_data);
data->mechanism = g_strdup (mechanism);
+ data->userdata = userdata;
return data;
}
priv->plugin = NULL;
priv->session_queue = g_queue_new ();
priv->active_session = NULL;
+ priv->active_process_userdata = NULL;
priv->expecting_request = FALSE;
}
GSignondProcessData* next_data = g_queue_pop_head (priv->session_queue);
if (next_data) {
priv->expecting_request = FALSE;
+ priv->active_process_userdata = next_data->userdata;
priv->active_session = next_data->auth_session;
g_object_ref (priv->active_session);
gsignond_auth_session_notify_state_changed (
priv->active_session,
GSIGNOND_PLUGIN_STATE_STARTED,
- "The request is being processed.");
+ "The request is being processed.",
+ priv->active_process_userdata);
gsignond_plugin_request_initial (priv->plugin,
next_data->session_data,
next_data->mechanism);
void gsignond_plugin_proxy_process (GSignondPluginProxy *self,
GSignondAuthSession *session,
GSignondSessionData *session_data,
- const gchar *mechanism)
+ const gchar *mechanism,
+ gpointer userdata)
{
g_assert (GSIGNOND_IS_PLUGIN_PROXY (self));
g_assert (GSIGNOND_IS_AUTH_SESSION (session));
g_queue_push_tail (priv->session_queue,
gsignond_process_data_new (session,
session_data,
- mechanism));
+ mechanism, userdata));
gsignond_auth_session_notify_state_changed (
session,
GSIGNOND_PLUGIN_STATE_PROCESS_PENDING,
- "The request has been queued.");
+ "The request has been queued.", userdata);
if (priv->active_session == NULL) {
gsignond_plugin_proxy_process_queue (self);
}
gsignond_plugin_cancel (priv->plugin);
g_object_unref (priv->active_session);
priv->active_session = NULL;
+ priv->active_process_userdata = NULL;
gsignond_plugin_proxy_process_queue (self);
} else { /* cancel by de-queue */
GSignondProcessData* data =
GError* error = g_error_new (GSIGNOND_ERROR,
GSIGNOND_ERROR_WRONG_STATE,
"Canceling an unknown session");
- gsignond_auth_session_notify_process_error (session, error);
+ gsignond_auth_session_notify_process_error (session, error, NULL);
g_error_free (error);
return;
}
// This avoids problems if cancel() is called from AuthSession handler
GSignondAuthSession* active_session = priv->active_session;
priv->active_session = NULL;
- gsignond_auth_session_notify_process_result (active_session, result);
+ gsignond_auth_session_notify_process_result (active_session, result, priv->active_process_userdata);
g_object_unref (active_session);
gsignond_plugin_proxy_process_queue (self);
}
}
priv->expecting_request = TRUE;
gsignond_auth_session_notify_process_result (priv->active_session,
- result);
+ result, priv->active_process_userdata);
}
static void
// This avoids problems if cancel() is called from AuthSession handler
GSignondAuthSession *active_session = priv->active_session;
priv->active_session = NULL;
- gsignond_auth_session_notify_process_error (active_session, error);
+ gsignond_auth_session_notify_process_error (active_session, error, priv->active_process_userdata);
g_object_unref (active_session);
gsignond_plugin_proxy_process_queue (self);
}
return;
}
gsignond_auth_session_notify_state_changed (priv->active_session,
- (gint) state, message);
+ (gint) state, message,
+ priv->active_process_userdata);
}
void gsignond_plugin_proxy_process (GSignondPluginProxy *self,
GSignondAuthSession* session,
GSignondSessionData *session_data,
- const gchar *mechanism);
+ const gchar *mechanism,
+ gpointer userdata);
void gsignond_plugin_proxy_user_action_finished (GSignondPluginProxy *self,
GSignondSignonuiData *ui_data);
void gsignond_plugin_proxy_refresh (GSignondPluginProxy *self,