added synchronous API calls for user/group functionalities
authorImran Zaman <imran.zaman@intel.com>
Wed, 4 Dec 2013 13:58:52 +0000 (15:58 +0200)
committerImran Zaman <imran.zaman@intel.com>
Wed, 4 Dec 2013 13:58:52 +0000 (15:58 +0200)
include/gum/gum-group.h
include/gum/gum-user.h
src/lib/gum-group.c
src/lib/gum-user.c
test/lib/client-test.c

index 784ebc7..c08638a 100644 (file)
@@ -75,17 +75,28 @@ gum_group_create (
         gpointer user_data);
 
 GumGroup *
+gum_group_create_sync ();
+
+GumGroup *
 gum_group_get (
         gid_t gid,
         GumGroupCb callback,
         gpointer user_data);
 
 GumGroup *
+gum_group_get_sync (
+        gid_t gid);
+
+GumGroup *
 gum_group_get_by_name (
         const gchar *groupname,
         GumGroupCb callback,
         gpointer user_data);
 
+GumGroup *
+gum_group_get_by_name_sync (
+        const gchar *groupname);
+
 gboolean
 gum_group_add (
         GumGroup *self,
@@ -93,18 +104,30 @@ gum_group_add (
         gpointer user_data);
 
 gboolean
+gum_group_add_sync (
+        GumGroup *self);
+
+gboolean
 gum_group_delete (
         GumGroup *self,
         GumGroupCb callback,
         gpointer user_data);
 
 gboolean
+gum_group_delete_sync (
+        GumGroup *self);
+
+gboolean
 gum_group_update (
         GumGroup *self,
         GumGroupCb callback,
         gpointer user_data);
 
 gboolean
+gum_group_update_sync (
+        GumGroup *self);
+
+gboolean
 gum_group_add_member (
         GumGroup *self,
         uid_t uid,
@@ -113,12 +136,23 @@ gum_group_add_member (
         gpointer user_data);
 
 gboolean
+gum_group_add_member_sync (
+        GumGroup *self,
+        uid_t uid,
+        gboolean add_as_admin);
+
+gboolean
 gum_group_delete_member (
         GumGroup *self,
         uid_t uid,
         GumGroupCb callback,
         gpointer user_data);
 
+gboolean
+gum_group_delete_member_sync (
+        GumGroup *self,
+        uid_t uid);
+
 G_END_DECLS
 
 #endif /* __GUM_GROUP_H_ */
index d8d0892..a7c558b 100644 (file)
@@ -75,17 +75,28 @@ gum_user_create (
         gpointer user_data);
 
 GumUser *
+gum_user_create_sync ();
+
+GumUser *
 gum_user_get (
         uid_t uid,
         GumUserCb callback,
         gpointer user_data);
 
 GumUser *
+gum_user_get_sync (
+        uid_t uid);
+
+GumUser *
 gum_user_get_by_name (
         const gchar *username,
         GumUserCb callback,
         gpointer user_data);
 
+GumUser *
+gum_user_get_by_name_sync (
+        const gchar *username);
+
 gboolean
 gum_user_add (
         GumUser *self,
@@ -93,6 +104,10 @@ gum_user_add (
         gpointer user_data);
 
 gboolean
+gum_user_add_sync (
+        GumUser *self);
+
+gboolean
 gum_user_delete (
         GumUser *self,
         gboolean rem_home_dir,
@@ -100,11 +115,20 @@ gum_user_delete (
         gpointer user_data);
 
 gboolean
+gum_user_delete_sync (
+        GumUser *self,
+        gboolean rem_home_dir);
+
+gboolean
 gum_user_update (
         GumUser *self,
         GumUserCb callback,
         gpointer user_data);
 
+gboolean
+gum_user_update_sync (
+        GumUser *self);
+
 G_END_DECLS
 
 #endif /* __GUM_USER_H_ */
index 9f66cb5..a29678a 100644 (file)
  * Following code snippet demonstrates how to create a new remote group object:
  *
  * |[
- *  GMainLoop *main_loop = NULL;
  *  GumGroup *group = NULL;
  *
- *  main_loop = g_main_loop_new (NULL, FALSE)
- *  group = gum_group_create (_on_group_created, NULL);
+ *  group = gum_group_create_sync ();
  *
- *  // wait for _on_group_created callback and use the object when callback is
- *  // triggered
- *  g_main_loop_run (main_loop);
+ *  // use the object
  *
  *  // destroy the object
  *  g_object_unref (group);
  *
  * Similarly, new group can be added as:
  * |[
- *  GMainLoop *main_loop = NULL;
  *  GumGroup *group = NULL;
  *  gboolean rval = FALSE;
  *
- *  main_loop = g_main_loop_new (NULL, FALSE)
- *  group = gum_group_create (_on_group_created, NULL);
- *
- *  // wait for _on_group_created callback and use the object when callback is
- *  // triggered
- *  g_main_loop_run (main_loop);
+ *  group = gum_group_create_sync ();
  *
  *  // set group properties
  *  g_object_set (G_OBJECT (group), "groupname", "group1", "secret", "123456",
  *   "grouptype", GUM_GROUPTYPE_USER, NULL);
  *
  *  // add group
- *  rval = gum_group_add (user, _on_group_added, NULL);
- *
- *  // wait for _on_group_added callback
- *  g_main_loop_run (main_loop);
+ *  rval = gum_group_add_sync (user);
  *
  *  // destroy the object
  *  g_object_unref (group);
@@ -388,6 +375,78 @@ _create_dbus_group (
     }
 }
 
+static GVariant *
+_get_prop_value (
+        GVariant *props,
+        const gchar *prop)
+{
+    GVariantIter *iter = NULL;
+    GVariant *item = NULL;
+    g_variant_get (props, "(a{sv})",  &iter);
+    while ((item = g_variant_iter_next_value (iter)))  {
+        gchar *key;
+        GVariant *value;
+        g_variant_get (item, "{sv}", &key, &value);
+        if (g_strcmp0 (key, prop) == 0) {
+            g_free (key);
+            return g_variant_ref (value);
+        }
+        g_free (key); key = NULL;
+        g_variant_unref (value); value = NULL;
+    }
+    return NULL;
+}
+
+static gboolean
+_sync_properties (
+        GumGroup *group)
+{
+    GError *error = NULL;
+    GVariant *result = NULL;
+
+    /* load all properties synchronously */
+    result = g_dbus_connection_call_sync (
+            g_dbus_proxy_get_connection (
+                    G_DBUS_PROXY (group->priv->dbus_service)),
+            g_dbus_proxy_get_name (G_DBUS_PROXY (group->priv->dbus_service)),
+            g_dbus_proxy_get_object_path (G_DBUS_PROXY (group->priv->dbus_group)),
+            "org.freedesktop.DBus.Properties",
+            "GetAll",
+            g_variant_new ("(s)",
+                    g_dbus_proxy_get_interface_name (
+                            G_DBUS_PROXY (group->priv->dbus_group))),
+            G_VARIANT_TYPE ("(a{sv})"),
+            G_DBUS_CALL_FLAGS_NONE,
+            -1,
+            group->priv->cancellable,
+            &error);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        return FALSE;
+    }
+
+    if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(a{sv})"))) {
+        guint n_properties = 0, ind = 0;
+        GParamSpec **properties = g_object_class_list_properties (
+                G_OBJECT_GET_CLASS(group), &n_properties);
+        for (ind=0; ind < n_properties; ind++) {
+            GParamSpec *pspec = properties[ind];
+            GVariant *prop = _get_prop_value (result,  pspec->name);
+            if (prop != NULL) {
+                g_dbus_proxy_set_cached_property (
+                        G_DBUS_PROXY (group->priv->dbus_group), pspec->name,
+                        prop);
+            }
+        }
+        g_free (properties);
+    }
+    g_variant_unref (result);
+    return TRUE;
+}
+
 static void
 _on_new_group_cb (
         GObject *object,
@@ -609,6 +668,41 @@ gum_group_create (
 }
 
 /**
+ * gum_group_create_sync:
+ *
+ * This method creates a new remote group object over the DBus synchronously.
+ *
+ * Returns: (transfer full): #GumGroup newly created object
+ */
+GumGroup *
+gum_group_create_sync ()
+{
+    GError *error = NULL;
+    gchar *object_path = NULL;
+
+    GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
+    g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
+
+    if (gum_dbus_group_service_call_create_new_group_sync (
+            group->priv->dbus_service, &object_path, group->priv->cancellable,
+                &error)) {
+        _create_dbus_group (group, object_path, error);
+    }
+
+    g_free (object_path);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        g_object_unref (group);
+        group = NULL;
+    }
+
+    return group;
+}
+
+/**
  * gum_group_get:
  * @gid: group id for the group
  * @callback: #GumGroupCb to be invoked when group object is fetched
@@ -635,6 +729,44 @@ gum_group_get (
     return group;
 }
 
+
+/**
+ * gum_group_get_sync:
+ * @gid: group id for the group
+ *
+ * This method gets the group object attached to gid over the DBus
+ * synchronously.
+ *
+ * Returns: (transfer full): #GumGroup object
+ */
+GumGroup *
+gum_group_get_sync (
+        gid_t gid)
+{
+    GError *error = NULL;
+    gchar *object_path = NULL;
+
+    GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
+    g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
+
+    if (gum_dbus_group_service_call_get_group_sync (
+            group->priv->dbus_service, gid, &object_path,
+            group->priv->cancellable, &error)) {
+        _create_dbus_group (group, object_path, error);
+    }
+
+    g_free (object_path);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        g_object_unref (group);
+        group = NULL;
+    }
+    return group;
+}
+
 /**
  * gum_group_get_by_name:
  * @groupname: name of the group
@@ -668,6 +800,48 @@ gum_group_get_by_name (
 }
 
 /**
+ * gum_group_get_by_name_sync:
+ * @groupname: name of the group
+ *
+ * This method gets the group object attached to groupname over the DBus
+ * synchronously.
+ *
+ * Returns: (transfer full): #GumGroup object
+ */
+GumGroup *
+gum_group_get_by_name_sync (
+        const gchar *groupname)
+{
+    GError *error = NULL;
+    gchar *object_path = NULL;
+
+    GumGroup *group = GUM_GROUP (g_object_new (GUM_TYPE_GROUP, NULL));
+    g_return_val_if_fail (group->priv->dbus_service != NULL, NULL);
+
+    if (!groupname) {
+        WARN ("groupname not specified");
+        return NULL;
+    }
+
+    if (gum_dbus_group_service_call_get_group_by_name_sync (
+            group->priv->dbus_service, groupname, &object_path,
+            group->priv->cancellable, &error)) {
+        _create_dbus_group (group, object_path, error);
+    }
+
+    g_free (object_path);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        g_object_unref (group);
+        group = NULL;
+    }
+    return group;
+}
+
+/**
  * gum_group_add:
  * @self: #GumGroup object to be added; object should have valid
  * #GumGroup:groupname and #GumGroup:grouptype properties.
@@ -702,6 +876,43 @@ gum_group_add (
 }
 
 /**
+ * gum_group_add_sync:
+ * @self: #GumGroup object to be added; object should have valid
+ * #GumGroup:groupname and #GumGroup:grouptype properties.
+ *
+ * This method adds the group over the DBus synchronously.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_group_add_sync (
+        GumGroup *self)
+{
+    GError *error = NULL;
+    gid_t gid = GUM_GROUP_INVALID_GID;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
+
+    if (!self->priv->dbus_group) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_group_call_add_group_sync (self->priv->dbus_group,
+            GUM_GROUP_INVALID_GID, &gid, self->priv->cancellable, &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+
+    return _sync_properties (self);
+}
+
+/**
  * gum_group_delete:
  * @self: #GumGroup object to be deleted; object should have valid
  * #GumGroup:gid property.
@@ -735,6 +946,42 @@ gum_group_delete (
 }
 
 /**
+ * gum_group_delete_sync:
+ * @self: #GumGroup object to be deleted; object should have valid
+ * #GumGroup:gid property.
+ *
+ * This method deletes the group over the DBus synchronously.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_group_delete_sync (
+        GumGroup *self)
+{
+    GError *error = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
+
+    if (!self->priv->dbus_group) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_group_call_delete_group_sync (self->priv->dbus_group,
+            self->priv->cancellable, &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/**
  * gum_group_update:
  * @self: #GumGroup object to be updated; object should have valid
  * #GumGroup:gid property.
@@ -769,6 +1016,43 @@ gum_group_update (
 }
 
 /**
+ * gum_group_update_sync:
+ * @self: #GumGroup object to be updated; object should have valid
+ * #GumGroup:gid property.
+ *
+ * This method updates the group over the DBus synchronously. The properties
+ * which can be updated are: secret.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_group_update_sync (
+        GumGroup *self)
+{
+    GError *error = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
+
+    if (!self->priv->dbus_group) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_group_call_update_group_sync (self->priv->dbus_group,
+            self->priv->cancellable, &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+
+    return _sync_properties (self);
+}
+
+/**
  * gum_group_add_member:
  * @self: #GumGroup object where new member is to be added; object should have
  * valid #GumGroup:gid property.
@@ -808,6 +1092,47 @@ gum_group_add_member (
 }
 
 /**
+ * gum_group_add_member_sync:
+ * @self: #GumGroup object where new member is to be added; object should have
+ * valid #GumGroup:gid property.
+ * @uid: user id of the member to be added to the group
+ * @add_as_admin: user will be added with admin privileges for the group if set
+ * to TRUE
+ *
+ * This method adds new member to the group over the DBus synchronously.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_group_add_member_sync (
+        GumGroup *self,
+        uid_t uid,
+        gboolean add_as_admin)
+{
+    GError *error = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
+
+    if (!self->priv->dbus_group) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_group_call_add_member_sync (self->priv->dbus_group, uid,
+            add_as_admin, self->priv->cancellable, &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/**
  * gum_group_delete_member:
  * @self: #GumGroup object where member is to be deleted from; object should
  * have valid #GumGroup:gid property.
@@ -841,3 +1166,41 @@ gum_group_delete_member (
             self->priv->cancellable, _on_group_delete_member_cb, self);
     return TRUE;
 }
+
+/**
+ * gum_group_delete_member_sync:
+ * @self: #GumGroup object where member is to be deleted from; object should
+ * have valid #GumGroup:gid property.
+ * @uid: user id of the member to be deleted from the group
+ *
+ * This method deletes new member from the group over the DBus synchronously.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_group_delete_member_sync (
+        GumGroup *self,
+        uid_t uid)
+{
+    GError *error = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_GROUP (self), FALSE);
+
+    if (!self->priv->dbus_group) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_group_call_delete_member_sync (self->priv->dbus_group, uid,
+            self->priv->cancellable, &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+
+    return TRUE;
+}
index 59a9d54..271a73c 100644 (file)
  * Following code snippet demonstrates how to create a new remote user object:
  *
  * |[
- *  GMainLoop *main_loop = NULL;
  *  GumUser *user = NULL;
  *
- *  main_loop = g_main_loop_new (NULL, FALSE)
- *  user = gum_user_create (_on_user_created, NULL);
+ *  user = gum_user_create_sync ();
  *
- *  // wait for _on_user_created callback and use the object when callback is
- *  // triggered
- *  g_main_loop_run (main_loop);
+ *  // use the object
  *
  *  // destroy the object
  *  g_object_unref (user);
  *
  * Similarly, new user can be added as:
  * |[
- *  GMainLoop *main_loop = NULL;
  *  GumUser *user = NULL;
  *  gboolean rval = FALSE;
  *
- *  main_loop = g_main_loop_new (NULL, FALSE)
- *  user = gum_user_create (_on_user_created, NULL);
- *
- *  // wait for _on_user_created callback and use the object when callback is
- *  // triggered
- *  g_main_loop_run (main_loop);
+ *  user = gum_user_create_sync ();
  *
  *  // set user properties
  *  g_object_set (G_OBJECT (user), "username", "user1", "secret", "123456",
  *   "usertype", GUM_USERTYPE_NORMAL, NULL);
  *
  *  // add user
- *  rval = gum_user_add (user, _on_user_added, NULL);
- *
- *  // wait for _on_user_added callback
- *  g_main_loop_run (main_loop);
+ *  rval = gum_user_add_sync (user);
  *
  *  // destroy the object
  *  g_object_unref (user);
@@ -514,6 +501,78 @@ _create_dbus_user (
     }
 }
 
+static GVariant *
+_get_prop_value (
+        GVariant *props,
+        const gchar *prop)
+{
+    GVariantIter *iter = NULL;
+    GVariant *item = NULL;
+    g_variant_get (props, "(a{sv})",  &iter);
+    while ((item = g_variant_iter_next_value (iter)))  {
+        gchar *key;
+        GVariant *value;
+        g_variant_get (item, "{sv}", &key, &value);
+        if (g_strcmp0 (key, prop) == 0) {
+            g_free (key);
+            return g_variant_ref (value);
+        }
+        g_free (key); key = NULL;
+        g_variant_unref (value); value = NULL;
+    }
+    return NULL;
+}
+
+static gboolean
+_sync_properties (
+        GumUser *user)
+{
+    GError *error = NULL;
+    GVariant *result = NULL;
+
+    /* load all properties synchronously */
+    result = g_dbus_connection_call_sync (
+            g_dbus_proxy_get_connection (
+                    G_DBUS_PROXY (user->priv->dbus_service)),
+            g_dbus_proxy_get_name (G_DBUS_PROXY (user->priv->dbus_service)),
+            g_dbus_proxy_get_object_path (G_DBUS_PROXY (user->priv->dbus_user)),
+            "org.freedesktop.DBus.Properties",
+            "GetAll",
+            g_variant_new ("(s)",
+                    g_dbus_proxy_get_interface_name (
+                            G_DBUS_PROXY (user->priv->dbus_user))),
+            G_VARIANT_TYPE ("(a{sv})"),
+            G_DBUS_CALL_FLAGS_NONE,
+            -1,
+            user->priv->cancellable,
+            &error);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        return FALSE;
+    }
+
+    if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(a{sv})"))) {
+        guint n_properties = 0, ind = 0;
+        GParamSpec **properties = g_object_class_list_properties (
+                G_OBJECT_GET_CLASS(user), &n_properties);
+        for (ind=0; ind < n_properties; ind++) {
+            GParamSpec *pspec = properties[ind];
+            GVariant *prop = _get_prop_value (result,  pspec->name);
+            if (prop != NULL) {
+                g_dbus_proxy_set_cached_property (
+                        G_DBUS_PROXY (user->priv->dbus_user), pspec->name,
+                        prop);
+            }
+        }
+        g_free (properties);
+    }
+    g_variant_unref (result);
+    return TRUE;
+}
+
 static void
 _on_new_user_cb (
         GObject *object,
@@ -691,6 +750,41 @@ gum_user_create (
 }
 
 /**
+ * gum_user_create_sync:
+ *
+ * This method creates a new remote user object over the DBus synchronously.
+ *
+ * Returns: (transfer full): #GumUser newly created object
+ */
+GumUser *
+gum_user_create_sync ()
+{
+    GError *error = NULL;
+    gchar *object_path = NULL;
+
+    GumUser *user = GUM_USER (g_object_new (GUM_TYPE_USER, NULL));
+    g_return_val_if_fail (user->priv->dbus_service != NULL, NULL);
+
+    if (gum_dbus_user_service_call_create_new_user_sync (
+                user->priv->dbus_service, &object_path, user->priv->cancellable,
+                &error)) {
+        _create_dbus_user (user, object_path, error);
+    }
+
+    g_free (object_path);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        g_object_unref (user);
+        user = NULL;
+    }
+
+    return user;
+}
+
+/**
  * gum_user_get:
  * @uid: user id for the user
  * @callback: #GumUserCb to be invoked when user object is fetched
@@ -718,6 +812,43 @@ gum_user_get (
 }
 
 /**
+ * gum_user_get_sync:
+ * @uid: user id for the user
+ *
+ * This method gets the user object attached to uid over the DBus
+ * synchronously.
+ *
+ * Returns: (transfer full): #GumUser object
+ */
+GumUser *
+gum_user_get_sync (
+        uid_t uid)
+{
+    GError *error = NULL;
+    gchar *object_path = NULL;
+
+    GumUser *user = GUM_USER (g_object_new (GUM_TYPE_USER, NULL));
+    g_return_val_if_fail (user->priv->dbus_service != NULL, NULL);
+
+    if (gum_dbus_user_service_call_get_user_sync (user->priv->dbus_service,
+            uid, &object_path, user->priv->cancellable, &error)) {
+        _create_dbus_user (user, object_path, error);
+    }
+
+    g_free (object_path);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        g_object_unref (user);
+        user = NULL;
+    }
+
+    return user;
+}
+
+/**
  * gum_user_get_by_name:
  * @username: name of the user
  * @callback: #GumUserCb to be invoked when user object is fetched
@@ -749,6 +880,48 @@ gum_user_get_by_name (
 }
 
 /**
+ * gum_user_get_by_name_sync:
+ * @username: name of the user
+ *
+ * This method gets the user object attached to username over the DBus
+ * synchronously.
+ *
+ * Returns: (transfer full): #GumUser object
+ */
+GumUser *
+gum_user_get_by_name_sync (
+        const gchar *username)
+{
+    GError *error = NULL;
+    gchar *object_path = NULL;
+
+    GumUser *user = GUM_USER (g_object_new (GUM_TYPE_USER, NULL));
+    g_return_val_if_fail (user->priv->dbus_service != NULL, NULL);
+    if (!username) {
+        WARN ("username not specified");
+        return NULL;
+    }
+
+    if (gum_dbus_user_service_call_get_user_by_name_sync (
+            user->priv->dbus_service, username, &object_path,
+            user->priv->cancellable,  &error)) {
+        _create_dbus_user (user, object_path, error);
+    }
+
+    g_free (object_path);
+
+    if (error) {
+        DBG ("Failed with error %d:%s", error->code, error->message);
+        g_error_free (error);
+        error = NULL;
+        g_object_unref (user);
+        user = NULL;
+    }
+
+    return user;
+}
+
+/**
  * gum_user_add:
  * @self: #GumUser object to be added; object should have either valid
  * #GumUser:username or #GumUser:nickname in addition to valid
@@ -783,6 +956,44 @@ gum_user_add (
 }
 
 /**
+ * gum_user_add_sync:
+ * @self: #GumUser object to be added; object should have either valid
+ * #GumUser:username or #GumUser:nickname in addition to valid
+ * #GumUser:usertype.
+ *
+ * This method adds the user over the DBus synchronously.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_user_add_sync (
+        GumUser *self)
+{
+    GError *error = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_USER (self), FALSE);
+    uid_t uid = GUM_USER_INVALID_UID;
+
+    if (!self->priv->dbus_user) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_user_call_add_user_sync (
+            self->priv->dbus_user, &uid, self->priv->cancellable,  &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+
+    return _sync_properties (self);
+}
+
+/**
  * gum_user_delete:
  * @self: #GumUser object to be deleted; object should have valid #GumUser:uid
  * property.
@@ -818,6 +1029,45 @@ gum_user_delete (
 }
 
 /**
+ * gum_user_delete_sync:
+ * @self: #GumUser object to be deleted; object should have valid #GumUser:uid
+ * property.
+ * @rem_home_dir: deletes home directory of the user if set to TRUE
+ *
+ * This method deletes the user over the DBus synchronously.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_user_delete_sync (
+        GumUser *self,
+        gboolean rem_home_dir)
+{
+    GError *error = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_USER (self), FALSE);
+
+    if (!self->priv->dbus_user) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_user_call_delete_user_sync (
+            self->priv->dbus_user, rem_home_dir, self->priv->cancellable,
+            &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/**
  * gum_user_update:
  * @self: #GumUser object to be updated; object should have valid #GumUser:uid
  * property.
@@ -850,3 +1100,40 @@ gum_user_update (
             self->priv->cancellable, _on_user_update_cb, self);
     return TRUE;
 }
+
+/**
+ * gum_user_update_sync:
+ * @self: #GumUser object to be updated; object should have valid #GumUser:uid
+ * property.
+ *
+ * This method updates the user over the DBus synchronously. The properties
+ * which can be updated are: secret, realname, office, officephone, homephone
+ * and shell.
+ *
+ * Returns: returns TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gum_user_update_sync (
+        GumUser *self)
+{
+    GError *error = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_USER (self), FALSE);
+
+    if (!self->priv->dbus_user) {
+        DBG ("Remote dbus object not valid");
+        return FALSE;
+    }
+
+    if (!gum_dbus_user_call_update_user_sync (
+            self->priv->dbus_user, self->priv->cancellable, &error)) {
+        if (error) {
+            DBG ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        }
+        return FALSE;
+    }
+    return _sync_properties (self);
+}
index 888f0c1..7698c27 100644 (file)
@@ -339,6 +339,10 @@ START_TEST (test_create_new_user)
 
     g_object_unref (user);
     g_object_unref (user2);
+
+    user2 = gum_user_create_sync ();
+    fail_if (user2 == NULL, "failed to create new user sync");
+    g_object_unref (user2);
 }
 END_TEST
 
@@ -378,6 +382,17 @@ START_TEST(test_add_user)
     _run_mainloop ();
 
     g_object_unref (user);
+
+    /* case 4: use sync method to add user*/
+    user = gum_user_create_sync ();
+    fail_if (user == NULL, "failed to create new user");
+
+    g_object_set (G_OBJECT (user), "username", "test_adduser2",
+            "secret", "123456", "usertype", GUM_USERTYPE_NORMAL, NULL);
+    rval = gum_user_add_sync (user);
+    fail_if (rval == FALSE, "failed to add user sync");
+
+    g_object_unref (user);
 }
 END_TEST
 
@@ -415,6 +430,25 @@ START_TEST(test_get_user_by_uid)
     _run_mainloop ();
 
     g_object_unref (user);
+
+    /* case 3: get user sync */
+    user = gum_user_create_sync ();
+    fail_if (user == NULL, "failed to create new user");
+
+    g_object_set (G_OBJECT (user), "username", "test_getuser2",
+            "secret", "123456", "usertype", GUM_USERTYPE_NORMAL, NULL);
+    rval = gum_user_add_sync (user);
+    fail_if (rval == FALSE, "failed to add user sync");
+
+    g_object_get (G_OBJECT (user), "uid", &uid, NULL);
+    fail_if (uid == GUM_USER_INVALID_UID, "Invalid uid for the user");
+
+    g_object_unref (user);
+
+    user = gum_user_get_sync (uid);
+    fail_if (user == NULL, "failed to get user sync");
+
+    g_object_unref (user);
 }
 END_TEST
 
@@ -449,6 +483,20 @@ START_TEST(test_get_user_by_name)
     _run_mainloop ();
 
     g_object_unref (user);
+
+    /* case 3: get user sync */
+    user = gum_user_create_sync ();
+    fail_if (user == NULL, "failed to create new user");
+
+    g_object_set (G_OBJECT (user), "username", "test_getuser_byname2",
+            "secret", "123456", "usertype", GUM_USERTYPE_NORMAL, NULL);
+    rval = gum_user_add_sync (user);
+    fail_if (rval == FALSE, "failed to add user sync");
+    g_object_unref (user);
+
+    user = gum_user_get_by_name_sync ("test_getuser_byname2");
+    fail_if (user == NULL, "failed to get user by name sync");
+    g_object_unref (user);
 }
 END_TEST
 
@@ -494,6 +542,20 @@ START_TEST (test_delete_user)
     fail_if (rval == FALSE, "failed to delete user");
     _run_mainloop ();
     g_object_unref (user);
+
+    /* case 4: use sync method to delete user*/
+    user = gum_user_create_sync ();
+    fail_if (user == NULL, "failed to create new user");
+
+    g_object_set (G_OBJECT (user), "username", "test_deluser3",
+            "secret", "123456", "usertype", GUM_USERTYPE_NORMAL, NULL);
+    rval = gum_user_add_sync (user);
+    fail_if (rval == FALSE, "failed to add user sync");
+
+    rval = gum_user_delete_sync (user, TRUE);
+    fail_if (rval == FALSE, "failed to delete user");
+    g_object_unref (user);
+
 }
 END_TEST
 
@@ -525,6 +587,20 @@ START_TEST (test_update_user)
     fail_if (rval == FALSE, "failed to update user");
     _run_mainloop ();
     g_object_unref (user);
+
+    /* case 3: use sync method to update user*/
+    user = gum_user_create_sync ();
+    fail_if (user == NULL, "failed to create new user");
+
+    g_object_set (G_OBJECT (user), "username", "test_upuser2",
+            "secret", "123456", "usertype", GUM_USERTYPE_NORMAL, NULL);
+    rval = gum_user_add_sync (user);
+    fail_if (rval == FALSE, "failed to add user sync");
+
+    g_object_set (G_OBJECT (user), "secret", "23456", NULL);
+    rval = gum_user_update_sync (user);
+    fail_if (rval == FALSE, "failed to update user");
+    g_object_unref (user);
 }
 END_TEST
 
@@ -537,17 +613,21 @@ START_TEST (test_create_new_group)
     GumGroup *group = NULL, *group2 = NULL;
 
     group = gum_group_create (_on_group_op_success, NULL);
-    fail_if (group == NULL, "failed to create new user");
+    fail_if (group == NULL, "failed to create new group");
 
     _run_mainloop ();
 
     group2 = gum_group_create (_on_group_op_success, NULL);
-    fail_if (group2 == NULL, "failed to create new user2");
+    fail_if (group2 == NULL, "failed to create new group2");
 
     _run_mainloop ();
 
     g_object_unref (group);
     g_object_unref (group2);
+
+    group2 = gum_group_create_sync ();
+    fail_if (group2 == NULL, "failed to create new group2 sync");
+    g_object_unref (group2);
 }
 END_TEST
 
@@ -575,10 +655,21 @@ START_TEST(test_add_group)
     _run_mainloop ();
 
     g_object_unref (group);
+
+    /* case 3: add group sync */
+    group = gum_group_create_sync ();
+    fail_if (group == NULL, "failed to create new group");
+
+    g_object_set (G_OBJECT (group), "groupname", "test_addgroup2",
+            "secret", "123456", "grouptype", GUM_GROUPTYPE_USER, NULL);
+    rval = gum_group_add_sync (group);
+    fail_if (rval == FALSE, "failed to add already existing group");
+
+    g_object_unref (group);
 }
 END_TEST
 
-START_TEST(test_get_group_by_uid)
+START_TEST(test_get_group_by_gid)
 {
     GumGroup *group = NULL;
     gid_t gid = GUM_GROUP_INVALID_GID;
@@ -612,6 +703,24 @@ START_TEST(test_get_group_by_uid)
     _run_mainloop ();
 
     g_object_unref (group);
+
+    /* case 3: get group sync */
+    group = gum_group_create_sync ();
+    fail_if (group == NULL, "failed to create new group");
+
+    g_object_set (G_OBJECT (group), "groupname", "test_getgroup2",
+            "secret", "123456", "grouptype", GUM_GROUPTYPE_USER, NULL);
+    rval = gum_group_add_sync (group);
+    fail_if (rval == FALSE, "failed to add group");
+
+    g_object_get (G_OBJECT (group), "gid", &gid, NULL);
+    fail_if (gid == GUM_GROUP_INVALID_GID, "Invalid gid for the group");
+    g_object_unref (group);
+
+    group = gum_group_get_sync (gid);
+    fail_if (group == NULL, "failed to get group");
+
+    g_object_unref (group);
 }
 END_TEST
 
@@ -647,6 +756,22 @@ START_TEST(test_get_group_by_name)
     _run_mainloop ();
 
     g_object_unref (group);
+
+    /* case 3: get group by name sync */
+    group = gum_group_create_sync ();
+    fail_if (group == NULL, "failed to create new group");
+
+    g_object_set (G_OBJECT (group), "groupname", "test_getgroup_byname2",
+            "secret", "123456", "grouptype", GUM_GROUPTYPE_USER, NULL);
+    rval = gum_group_add_sync (group);
+    fail_if (rval == FALSE, "failed to add group");
+    g_object_unref (group);
+
+    group = gum_group_get_by_name_sync ("test_getgroup_byname2");
+    fail_if (group == NULL, "failed to get group by name sync");
+
+    g_object_unref (group);
+
 }
 END_TEST
 
@@ -677,6 +802,20 @@ START_TEST (test_delete_group)
     fail_if (rval == FALSE, "failed to delete group");
     _run_mainloop ();
     g_object_unref (group);
+
+    /* case 2: delete group sync */
+    group = gum_group_create_sync ();
+    fail_if (group == NULL, "failed to create new group");
+
+    g_object_set (G_OBJECT (group), "groupname", "test_delgroup2",
+            "secret", "123456", "grouptype", GUM_GROUPTYPE_USER, NULL);
+    rval = gum_group_add_sync (group);
+    fail_if (rval == FALSE, "failed to add group");
+
+    rval = gum_group_delete_sync (group);
+    fail_if (rval == FALSE, "failed to delete group sync");
+
+    g_object_unref (group);
 }
 END_TEST
 
@@ -708,6 +847,21 @@ START_TEST (test_update_group)
     fail_if (rval == FALSE, "failed to update group");
     _run_mainloop ();
     g_object_unref (group);
+
+    /* case 3: update group sync */
+    group = gum_group_create_sync ();
+    fail_if (group == NULL, "failed to create new group");
+
+    g_object_set (G_OBJECT (group), "groupname", "test_upgroup2",
+            "secret", "123456", "grouptype", GUM_GROUPTYPE_USER, NULL);
+    rval = gum_group_add_sync (group);
+    fail_if (rval == FALSE, "failed to add group");
+
+    g_object_set (G_OBJECT (group), "secret", "23456", NULL);
+    rval = gum_group_update_sync (group);
+    fail_if (rval == FALSE, "failed to update group");
+
+    g_object_unref (group);
 }
 END_TEST
 
@@ -753,6 +907,22 @@ START_TEST (test_add_group_member)
     _run_mainloop ();
 
     g_object_unref (user);
+
+    /* case 3: add group mem sync */
+    user = gum_user_create_sync ();
+    fail_if (user == NULL, "failed to create new user");
+
+    g_object_set (G_OBJECT (user), "username", "test_addgrpmem_user2",
+            "secret", "123456", "usertype", GUM_USERTYPE_NORMAL, NULL);
+    rval = gum_user_add_sync (user);
+    fail_if (rval == FALSE, "failed to add user");
+
+    g_object_get (G_OBJECT (user), "uid", &uid, NULL);
+
+    rval = gum_group_add_member_sync (group, uid, TRUE);
+    fail_if (rval == FALSE, "failed to add group member sync");
+
+    g_object_unref (user);
     g_object_unref (group);
 }
 END_TEST
@@ -803,6 +973,25 @@ START_TEST (test_delete_group_member)
     _run_mainloop ();
 
     g_object_unref (user);
+
+    /* case 3: add group mem sync */
+    user = gum_user_create_sync ();
+    fail_if (user == NULL, "failed to create new user");
+
+    g_object_set (G_OBJECT (user), "username", "test_delgrpmem_user2",
+            "secret", "123456", "usertype", GUM_USERTYPE_NORMAL, NULL);
+    rval = gum_user_add_sync (user);
+    fail_if (rval == FALSE, "failed to add user");
+
+    g_object_get (G_OBJECT (user), "uid", &uid, NULL);
+
+    rval = gum_group_add_member_sync (group, uid, TRUE);
+    fail_if (rval == FALSE, "failed to add group member sync");
+
+    rval = gum_group_delete_member_sync (group, uid);
+    fail_if (rval == FALSE, "failed to delete group member sync");
+
+    g_object_unref (user);
     g_object_unref (group);
 }
 END_TEST
@@ -827,7 +1016,7 @@ Suite* daemon_suite (void)
 
     tcase_add_test (tc, test_create_new_group);
     tcase_add_test (tc, test_add_group);
-    tcase_add_test (tc, test_get_group_by_uid);
+    tcase_add_test (tc, test_get_group_by_gid);
     tcase_add_test (tc, test_get_group_by_name);
     tcase_add_test (tc, test_delete_group);
     tcase_add_test (tc, test_update_group);