daemon: Fixes to issues found in signonui interaction
authorAmarnath Valluri <amarnath.valluri@linux.intel.com>
Mon, 22 Jul 2013 10:53:51 +0000 (13:53 +0300)
committerAmarnath Valluri <amarnath.valluri@linux.intel.com>
Mon, 22 Jul 2013 17:29:46 +0000 (20:29 +0300)
src/daemon/db/gsignond-db-metadata-database.c
src/daemon/dbus/gsignond-dbus-auth-session-adapter.c
src/daemon/dbus/gsignond-dbus-signonui-adapter.c
src/daemon/gsignond-identity.c
src/daemon/gsignond-signonui-proxy.c

index c880366..5584489 100644 (file)
@@ -1076,6 +1076,17 @@ gsignond_db_metadata_database_update_identity (
         return 0;
     }
 
+    if (!gsignond_identity_info_get_is_identity_new (identity)) {
+        DBG ("Remove old acl and owner list as identity is not new");
+        /* remove acl */
+        _gsignond_db_metadata_database_exec (self,
+                "DELETE FROM ACL WHERE identity_id = %u;", id);
+
+        /* remove owner */
+        _gsignond_db_metadata_database_exec (self,
+                "DELETE FROM OWNER WHERE identity_id = %u;", id);
+    }
+
     /* methods */
     methods = gsignond_identity_info_get_methods (identity);
     if (!_gsignond_db_metadata_database_insert_methods (self, identity,
@@ -1108,16 +1119,6 @@ gsignond_db_metadata_database_update_identity (
         goto finished;
     }
 
-    if (!gsignond_identity_info_get_is_identity_new (identity)) {
-        DBG ("Remove old acl and owner list as identity is not new");
-        /* remove acl */
-        _gsignond_db_metadata_database_exec (self,
-                "DELETE FROM ACL WHERE identity_id = %u;", id);
-
-        /* remove owner */
-        _gsignond_db_metadata_database_exec (self,
-                "DELETE FROM OWNER WHERE identity_id = %u;", id);
-    }
 
     /* ACL insert, this will do basically identity level ACL */
     g_hash_table_iter_init (&method_iter, methods);
index 0b5fd18..f0856b1 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "gsignond/gsignond-log.h"
 #include "gsignond/gsignond-utils.h"
+#include "gsignond/gsignond-error.h"
 #include "gsignond-dbus-auth-session-adapter.h"
 #include "gsignond-dbus.h"
 
@@ -320,8 +321,11 @@ _on_process_done (GSignondSessionData *reply, const GError *error, gpointer user
     self = info->adapter;
     self->priv->is_process_active = FALSE;
 
-    if (error)
-        g_dbus_method_invocation_return_gerror (info->invocation, error);
+    if (error) {
+        DBG("ERROR : %s(%d)", error->message, error->code);
+        GError *dbus_err = gsignond_get_gerror_for_id (error->code, error->message, NULL);
+        g_dbus_method_invocation_take_error (info->invocation, dbus_err);
+    }
     else {
         GVariant *result = gsignond_dictionary_to_variant ((GSignondDictionary *)reply); 
         gsignond_dbus_auth_session_complete_process (
index 155348c..74b887b 100644 (file)
@@ -232,9 +232,13 @@ _on_query_dialog_ready (GObject *proxy, GAsyncResult *res, gpointer user_data)
 
     if (info) {
         if (info->cb) {
-            GVariant *out_params = NULL; g_variant_get (reply, "(@a{sv})", &out_params);
+            GVariant *out_params = NULL;
+
+            if (!error) {
+                g_variant_get (reply, "(@a{sv})", &out_params);
+            }
             ((GSignondDbusSignonuiQueryDialogCb)info->cb) (out_params, error, info->data);
-            g_variant_unref (out_params);
+            if(out_params) g_variant_unref (out_params);
         }
         g_object_unref (info->adapter);
         g_slice_free (_SignonuiDbusInfo, info);
@@ -265,7 +269,7 @@ gsignond_dbus_signonui_adapter_query_dialog (GSignondDbusSignonuiAdapter *adapte
     info->data = user_data;
 
     g_dbus_proxy_call (adapter->priv->proxy, "queryDialog",
-            g_variant_new ("(a{sv})", params), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+            g_variant_new ("(@a{sv})", params), G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL,
             _on_query_dialog_ready, (gpointer)info);
 
     return TRUE;
index f50ad5b..ddd3d8c 100644 (file)
@@ -361,15 +361,22 @@ _on_user_action_completed (GSignondSignonuiData *reply, GError *error, gpointer
         WARN ("UI-Error: %s on identity %d",
               error->message,
               gsignond_identity_info_get_id (priv->info));
+        if (cb_data->session) {
+            GSignondSignonuiData *reply = gsignond_signonui_data_new();
+            gsignond_signonui_data_set_query_error (reply, SIGNONUI_ERROR_GENERAL);
+            gsignond_auth_session_user_action_finished (cb_data->session, reply);
+            gsignond_signonui_data_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) {
@@ -407,7 +414,6 @@ _on_user_action_completed (GSignondSignonuiData *reply, GError *error, gpointer
     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);
 }
@@ -422,7 +428,7 @@ _on_user_action_required (GSignondAuthSession *session, GSignondSignonuiData *ui
     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);
 }
 
 static void
@@ -554,7 +560,6 @@ _on_credentials_updated (GSignondSignonuiData *reply, GError *error, gpointer us
     GSignondIdentity *identity = GSIGNOND_IDENTITY (user_data);
     guint32 id = 0;
     GError *err = NULL;
-    GSignondSignonuiError err_id = 0;
 
     if (error) {
         WARN ("failed to verify user : %s", error->message);
@@ -562,39 +567,43 @@ _on_credentials_updated (GSignondSignonuiData *reply, GError *error, gpointer us
 
         err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED, "Operation cancled");
     }
+    else
+    {
+        GSignondSignonuiError err_id = SIGNONUI_ERROR_NONE;
+        gboolean res = gsignond_signonui_data_get_query_error (reply, &err_id);
 
-    gboolean res = gsignond_signonui_data_get_query_error (reply, &err_id);
-    g_assert (res == TRUE);
+        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,
+        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, 
+                    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);
@@ -629,7 +638,6 @@ gsignond_identity_request_credentials_update (GSignondIdentity *identity,
 
     ui_data = gsignond_signonui_data_new ();
 
-    gsignond_signonui_data_set_query_username (ui_data, FALSE);
     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));
@@ -649,7 +657,6 @@ _on_user_verified (GSignondSignonuiData *reply, GError *error, gpointer user_dat
     GSignondIdentity *identity = GSIGNOND_IDENTITY (user_data);
     gboolean res = FALSE;
     GError *err = NULL;
-    GSignondSignonuiError err_id = 0;
 
     if (error) {
         WARN ("failed to verify user : %s", error->message);
@@ -657,40 +664,42 @@ _on_user_verified (GSignondSignonuiData *reply, GError *error, gpointer user_dat
 
         err = gsignond_get_gerror_for_id (GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED, "Operation cancled");
     }
-
-    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,
+    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 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, 
+                    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);
 }
@@ -726,11 +735,10 @@ gsignond_identity_verify_user (GSignondIdentity *identity,
     }
 
     ui_data = gsignond_signonui_data_new_from_variant (params);
-    gsignond_signonui_data_set_query_username (ui_data, FALSE);
     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_verified, NULL, identity);
 
index ec79fca..6b8ad2d 100644 (file)
@@ -53,6 +53,7 @@ typedef struct {
 struct _GSignondSignonuiProxyPrivate
 {
     GSignondDbusSignonuiAdapter *signonui;
+    guint signonui_timer_id;
     _UIQueryRequest *active_request; /* Active dialog */
     GQueue *request_queue;           /* request queue */
     gboolean is_idle;
@@ -114,6 +115,10 @@ _dispose (GObject *object)
 {
     GSignondSignonuiProxy *self = GSIGNOND_SIGNONUI_PROXY (object);
 
+    if (self->priv->signonui_timer_id) {
+        g_source_remove (self->priv->signonui_timer_id);
+        self->priv->signonui_timer_id = 0;
+    }
     if (self->priv->signonui) {
         g_object_unref (self->priv->signonui);
         self->priv->signonui = NULL;
@@ -151,10 +156,7 @@ gsignond_signonui_proxy_init (GSignondSignonuiProxy *proxy)
 {
     proxy->priv = GSIGNOND_SIGNONUI_PROXY_GET_PRIV (proxy);
 
-    proxy->priv->signonui = gsignond_dbus_signonui_adapter_new ();
-
-    if (proxy->priv->signonui)
-        g_signal_connect_swapped (proxy->priv->signonui, "refresh", G_CALLBACK(_on_refresh_request), proxy);
+    proxy->priv->signonui = NULL;
     proxy->priv->active_request = NULL;
     proxy->priv->request_queue = g_queue_new ();
     proxy->priv->is_idle = TRUE;
@@ -174,18 +176,18 @@ _on_refresh_request (GSignondSignonuiProxy *proxy, gchar *request_id, gpointer u
 }
 
 static void
-_query_dialog_cb (GVariant *reply, GError *error, gpointer user_data)
+_query_dialog_cb_internal (GSignondSignonuiProxy *proxy, GSignondSignonuiData *ui_data, GError *error)
 {
-    GSignondSignonuiProxy *proxy = GSIGNOND_SIGNONUI_PROXY (user_data);
-
     _UIQueryRequest *req = proxy->priv->active_request;
 
-    if (req && req->cb) 
-        req->cb (gsignond_signonui_data_new_from_variant (reply), error, req->userdata);
+    if (req && req->cb) {
+        req->cb (ui_data, error, req->userdata);
+    }
     else if (error) {
         WARN ("UI-Error: %s", error->message);
         g_error_free (error);
     }
+    if (ui_data) gsignond_signonui_data_unref (ui_data);
 
     _ui_query_request_free (req);
 
@@ -195,22 +197,64 @@ _query_dialog_cb (GVariant *reply, GError *error, gpointer user_data)
 }
 
 static void
+_query_dialog_cb (GVariant *reply, GError *error, gpointer user_data)
+{
+    GSignondSignonuiProxy *proxy = GSIGNOND_SIGNONUI_PROXY (user_data);
+    GSignondSignonuiData *ui_data = reply ? gsignond_signonui_data_new_from_variant (reply) : NULL;
+
+     _query_dialog_cb_internal (proxy, ui_data, error);
+}
+
+static gboolean
+_close_ui_connection (gpointer data)
+{
+    GSignondSignonuiProxy *proxy = GSIGNOND_SIGNONUI_PROXY(data);
+    g_return_val_if_fail (proxy, FALSE);
+
+    proxy->priv->signonui_timer_id = 0;
+
+    g_clear_object (&proxy->priv->signonui);
+
+    return FALSE;
+}
+
+static void
 _process_next_request (GSignondSignonuiProxy *proxy)
 {
     _UIQueryRequest *req = g_queue_pop_head (proxy->priv->request_queue);
+    GVariant *params = NULL;
 
     if (!req) {
         proxy->priv->is_idle = TRUE;
         proxy->priv->active_request = NULL;
+        proxy->priv->signonui_timer_id = 
+            g_timeout_add_seconds (10, (GSourceFunc)_close_ui_connection, proxy);
         return;
     }
+    else {
+        if (proxy->priv->signonui_timer_id) {
+            g_source_remove (proxy->priv->signonui_timer_id);
+            proxy->priv->signonui_timer_id = 0;
+        }
+        if (!proxy->priv->signonui)
+            proxy->priv->signonui = gsignond_dbus_signonui_adapter_new ();
+        if (proxy->priv->signonui)
+            g_signal_connect_swapped (proxy->priv->signonui, "refresh",
+                    G_CALLBACK(_on_refresh_request), proxy);
+        else {
+            GSignondSignonuiData *reply = gsignond_signonui_data_new ();
+            gsignond_signonui_data_set_query_error(reply, SIGNONUI_ERROR_NO_SIGNONUI);
+            _query_dialog_cb_internal (proxy, reply, NULL);
+        }
+    }
 
     proxy->priv->active_request = req;
 
     /* update request id */
     gsignond_signonui_data_set_request_id (req->ui_data, G_OBJECT_TYPE_NAME(req->caller));
+    params =  gsignond_signonui_data_to_variant(req->ui_data) ;
     gsignond_dbus_signonui_adapter_query_dialog (proxy->priv->signonui, 
-            gsignond_signonui_data_to_variant(req->ui_data), _query_dialog_cb, proxy);
+            params, _query_dialog_cb, proxy);
 
     proxy->priv->is_idle = FALSE;
 }
@@ -258,7 +302,6 @@ gsignond_signonui_proxy_refresh_dialog (GSignondSignonuiProxy *proxy,
         && proxy->priv->active_request->caller == caller) {
         _UIRefreshRequest *req = _ui_refresh_request_new (cb, userdata);
 
-        /* FIXME: Is it required to set refresh id for refresh data */
         gsignond_signonui_data_set_request_id (ui_data, G_OBJECT_TYPE_NAME(caller));
         gsignond_dbus_signonui_adapter_refresh_dialog (proxy->priv->signonui,
                 gsignond_signonui_data_to_variant (ui_data), _refresh_dialog_cb, req);
@@ -317,11 +360,11 @@ gsignond_signonui_proxy_cancel_request (GSignondSignonuiProxy *proxy,
     if (!element) return FALSE;
     req = element->data;
 
-     if (req->cb) {
-        gsignond_signonui_data_ref (req->ui_data);
-        gsignond_signonui_data_set_query_error(req->ui_data, SIGNONUI_ERROR_CANCELED);
+    if (req->cb) {
+        GSignondSignonuiData *reply = gsignond_signonui_data_new ();
+        gsignond_signonui_data_set_query_error(reply, SIGNONUI_ERROR_CANCELED);
 
-        req->cb (req->ui_data, NULL, req->userdata);
+        req->cb (reply, NULL, req->userdata);
     }
 
     if (cb) cb(NULL, userdata);