added implementation for reference APIs along with unit tests
authorImran Zaman <imran.zaman@intel.com>
Fri, 27 Jun 2014 10:30:27 +0000 (13:30 +0300)
committerImran Zaman <imran.zaman@intel.com>
Fri, 27 Jun 2014 10:30:27 +0000 (13:30 +0300)
libgsignon-glib/signon-auth-session.h
libgsignon-glib/signon-identity.c
tests/check_signon.c

index f855cf37a5d4096423fe66730d5fa63278cc1784..620ecd904a217d03a6b2989a3ffe2e949fa59458 100644 (file)
@@ -81,7 +81,6 @@ typedef enum {
 
 /**
  * SignonAuthSessionState:
- *
  * @SIGNON_AUTH_SESSION_STATE_NOT_STARTED: No message.
  * @SIGNON_AUTH_SESSION_STATE_RESOLVING_HOST: Resolving remote server host name.
  * @SIGNON_AUTH_SESSION_STATE_CONNECTING: Connecting to remote server.
index ba42cf4f5de922b5e2812052c39015d6e377b190..39afa7e271c0a589b2192baa0e8ed3ee73facbe1 100644 (file)
@@ -251,6 +251,14 @@ typedef struct _IdentityCredentialsUpdateCbData
     gpointer user_data;
 } IdentityCredentialsUpdateCbData;
 
+typedef struct _IdentityReferenceCbData
+{
+    SignonIdentity *self;
+    gchar *reference;
+    SignonIdentityVoidCb cb;
+    gpointer user_data;
+} IdentityReferenceCbData;
+
 typedef struct _IdentityVoidCbData
 {
     SignonIdentity *self;
@@ -1604,6 +1612,155 @@ identity_void_operation(SignonIdentity *self,
                                     operation_data);
 }
 
+static void
+identity_reference_added_reply (GObject *object, GAsyncResult *res,
+                        gpointer userdata)
+{
+    SsoIdentity *proxy = SSO_IDENTITY (object);
+    gint result;
+    GError *error = NULL;
+    IdentityReferenceCbData *cb_data = (IdentityReferenceCbData *)userdata;
+
+    g_return_if_fail (cb_data != NULL);
+    g_return_if_fail (cb_data->self != NULL);
+    g_return_if_fail (cb_data->self->priv != NULL);
+
+    sso_identity_call_add_reference_finish (proxy, &result, res, &error);
+
+    if (SIGNON_IS_NOT_CANCELLED (error) && cb_data->cb)
+    {
+        (cb_data->cb) (cb_data->self, error, cb_data->user_data);
+    }
+
+    g_clear_error(&error);
+    g_free (cb_data->reference);
+    g_slice_free (IdentityReferenceCbData, cb_data);
+}
+
+static void
+identity_reference_removed_reply (GObject *object, GAsyncResult *res,
+                        gpointer userdata)
+{
+    SsoIdentity *proxy = SSO_IDENTITY (object);
+    gint result;
+    GError *error = NULL;
+    IdentityReferenceCbData *cb_data = (IdentityReferenceCbData *)userdata;
+
+    g_return_if_fail (cb_data != NULL);
+    g_return_if_fail (cb_data->self != NULL);
+    g_return_if_fail (cb_data->self->priv != NULL);
+
+    sso_identity_call_remove_reference_finish (proxy, &result, res, &error);
+
+    if (SIGNON_IS_NOT_CANCELLED (error) && cb_data->cb)
+    {
+        (cb_data->cb) (cb_data->self, error, cb_data->user_data);
+    }
+
+    g_clear_error(&error);
+    g_free (cb_data->reference);
+    g_slice_free (IdentityReferenceCbData, cb_data);
+}
+
+static void
+identity_add_reference_ready_cb(gpointer object, const GError *error,
+    gpointer user_data)
+{
+    g_return_if_fail (SIGNON_IS_IDENTITY (object));
+
+    SignonIdentity *self = SIGNON_IDENTITY (object);
+    SignonIdentityPrivate *priv = self->priv;
+    g_return_if_fail (priv != NULL);
+
+    DEBUG ("%s %d", G_STRFUNC, __LINE__);
+    IdentityReferenceCbData *cb_data = (IdentityReferenceCbData *)user_data;
+    g_return_if_fail (cb_data != NULL);
+
+    if (priv->removed == TRUE)
+    {
+        GError *new_error = g_error_new (signon_error_quark(),
+                                          SIGNON_ERROR_IDENTITY_NOT_FOUND,
+                                         "Already removed from database.");
+        if (cb_data->cb)
+        {
+            (cb_data->cb) (self, new_error, cb_data->user_data);
+        }
+
+        g_error_free (new_error);
+        g_free (cb_data->reference);
+        g_slice_free (IdentityReferenceCbData, cb_data);
+    }
+    else if (error)
+    {
+        DEBUG ("IdentityError: %s", error->message);
+        if (cb_data->cb)
+        {
+            (cb_data->cb) (self, error, cb_data->user_data);
+        }
+
+        g_free (cb_data->reference);
+        g_slice_free (IdentityReferenceCbData, cb_data);
+    }
+    else
+    {
+        g_return_if_fail (priv->proxy != NULL);
+        sso_identity_call_add_reference (priv->proxy,
+                                  cb_data->reference,
+                                  priv->cancellable,
+                                  identity_reference_added_reply,
+                                  cb_data);
+    }
+}
+
+static void
+identity_remove_reference_ready_cb(gpointer object, const GError *error,
+    gpointer user_data)
+{
+    g_return_if_fail (SIGNON_IS_IDENTITY (object));
+
+    SignonIdentity *self = SIGNON_IDENTITY (object);
+    SignonIdentityPrivate *priv = self->priv;
+    g_return_if_fail (priv != NULL);
+
+    DEBUG ("%s %d", G_STRFUNC, __LINE__);
+    IdentityReferenceCbData *cb_data = (IdentityReferenceCbData *)user_data;
+    g_return_if_fail (cb_data != NULL);
+
+    if (priv->removed == TRUE)
+    {
+        GError *new_error = g_error_new (signon_error_quark(),
+                                          SIGNON_ERROR_IDENTITY_NOT_FOUND,
+                                         "Already removed from database.");
+        if (cb_data->cb)
+        {
+            (cb_data->cb) (self, new_error, cb_data->user_data);
+        }
+
+        g_error_free (new_error);
+        g_free (cb_data->reference);
+        g_slice_free (IdentityReferenceCbData, cb_data);
+    }
+    else if (error)
+    {
+        DEBUG ("IdentityError: %s", error->message);
+        if (cb_data->cb)
+        {
+            (cb_data->cb) (self, error, cb_data->user_data);
+        }
+        g_free (cb_data->reference);
+        g_slice_free (IdentityReferenceCbData, cb_data);
+    }
+    else
+    {
+        g_return_if_fail (priv->proxy != NULL);
+        sso_identity_call_remove_reference (priv->proxy,
+                                  cb_data->reference,
+                                  priv->cancellable,
+                                  identity_reference_removed_reply,
+                                  cb_data);
+    }
+}
+
 /**
  * signon_identity_remove:
  * @self: the #SignonIdentity.
@@ -1720,10 +1877,17 @@ void signon_identity_add_reference(SignonIdentity *self,
     SignonIdentityPrivate *priv = self->priv;
     g_return_if_fail (priv != NULL);
 
-    //TODO implement
+    IdentityReferenceCbData *cb_data = g_slice_new0 (IdentityReferenceCbData);
+    cb_data->self = self;
+    cb_data->reference = g_strdup (reference);
+    cb_data->cb = (SignonIdentityVoidCb)cb;
+    cb_data->user_data = user_data;
 
-    if (cb)
-        (cb) (self, NULL, user_data);
+    identity_check_remote_registration (self);
+    _signon_object_call_when_ready (self,
+                                    identity_object_quark(),
+                                    identity_add_reference_ready_cb,
+                                    cb_data);
 }
 
 /**
@@ -1745,10 +1909,17 @@ void signon_identity_remove_reference(SignonIdentity *self,
     SignonIdentityPrivate *priv = self->priv;
     g_return_if_fail (priv != NULL);
 
-    //TODO implement
+    IdentityReferenceCbData *cb_data = g_slice_new0 (IdentityReferenceCbData);
+    cb_data->self = self;
+    cb_data->reference = g_strdup (reference);
+    cb_data->cb = (SignonIdentityVoidCb)cb;
+    cb_data->user_data = user_data;
 
-    if (cb)
-        (cb) (self, NULL, user_data);
+    identity_check_remote_registration (self);
+    _signon_object_call_when_ready (self,
+                                    identity_object_quark(),
+                                    identity_remove_reference_ready_cb,
+                                    cb_data);
 }
 
 /**
index afe291e208b4c9b351db27d494973c7be1250e77..56669158048823c1e24dec9e18e6b2a0e9c653d7 100644 (file)
@@ -956,7 +956,6 @@ START_TEST(test_remove_identity)
     /*
      * Try to remove already removed
      * */
-
     signon_identity_remove(idty2, identity_remove_cb, GINT_TO_POINTER(TRUE));
 
     g_object_unref (idty);
@@ -964,6 +963,109 @@ START_TEST(test_remove_identity)
 }
 END_TEST
 
+static void identity_ref_add_cb(SignonIdentity *self, const GError *error,
+    gpointer user_data)
+{
+    g_warning (" %s ", __func__);
+    if (error)
+    {
+        g_warning ("Error: %s ", error->message);
+        fail_if (user_data == NULL, "There should be no error in callback");
+    }
+    else
+    {
+        g_warning ("No error");
+        fail_if (user_data != NULL, "The callback must return an error");
+    }
+
+    _stop_mainloop ();
+}
+
+static void identity_ref_remove_cb(SignonIdentity *self, const GError *error,
+    gpointer user_data)
+{
+    g_warning (" %s ", __func__);
+    if (error)
+    {
+        g_warning ("Error: %s ", error->message);
+        fail_if (user_data == NULL, "There should be no error in callback");
+    }
+    else
+    {
+        g_warning ("No error");
+        fail_if (user_data != NULL, "The callback must return an error");
+    }
+
+    _stop_mainloop ();
+}
+
+START_TEST(test_referenc_remove_identity)
+{
+    g_debug("%s", G_STRFUNC);
+    SignonIdentity *idty = signon_identity_new ();
+    fail_unless (idty != NULL);
+    fail_unless (SIGNON_IS_IDENTITY (idty),
+                 "Failed to initialize the Identity.");
+
+    /*
+     * Try to remove non-existing reference
+     * */
+    signon_identity_remove_reference(idty, "no-ref", identity_ref_remove_cb,
+        GINT_TO_POINTER(TRUE));
+    _run_mainloop ();
+
+    gint id = new_identity();
+    SignonIdentity *idty2 = signon_identity_new_from_db (id);
+    signon_identity_add_reference(idty2, "app-rem1", identity_ref_add_cb,
+        NULL);
+    _run_mainloop ();
+
+    /*
+     * Try to remove existing reference
+     * */
+    signon_identity_remove_reference(idty2, "app-rem1", identity_remove_cb,
+        NULL);
+    _run_mainloop ();
+
+    g_object_unref (idty);
+    g_object_unref (idty2);
+}
+END_TEST
+
+START_TEST(test_referenc_add_identity)
+{
+    g_debug("%s", G_STRFUNC);
+
+    gint id = new_identity();
+    SignonIdentity *idty = signon_identity_new_from_db (id);
+    fail_unless (idty != NULL);
+    fail_unless (SIGNON_IS_IDENTITY (idty),
+                 "Failed to initialize the Identity.");
+    /*
+     * Try to add non-existing reference
+     * */
+    signon_identity_add_reference(idty, "app1", identity_ref_add_cb,
+        NULL);
+    _run_mainloop ();
+
+    /*
+     * Try to add an existing reference (which replaces the old one)
+     * */
+    signon_identity_add_reference(idty, "app1", identity_ref_add_cb,
+        NULL);
+    _run_mainloop ();
+
+    /*
+     * Try to add another reference
+     * */
+    signon_identity_add_reference(idty, "app2", identity_ref_add_cb,
+        NULL);
+    _run_mainloop ();
+
+    g_object_unref (idty);
+}
+END_TEST
+
 static gboolean _contains(gchar **mechs, gchar *mech)
 {
     gboolean present = FALSE;
@@ -1483,6 +1585,8 @@ signon_suite(void)
     tcase_add_test (tc_core, test_auth_session_process_after_store);
     tcase_add_test (tc_core, test_store_credentials_identity);
     tcase_add_test (tc_core, test_remove_identity);
+    tcase_add_test (tc_core, test_referenc_remove_identity);
+    tcase_add_test (tc_core, test_referenc_add_identity);
     tcase_add_test (tc_core, test_info_identity);
 
     tcase_add_test (tc_core, test_query_identities);