#include "gsignond-identity-enum-types.h"
#include "gsignond-auth-session.h"
#include "gsignond/gsignond-config-dbus.h"
-#include "gsignond/gsignond-signonui.h"
#include "common/gsignond-identity-info-internal.h"
#include "plugins/gsignond-plugin-proxy-factory.h"
G_DEFINE_TYPE (GSignondIdentity, gsignond_identity, G_TYPE_OBJECT);
-static void _on_session_close (gpointer data, GObject *session);
+static void _on_session_dead (gpointer data, GObject *session);
static void _on_refresh_dialog (GSignondAuthSession *session, GSignondSignonuiData *ui_data, gpointer userdata);
+static void _on_process_canceled (GSignondAuthSession *session, GSignondIdentityCbData *cb_data);
+static void _on_user_action_required (GSignondAuthSession *session, GSignondSignonuiData *ui_data, gpointer userdata);
+static void _on_store_token (GSignondAuthSession *session, GSignondDictionary *token_data, gpointer userdata);
#define GSIGNOND_IDENTITY_PRIV(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSIGNOND_TYPE_IDENTITY, GSignondIdentityPrivate)
static void
_release_weak_ref_on_session (gpointer key, gpointer value, gpointer data)
{
- g_object_weak_unref (G_OBJECT (value), _on_session_close, data);
+ GObject *session = G_OBJECT (value);
+ g_signal_handlers_disconnect_by_func (session, G_CALLBACK (_on_user_action_required), data);
+ g_signal_handlers_disconnect_by_func (session, G_CALLBACK (_on_store_token), data);
+ g_object_weak_unref (session, _on_session_dead, data);
}
static void
{
GSignondIdentityCbData *cb_data = (GSignondIdentityCbData *) userdata;
- gsignond_daemon_refresh_dialog (GSIGNOND_DAEMON (cb_data->identity->priv->owner),
- G_OBJECT (cb_data->session), ui_data, _on_dialog_refreshed, userdata);
+ if (!gsignond_daemon_refresh_dialog (GSIGNOND_DAEMON (cb_data->identity->priv->owner),
+ G_OBJECT (cb_data->session), ui_data, _on_dialog_refreshed, userdata)) {
+ WARN ("Dialog Refresh Failed");
+ }
}
static void
GSignondIdentityPrivate *priv = GSIGNOND_IDENTITY_PRIV (cb_data->identity);
GSignondSignonuiError ui_error = SIGNONUI_ERROR_NONE;
+ g_return_if_fail (cb_data && GSIGNOND_IS_AUTH_SESSION (cb_data->session));
+
g_signal_handlers_disconnect_by_func(cb_data->session, _on_refresh_dialog, user_data);
+ g_signal_handlers_disconnect_by_func(cb_data->session, _on_process_canceled, user_data);
if (error) {
WARN ("UI-Error: %s on identity %d",
error->message,
gsignond_identity_info_get_id (priv->info));
+ if (cb_data->session) {
+ GSignondSignonuiData *reply = gsignond_dictionary_new();
+ gsignond_signonui_data_set_query_error (reply, SIGNONUI_ERROR_GENERAL);
+ gsignond_auth_session_user_action_finished (cb_data->session, reply);
+ gsignond_dictionary_unref(reply);
+ }
g_error_free (error);
g_slice_free (GSignondIdentityCbData, cb_data);
return;
}
- if (!gsignond_signonui_data_get_query_error (reply, &ui_error))
+ if (gsignond_signonui_data_get_query_error (reply, &ui_error)
+ && ui_error != SIGNONUI_ERROR_NONE) {
WARN ("signonui error %d for identity %d",
- ui_error,
- gsignond_identity_info_get_id (priv->info));
+ ui_error, gsignond_identity_info_get_id (priv->info));
+ }
if (!gsignond_identity_info_get_validated (priv->info) &&
ui_error == SIGNONUI_ERROR_NONE) {
if (cb_data->session) {
gsignond_auth_session_user_action_finished (cb_data->session, reply);
}
- else if (reply) gsignond_signonui_data_unref (reply);
g_slice_free (GSignondIdentityCbData, cb_data);
}
static void
+_on_process_canceled (GSignondAuthSession *session, GSignondIdentityCbData *cb_data)
+{
+ g_signal_handlers_disconnect_by_func(session, G_CALLBACK(_on_process_canceled), cb_data);
+
+ if (!cb_data) {
+ WARN ("assert (cb_data)");
+ return;
+ }
+ if (!gsignond_daemon_cancel_dialog (
+ cb_data->identity->priv->owner, G_OBJECT(session), NULL, NULL)) {
+ WARN ("Fail to cancel dialog");
+ }
+ g_slice_free (GSignondIdentityCbData, cb_data);
+}
+
+static void
_on_user_action_required (GSignondAuthSession *session, GSignondSignonuiData *ui_data, gpointer userdata)
{
GSignondIdentity *identity = GSIGNOND_IDENTITY (userdata);
cb_data->session = session;
gsignond_daemon_show_dialog (GSIGNOND_DAEMON (identity->priv->owner), G_OBJECT(session),
- ui_data, _on_user_action_completed, _on_refresh_requested_by_ui, userdata);
+ ui_data, _on_user_action_completed, _on_refresh_requested_by_ui, cb_data);
+
+ g_signal_connect (session, "process-canceled", G_CALLBACK(_on_process_canceled), cb_data);
}
static void
}
static void
-_on_session_close (gpointer data, GObject *session)
+_on_session_dead (gpointer data, GObject *session)
{
GSignondIdentity *identity = GSIGNOND_IDENTITY (data);
GSIGNOND_IDENTITY_INFO_NEW_IDENTITY) {
token_data = gsignond_daemon_load_identity_data (identity->priv->owner, identity_id, method);
}
+ if (!token_data) token_data = gsignond_dictionary_new();
session = gsignond_auth_session_new (identity->priv->info, method, token_data);
g_signal_connect (session, "process-store", G_CALLBACK (_on_store_token), identity);
g_hash_table_insert (identity->priv->auth_sessions, g_strdup (method), session);
- g_object_weak_ref (G_OBJECT (session), _on_session_close, identity);
+ g_object_weak_ref (G_OBJECT (session), _on_session_dead, identity);
DBG ("session %p creation for method '%s' complete", session, method);
}
static void
-_on_query_dialog_done (GSignondSignonuiData *reply, GError *error, gpointer user_data)
+_on_credentials_updated (GSignondSignonuiData *reply, GError *error, gpointer user_data)
{
GSignondIdentity *identity = GSIGNOND_IDENTITY (user_data);
guint32 id = 0;
GError *err = NULL;
- GSignondSignonuiError err_id = 0;
if (error) {
- WARN ("failed to verfiy user : %s", error->message);
+ WARN ("failed to verify user : %s", error->message);
g_error_free (error);
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED, "Operation cancled");
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED, "Operation canceled");
}
+ else
+ {
+ GSignondSignonuiError err_id = SIGNONUI_ERROR_NONE;
+ gboolean res = gsignond_signonui_data_get_query_error (reply, &err_id);
+
+ if (!res) {
+ DBG ("No error code set by UI daemon, treating as ERROR_NONE");
+ }
- gboolean res = gsignond_signonui_data_get_query_error (reply, &err_id);
- g_assert (res == TRUE);
-
- if (err_id != SIGNONUI_ERROR_NONE) {
- switch (err_id) {
- case SIGNONUI_ERROR_CANCELED:
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED,
- "Operation cancled");
- break;
- default:
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
+ if (err_id != SIGNONUI_ERROR_NONE) {
+ switch (err_id) {
+ case SIGNONUI_ERROR_CANCELED:
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED,
+ "Operation canceled");
+ break;
+ default:
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
"signon ui returned with error : %d", err_id);
- break;
+ break;
+ }
}
- }
- else {
- const gchar *secret = gsignond_signonui_data_get_password (reply);
+ else {
+ const gchar *secret = gsignond_signonui_data_get_password (reply);
- if (!secret) {
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
+ if (!secret) {
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
"Server internal error occured");
- } else if (identity->priv->info) {
- gsignond_identity_info_set_secret (identity->priv->info, secret) ;
+ } else if (identity->priv->info) {
+ gsignond_identity_info_set_secret (identity->priv->info, secret) ;
- /* Save new secret in db */
- id = gsignond_daemon_store_identity (identity->priv->owner, identity);
- if (!id) err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_STORE_FAILED, "Failed to store secret");
+ /* Save new secret in db */
+ id = gsignond_daemon_store_identity (identity->priv->owner, identity);
+ if (!id) err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_STORE_FAILED, "Failed to store secret");
+ }
}
}
- gsignond_signonui_data_unref (reply);
-
g_signal_emit (identity, signals[SIG_CREDENTIALS_UPDATED], 0 , id, err);
if (err) g_error_free (err);
return FALSE;
}
- ui_data = gsignond_signonui_data_new ();
+ ui_data = gsignond_dictionary_new ();
- gsignond_signonui_data_set_query_username (ui_data, TRUE);
+ gsignond_signonui_data_set_query_password (ui_data, TRUE);
gsignond_signonui_data_set_username (ui_data, gsignond_identity_info_get_username (identity->priv->info));
gsignond_signonui_data_set_caption (ui_data, gsignond_identity_info_get_caption (identity->priv->info));
gsignond_signonui_data_set_message (ui_data, message);
gsignond_daemon_show_dialog (GSIGNOND_DAEMON (identity->priv->owner), G_OBJECT(identity),
- ui_data, _on_query_dialog_done, NULL, identity);
+ ui_data, _on_credentials_updated, NULL, identity);
- gsignond_signonui_data_unref (ui_data);
+ gsignond_dictionary_unref (ui_data);
return TRUE;
}
static void
-_on_user_verfied (GSignondSignonuiData *reply, GError *error, gpointer user_data)
+_on_user_verified (GSignondSignonuiData *reply, GError *error, gpointer user_data)
{
GSignondIdentity *identity = GSIGNOND_IDENTITY (user_data);
gboolean res = FALSE;
GError *err = NULL;
- GSignondSignonuiError err_id = 0;
if (error) {
- WARN ("failed to verfiy user : %s", error->message);
+ WARN ("failed to verify user : %s", error->message);
g_error_free (error);
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED, "Operation cancled");
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED, "Operation canceled");
}
-
- gboolean query_res = gsignond_signonui_data_get_query_error (reply, &err_id);
- g_assert (query_res == TRUE);
-
- if (err_id != SIGNONUI_ERROR_NONE) {
- switch (err_id) {
- case SIGNONUI_ERROR_CANCELED:
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED,
- "Operation cancled");
- break;
- case SIGNONUI_ERROR_FORGOT_PASSWORD:
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_FORGOT_PASSWORD, "Forgot password");
- break;
- default:
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
+ else
+ {
+ GSignondSignonuiError err_id = SIGNONUI_ERROR_NONE;
+ gboolean res = gsignond_signonui_data_get_query_error (reply, &err_id);
+ if (!res) {
+ DBG ("No error code set by UI daemon, treating as ERROR_NONE");
+ }
+ if (err_id != SIGNONUI_ERROR_NONE) {
+ switch (err_id) {
+ case SIGNONUI_ERROR_CANCELED:
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED,
+ "Operation canceled");
+ break;
+ case SIGNONUI_ERROR_FORGOT_PASSWORD:
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_FORGOT_PASSWORD, "Forgot password");
+ break;
+ default:
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
"signon ui returned error : %d", err_id);
- break;
+ break;
+ }
}
- }
- else {
- const gchar *secret = gsignond_signonui_data_get_password (reply);
+ else {
+ const gchar *secret = gsignond_signonui_data_get_password (reply);
- if (!secret) {
- err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
+ if (!secret) {
+ err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_INTERNAL_SERVER,
"Server internal error occured");
- } else if (identity->priv->info) {
- res = g_strcmp0 (secret, gsignond_identity_info_get_secret
+ } else if (identity->priv->info) {
+ res = g_strcmp0 (secret, gsignond_identity_info_get_secret
(identity->priv->info)) == 0;
+ }
}
}
- gsignond_signonui_data_unref (reply);
-
- g_signal_emit (identity, signals[SIG_USER_VERIFIED], 0, res, error);
+ g_signal_emit (identity, signals[SIG_USER_VERIFIED], 0, res, err);
if (err) g_error_free (err);
}
return FALSE;
}
- ui_data = gsignond_signonui_data_new_from_variant (params);
+ ui_data = gsignond_dictionary_new_from_variant (params);
gsignond_signonui_data_set_query_password (ui_data, TRUE);
gsignond_signonui_data_set_username (ui_data, gsignond_identity_info_get_username (identity->priv->info));
gsignond_signonui_data_set_caption (ui_data, gsignond_identity_info_get_caption (identity->priv->info));
-
+
gsignond_daemon_show_dialog (GSIGNOND_DAEMON (identity->priv->owner), G_OBJECT (identity),
- ui_data, _on_user_verfied, NULL, identity);
+ ui_data, _on_user_verified, NULL, identity);
- gsignond_signonui_data_unref (ui_data);
+ gsignond_dictionary_unref (ui_data);
return TRUE;
}