common: make gsignond-identity-info.h private, as it's not used by anything in the...
[platform/upstream/gsignond.git] / test / daemon / daemon-test.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of gsignond
5  *
6  * Copyright (C) 2012 Intel Corporation.
7  *
8  * Contact: Amarnaht Valluri <amarnath.valluri@linux.intel.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include "config.h"
27 #include <check.h>
28 #include <error.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <gio/gio.h>
32 #include <glib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36 #include "daemon/dbus/gsignond-dbus.h"
37 #include "daemon/dbus/gsignond-dbus-auth-service-gen.h"
38 #include "daemon/dbus/gsignond-dbus-identity-gen.h"
39 #include "daemon/dbus/gsignond-dbus-auth-session-gen.h"
40 #include "common/gsignond-identity-info.h"
41 #include "gsignond/gsignond-log.h"
42
43 #ifdef USE_P2P
44 #  ifdef GSIGNOND_SERVICE
45 #    undef GSIGNOND_SERVICE
46 #  endif
47 #  define GSIGNOND_SERVICE NULL
48 #endif
49
50 struct IdentityData {
51     gchar *key;
52     gchar *type;
53     void *value;
54 } data[] = {
55     { "UserName", "s", "test_user" },
56     { "Caption", "s", "test_caption" },
57     { "Secret", "s", "test_pass" },
58     { "StoreSecret", "b", (void *)TRUE}
59 };
60
61 #if HAVE_GTESTDBUS
62 GTestDBus *dbus = NULL;
63 #else
64 GPid daemon_pid = 0;
65 #endif
66
67 static gchar* _get_executable_name()
68 {
69     gchar *procfname;
70     char *path;
71     ssize_t res;
72     pid_t pid = getpid();
73
74     //valgrind does some magic with tasks, so we read the executable name of
75     //the 'main' task, instead of the current task
76     procfname = g_strdup_printf ("/proc/%d/task/%d/exe", pid, pid);
77     path = g_malloc0 (PATH_MAX + 1);
78     res = readlink (procfname, path, PATH_MAX);
79     g_free (procfname);
80
81     if (res <= 0) {
82         WARN ("failed to follow link for pid %d", pid);
83         g_free (path);
84         return NULL;
85     }
86     return path;
87 }
88
89 static void
90 setup_daemon (void)
91 {
92     gchar* exe_name = _get_executable_name();
93     fail_if(exe_name == NULL);
94     
95     fail_if (g_setenv ("G_MESSAGES_DEBUG", "all", TRUE) == FALSE);
96     fail_if (g_setenv ("SSO_IDENTITY_TIMEOUT", "5", TRUE) == FALSE);
97     fail_if (g_setenv ("SSO_DAEMON_TIMEOUT", "5", TRUE) == FALSE);
98     fail_if (g_setenv ("SSO_AUTH_SESSION_TIMEOUT", "5", TRUE) == FALSE);
99     fail_if (g_setenv ("SSO_STORAGE_PATH", "/tmp/gsignond", TRUE) == FALSE);
100     fail_if (g_setenv ("SSO_SECRET_PATH", "/tmp/gsignond", TRUE) == FALSE);
101     fail_if (g_setenv ("SSO_KEYCHAIN_SYSCTX", exe_name, TRUE) == FALSE);
102     fail_if (g_setenv ("SSO_PLUGIN_TIMEOUT", "5", TRUE) == FALSE);
103
104     DBG ("Programe pid %d, name : %s\n", getpid(), exe_name);
105     free(exe_name);
106
107     if (system("rm -rf /tmp/gsignond") != 0) {
108         DBG("Failed to clean db path : %s\n", strerror(errno));
109     }
110 #if HAVE_GTESTDBUS
111     dbus = g_test_dbus_new (G_TEST_DBUS_NONE);
112     fail_unless (dbus != NULL, "could not create test dbus");
113
114     g_test_dbus_add_service_dir (dbus, GSIGNOND_TEST_DBUS_SERVICE_DIR);
115
116     g_test_dbus_up (dbus);
117     DBG ("Test dbus server address : %s\n", g_test_dbus_get_bus_address(dbus));
118 #else
119     GError *error = NULL;
120 #   ifdef USE_P2P
121     /* start daemon maually */
122     gchar *argv[2];
123     gchar *test_daemon_path = g_build_filename (g_getenv("SSO_BIN_DIR"),
124             "gsignond", NULL);
125     fail_if (test_daemon_path == NULL, "No SSO daemon path found");
126
127     argv[0] = test_daemon_path;
128     argv[1] = NULL;
129     g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
130             &daemon_pid, &error);
131     g_free (test_daemon_path);
132     fail_if (error != NULL, "Failed to span daemon : %s",
133             error ? error->message : "");
134     sleep (5); /* 5 seconds */
135 #   else
136     /* session bus where no GTestBus support */
137     GIOChannel *channel = NULL;
138     gchar *bus_address = NULL;
139     gint tmp_fd = 0;
140     gint pipe_fd[2];
141     gchar *argv[] = {"dbus-daemon", "--config-file=<<conf-file>>", "--print-address=<<fd>>", NULL};
142     gsize len = 0;
143     const gchar *dbus_monitor = NULL;
144
145     argv[1] = g_strdup_printf ("--config-file=%s", "gsignond-dbus.conf");
146
147     if (pipe(pipe_fd)== -1) {
148         WARN("Failed to open temp file : %s", error->message);
149         argv[2] = g_strdup_printf ("--print-address=1");
150         g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &daemon_pid, NULL, NULL, &tmp_fd, &error);
151     } else {
152         tmp_fd = pipe_fd[0];
153         argv[2] = g_strdup_printf ("--print-address=%d", pipe_fd[1]);
154         g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_LEAVE_DESCRIPTORS_OPEN, NULL, NULL, &daemon_pid, &error);
155     }
156     fail_if (error != NULL, "Failed to span daemon : %s", error ? error->message : "");
157     fail_if (daemon_pid == 0, "Failed to get daemon pid");
158     g_free (argv[1]);
159     g_free (argv[2]);
160     sleep (5); /* 5 seconds */
161
162     channel = g_io_channel_unix_new (tmp_fd);
163     g_io_channel_read_line (channel, &bus_address, NULL, &len, &error);
164     fail_if (error != NULL, "Failed to daemon address : %s", error ? error->message : "");
165     g_io_channel_unref (channel);
166     
167     if (pipe_fd[0]) close (pipe_fd[0]);
168     if (pipe_fd[1]) close (pipe_fd[1]);
169
170     if (bus_address) bus_address[len] = '\0';
171     fail_if(bus_address == NULL || strlen(bus_address) == 0);
172
173     if (GSIGNOND_BUS_TYPE == G_BUS_TYPE_SYSTEM)
174         fail_if (g_setenv("DBUS_SYSTEM_BUS_ADDRESS", bus_address, TRUE) == FALSE);
175     else
176         fail_if (g_setenv("DBUS_SESSION_BUS_ADDRESS", bus_address, TRUE) == FALSE);
177
178     DBG ("Daemon Address : %s\n", bus_address);
179     g_free (bus_address);
180
181     if ((dbus_monitor = g_getenv("SSO_DBUS_DEBUG")) != NULL && g_strcmp0 (dbus_monitor, "0")) {
182         /* start dbus-monitor */
183         char *argv[] = {"dbus-monitor", "<<bus_type>>", NULL };
184         argv[1] = GSIGNOND_BUS_TYPE == G_BUS_TYPE_SYSTEM ? "--system" : "--session" ;
185         g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
186         if (error) {
187                 DBG ("Error while running dbus-monitor : %s", error->message);
188                 g_error_free (error);
189         }
190     }
191 #   endif
192
193     DBG ("Daemon PID = %d\n", daemon_pid);
194 #endif
195 }
196
197 static void
198 teardown_daemon (void)
199 {
200 #if HAVE_GTESTDBUS
201     g_test_dbus_down (dbus);
202 #else
203     if (daemon_pid) kill (daemon_pid, SIGTERM);
204 #endif
205
206     g_unsetenv ("SSO_IDENTITY_TIMEOUT");
207     g_unsetenv ("SSO_DAEMON_TIMEOUT");
208     g_unsetenv ("SSO_AUTH_SESSION_TIMEOUT");
209     g_unsetenv ("SSO_STORAGE_PATH");
210     g_unsetenv ("SSO_SECRET_PATH");
211     g_unsetenv ("SSO_KEYCHAIN_SYSCTX");
212 }
213
214 gboolean _validate_identity_info (GVariant *identity_info)
215 {
216     GSignondIdentityInfo *identity = 0;
217     const gchar *username = 0;
218     if (!identity_info) return FALSE;
219
220     identity = (GSignondIdentityInfo *)gsignond_dictionary_new_from_variant (identity_info);
221     if (!identity) return FALSE;
222
223     username = gsignond_identity_info_get_username (identity);
224
225     gsignond_dictionary_unref (identity);
226
227     if (!username || strcmp (username, "test_user")) return FALSE;
228
229     return TRUE;
230 }
231
232 GVariant * _get_test_identity_data()
233 {
234     GVariantBuilder builder, method_builder;
235     const gchar *mechanisms[] = {"mech1","mech2", NULL };
236     int i;
237
238     g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
239
240     for (i=0; i < sizeof(data)/sizeof(struct IdentityData); i++) {
241         g_variant_builder_add (&builder, "{sv}", data[i].key, g_variant_new (data[i].type, data[i].value));
242     }
243
244     g_variant_builder_init (&method_builder, (const GVariantType *)"a{sas}");
245     g_variant_builder_add (&method_builder, "{s^as}", "ssotest", mechanisms);
246
247     g_variant_builder_add (&builder, "{sv}", "AuthMethods", g_variant_builder_end (&method_builder));
248
249     return g_variant_builder_end (&builder);
250 }
251
252 GVariant * _create_identity_info_with_data (const gchar *username,
253                                             const gchar *caption, 
254                                             gint type, 
255                                             const gchar *methods[],
256                                             const gchar **mechanisms[])
257 {
258     GVariantBuilder builder;
259
260     g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
261
262     if(username) g_variant_builder_add (&builder, "{sv}", "UserName", g_variant_new_string (username));
263     if(caption) g_variant_builder_add (&builder, "{sv}", "Caption", g_variant_new_string (caption));
264     if (type != 0) g_variant_builder_add (&builder, "{sv}", "Type", g_variant_new_int32(type));
265     if (methods && mechanisms) {
266         GVariantBuilder method_builder;
267         int i;
268  
269         g_variant_builder_init (&method_builder, (const GVariantType *)"a{sas}");
270
271         for (i=0; methods[i]; i++) {
272             g_variant_builder_add (&method_builder, "{s^as}", methods[i], mechanisms[i]);
273         }
274
275         g_variant_builder_add (&builder, "{sv}", "AuthMethods", g_variant_builder_end (&method_builder));
276     }
277
278     return g_variant_builder_end (&builder);
279 }
280
281
282 GDBusConnection * _get_bus_connection (GError **error)
283 {
284 #if USE_P2P
285     gchar address[128];
286
287     g_snprintf (address, 127, GSIGNOND_DBUS_ADDRESS, g_get_user_runtime_dir());
288     return g_dbus_connection_new_for_address_sync (
289         address,
290         G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
291         NULL,
292         NULL,
293         error);
294 #else
295     return g_bus_get_sync (GSIGNOND_BUS_TYPE, NULL, error);
296 #endif
297 }
298
299 GSignondDbusAuthService * _get_auth_service (GDBusConnection *connection,
300                                              GError **error)
301 {
302     return gsignond_dbus_auth_service_proxy_new_sync (
303                 connection,
304                 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
305                 GSIGNOND_SERVICE,
306                 GSIGNOND_DAEMON_OBJECTPATH,
307                 NULL, error);
308 }
309
310 GSignondDbusIdentity * _get_identity_for_path (GDBusConnection *connection,
311                                                const gchar *identity_path,
312                                                GError **error)
313 {
314     return gsignond_dbus_identity_proxy_new_sync (
315         connection,
316         G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
317         GSIGNOND_SERVICE,
318         identity_path,
319         NULL, error);
320 }
321
322 GSignondDbusAuthSession * _get_auth_session_for_path (GDBusConnection *connection,
323                                                       const gchar *session_path,
324                                                       GError **error)
325 {
326     return gsignond_dbus_auth_session_proxy_new_sync (
327         connection,
328         G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
329         GSIGNOND_SERVICE,
330         session_path,
331         NULL, error);
332 }
333
334 GSignondDbusIdentity * _register_identity (GSignondDbusAuthService *auth_service,
335                                            const gchar *app_context,
336                                            GError **error) 
337 {
338     GDBusConnection *connection = NULL;
339     GSignondDbusIdentity *identity = NULL;
340     gchar *identity_path = NULL;
341
342     gboolean res = gsignond_dbus_auth_service_call_register_new_identity_sync (
343         auth_service,
344         app_context,
345         &identity_path,
346         NULL,
347         error);
348
349     if (res == FALSE) {
350         DBG (" ERROR :: %s", error ? (*error)->message : "");
351         return NULL;
352     }
353
354     connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (auth_service));
355     identity = _get_identity_for_path (connection, identity_path, error);
356
357     g_free (identity_path);
358
359     return identity;
360 }
361
362 GSignondDbusIdentity * _get_identity (GSignondDbusAuthService *auth_service,
363                                       guint32 id,
364                                       const gchar *app_context,
365                                       GVariant **identity_info,
366                                       GError **error)
367 {
368     gboolean res;
369     gchar *identity_path = NULL;
370     GDBusConnection *connection = NULL;
371     GSignondDbusIdentity *identity = NULL;
372     
373     res = gsignond_dbus_auth_service_call_get_identity_sync(
374         auth_service,
375         id,
376         app_context,        
377         &identity_path,
378         identity_info,
379         NULL,
380         error);
381
382     if (res == FALSE || !identity_path) {
383         DBG ("ERROR :: %s", error ? (*error)->message : "");
384         return NULL;
385     }
386
387     connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (auth_service));
388     identity = _get_identity_for_path (connection, identity_path, error);
389
390     g_free (identity_path);
391
392     return identity;
393 }
394
395 /*
396  * Test cases
397  */
398 START_TEST (test_register_new_identity)
399 {
400     GError *error = 0;
401     GDBusConnection *connection = NULL;
402     GSignondDbusAuthService *auth_service = NULL;
403     GSignondDbusIdentity *identity = NULL;
404
405     connection = _get_bus_connection (&error);
406     fail_if (connection == NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
407
408     auth_service = _get_auth_service (connection, &error);
409     fail_if (auth_service == NULL, "failed to get auth_service : %s", error ? error->message : "");
410
411     identity = _register_identity (auth_service, "test_app", &error);
412     fail_if (identity == NULL, "Failed to register identity : %s", error ? error->message : "");
413
414     g_object_unref (identity);
415     g_object_unref (auth_service);
416     g_object_unref (connection);
417 }
418 END_TEST
419
420 START_TEST (test_register_new_identity_with_no_app_context)
421 {
422     GError *error = NULL;
423     GSignondDbusAuthService *auth_service = NULL;
424     GSignondDbusIdentity *identity = NULL;
425     GDBusConnection *connection = _get_bus_connection (&error);
426     fail_if (connection == NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
427     fail_if (error != NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
428  
429     auth_service = _get_auth_service (connection, &error);
430     fail_if (auth_service == NULL, "failed to get auth_service : %s", error ? error->message : "");
431
432     identity = _register_identity (auth_service, "", &error);
433     fail_if (identity == NULL, "Failed to register identity : %s", error ? error->message : "");
434
435     g_object_unref (identity);
436     g_object_unref (auth_service);
437     g_object_unref (connection);
438 }
439 END_TEST
440
441 START_TEST (test_identity_store)
442 {
443     GError *error = NULL; gboolean res = FALSE;
444     GSignondDbusAuthService *auth_service = 0;
445     GSignondDbusIdentity *identity = 0;
446     guint id;
447     GVariant *identity_info = NULL;
448
449     GDBusConnection *connection = _get_bus_connection (&error);
450     fail_if (connection == NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
451     fail_if (error != NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
452
453     auth_service = _get_auth_service (connection, &error);
454     fail_if (auth_service == NULL, "failed to get auth_service : %s", error ? error->message : "");
455
456     identity_info = _get_test_identity_data ();
457     fail_if (identity_info == NULL, "Failed to get test identity data");
458
459     identity = _register_identity (auth_service, "test_app", &error);
460     fail_if (identity == NULL, "Failed to register identity : %s", error ? error->message : "");
461
462     res = gsignond_dbus_identity_call_store_sync (identity, identity_info, 
463                                     &id, NULL, &error); 
464     fail_if (res == FALSE, "Failed to store identity : %s", error ? error->message : "");
465     fail_if (id == 0);
466
467     DBG ("Identity id : %d\n", id);
468
469     g_object_unref (identity);
470     g_object_unref (auth_service);
471     g_object_unref (connection);
472 }
473 END_TEST
474
475 START_TEST(test_identity_get_identity)
476 {
477     GError *error = NULL;
478     GSignondDbusAuthService *auth_service = 0;
479     guint32 id = 1; /* identity id created in test_identity_store */
480     GVariant *identity_info = NULL;
481     GSignondDbusIdentity *identity = NULL;
482     GDBusConnection *connection = _get_bus_connection (&error);
483     fail_if (connection == NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
484     fail_if (error != NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
485
486     auth_service = _get_auth_service (connection, &error);
487     fail_if (auth_service == NULL, "failed to get auth_service : %s", error ? error->message : "");
488
489     identity = _get_identity (auth_service, id, "test_app", &identity_info, &error);
490     fail_if (identity == NULL, "Failed to get identity for id '%u' : %s", id, error ? error->message : "");
491     fail_if (identity_info == NULL);
492
493     fail_if (_validate_identity_info(identity_info) == FALSE);
494
495     g_object_unref (auth_service);
496     g_object_unref (identity);
497     g_object_unref (connection);
498 }
499 END_TEST
500
501 START_TEST(test_clear_database)
502 {
503     GError *error = 0;
504     gboolean res, ret;
505     GSignondDbusAuthService *auth_service = 0;
506     GDBusConnection *connection = _get_bus_connection (&error);
507     fail_if (connection == NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
508     fail_if (error != NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
509  
510     auth_service = _get_auth_service (connection, &error);
511     fail_if (auth_service == NULL, "failed to get auth_service : %s", error ? error->message : "");
512
513     res = gsignond_dbus_auth_service_call_clear_sync (
514         auth_service,
515         &ret,
516         NULL,
517         &error);
518     fail_if (res == FALSE || ret == FALSE, "Failed to wipe databases : %s", error ? error->message : "");
519
520     g_object_unref (auth_service);
521     g_object_unref (connection);
522 }
523 END_TEST
524
525 static void _on_session_unregistered (GSignondDbusAuthSession *sesssion, gpointer userdata)
526 {
527     gboolean *out = (gboolean*) userdata;
528     g_return_if_fail (out);
529
530     *out = TRUE;
531 }
532
533 static void _on_identity_updated (GSignondDbusIdentity *identity, gint change_type, gpointer userdata)
534 {
535     gboolean *out = (gboolean *)userdata;
536     g_return_if_fail (out);
537
538     if (change_type == 2 /* GSIGNOND_IDENTITY_SIGNED_OUT */) 
539         *out = TRUE;
540 }
541
542 static void _on_sign_out_reply (GSignondDbusIdentity *sender, GAsyncResult *reply, gpointer data)
543 {
544     GError *error = NULL;
545
546     gboolean res = FALSE, ret = FALSE;
547     
548     ret = gsignond_dbus_identity_call_sign_out_finish (sender, &res, reply, &error);
549
550     fail_if (ret == FALSE, "failed to finish signout, %s", error ? error->message : "");
551     fail_if (res == FALSE, "failed to call signout on identity : %s", error ? error->message : "");
552
553     g_main_loop_quit ((GMainLoop *)data);
554     g_main_loop_unref((GMainLoop *)data);
555 }
556
557 START_TEST(test_identity_signout)
558 {
559     GError *error = 0;
560     gboolean res;
561     GSignondDbusAuthService *auth_service = 0;
562     GSignondDbusIdentity *identity = 0;
563     GSignondDbusAuthSession *auth_session = 0;
564     GVariant *identity_info = NULL;
565     gchar *session_path = NULL;
566     guint id;
567     gboolean identity_signed_out = FALSE;
568     gboolean session_unregistered = FALSE;
569     GMainLoop *loop = NULL;
570     GDBusConnection *connection = _get_bus_connection (&error);
571     fail_if (connection == NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
572     fail_if (error != NULL, "failed to get bus connection : %s", error ? error->message : "(null)");
573
574     loop = g_main_loop_new (NULL, FALSE);
575
576     auth_service = _get_auth_service (connection, &error);
577     fail_if (auth_service == NULL, "failed to get auth_service : %s", error ? error->message : "");
578
579     identity = _register_identity (auth_service, "", &error);
580     fail_if (identity == NULL, "Failed to register new identity : %s", error ? error->message : "");
581
582     identity_info = _get_test_identity_data ();
583     fail_if (identity_info == NULL);
584
585     res = gsignond_dbus_identity_call_store_sync (identity, identity_info,
586                                                   &id, NULL, &error);
587     fail_if (res == FALSE, "Failed to store identity");
588     fail_if (id == 0);
589
590     g_signal_connect (identity, "info-updated", G_CALLBACK(_on_identity_updated), &identity_signed_out);
591
592     res = gsignond_dbus_identity_call_get_auth_session_sync (
593             identity, "ssotest", &session_path, NULL, &error);
594
595     fail_if (res == FALSE, "Failed to create authentication session on identity for method 'ssotest', error : %s",
596         error ? error->message : "");
597     fail_if (session_path == NULL, "(null) session_path");
598
599     auth_session = _get_auth_session_for_path (connection, session_path, &error);
600
601     g_free (session_path);
602     fail_if (error != NULL, "failed to created session proxy for path '%s', error: %s", 
603         session_path, error ? error->message : "");
604     fail_if (auth_session == NULL, "(null) session object");
605
606     g_signal_connect (auth_session, "unregistered", G_CALLBACK (_on_session_unregistered), &session_unregistered);
607
608     /* Call SignOut on identity */
609     gsignond_dbus_identity_call_sign_out (identity, NULL, (GAsyncReadyCallback)_on_sign_out_reply, loop);
610
611     g_main_loop_run (loop);
612
613     fail_unless (session_unregistered == TRUE, "Session unregistred not reached");
614     fail_unless (identity_signed_out == TRUE, "Identity signed out signal not reached");
615
616     g_object_unref (auth_service);
617     g_object_unref (identity);
618     g_object_unref (auth_session);
619     g_object_unref (connection);
620 }
621 END_TEST
622
623 START_TEST(test_query_identities)
624 {
625     GDBusConnection *connection = NULL;
626     GSignondDbusAuthService *auth_service = NULL;
627     GSignondDbusIdentity *identity = NULL;
628     GVariant *v_info = NULL;
629     GSignondIdentityInfo *info1 = NULL, *info2 = NULL, *info3 = NULL, *tmp_info = NULL;
630     GSignondDictionary *filter = NULL;
631     GVariant *v_identities = NULL;
632     const gchar *methods[] = { "ssotest", NULL };
633     const gchar *mech[] = {"mech1", "mech2", NULL};
634     const gchar **mechanisms[] = { mech };
635     gboolean res;
636     guint32 id = 0;
637     GError *error = NULL;
638
639     connection = _get_bus_connection (&error);
640     fail_if (connection == NULL, "Failed to get bus connection : %s", error ? error->message : "");
641
642     auth_service = _get_auth_service (connection, &error);
643     fail_if (auth_service == NULL, "Failed to get auth_service : %s", error ? error->message : "");
644
645     /* created identity1 */
646     identity = _register_identity (auth_service, "app_context_A", &error);
647     fail_if (identity == NULL, "Failed to register new identity : %s", error ? error->message : "");
648
649     v_info = _create_identity_info_with_data ("user1", "caption1", 1, methods, mechanisms);
650     fail_if (v_info == NULL);
651     res = gsignond_dbus_identity_call_store_sync (identity, v_info, &id, NULL, &error);
652     fail_if (res == FALSE || id == 0, "Failed to store identity : %s", error ? error->message : "");
653     g_object_unref (identity);
654
655     identity = _get_identity (auth_service, id, "app_context_A", &v_info, &error);
656     fail_if (identity == NULL || v_info == NULL, "Failed to load identity for id '%d' : %s", id, error ? error->message : "");
657     g_object_unref (identity);
658     info1 = gsignond_dictionary_new_from_variant (v_info);
659
660     /* created identity2 */
661     identity = _register_identity (auth_service, "app_context_B", &error);
662     fail_if (identity == NULL, "Failed to register new identity : %s", error ? error->message : "");
663
664     v_info = _create_identity_info_with_data ("user2", "caption2", 2, methods, mechanisms);
665     fail_if (v_info == NULL);
666     res = gsignond_dbus_identity_call_store_sync (identity, v_info, &id, NULL, &error);
667     fail_if (res == FALSE || id == 0, "Failed to store identity : %s", error ? error->message : "");
668     g_object_unref (identity);
669
670     identity = _get_identity (auth_service, id, "app_context_B", &v_info, &error);
671     fail_if (identity == NULL || v_info == NULL, "Failed to load identity for id '%d' : %s", id, error ? error->message : "");
672     g_object_unref (identity);
673     info2 = gsignond_dictionary_new_from_variant (v_info);
674
675     /* create identity3 */
676     identity = _register_identity (auth_service, "app_context_A", &error);
677     fail_if (identity == NULL, "Failed to register new identity : %s", error ? error->message : "");
678
679     v_info = _create_identity_info_with_data ("user2", "caption3", 2, methods, mechanisms);
680     fail_if (v_info == NULL);
681     res = gsignond_dbus_identity_call_store_sync (identity, v_info, &id, NULL, &error);
682     fail_if (res == FALSE || id == 0, "Failed to store identity : %s", error ? error->message : "");
683     g_object_unref (identity);
684
685     identity = _get_identity (auth_service, id, "app_context_A", &v_info, &error);
686     fail_if (identity == NULL || v_info == NULL, "Failed to load identity for id '%d' : %s", id, error ? error->message : "");
687     g_object_unref (identity);
688     info3 = gsignond_dictionary_new_from_variant (v_info);
689
690     /* query identities for app-context: app_context_A */
691     v_identities = NULL;
692     filter = gsignond_dictionary_new();
693     res = gsignond_dbus_auth_service_call_query_identities_sync (auth_service,
694             gsignond_dictionary_to_variant (filter),
695             "app_context_A", &v_identities, NULL, &error);
696     gsignond_dictionary_unref (filter);
697     fail_if (res == FALSE || !v_identities, "Failed to query identities for "
698                            "app context 'app_context_A' : %s",
699                            error ? error->message : "");
700     fail_if (g_variant_n_children (v_identities) != 2, 
701         "Expected no of identities '%d', got '%d'", 2,
702         g_variant_n_children(v_identities));
703     /* validated query results */
704     tmp_info = gsignond_dictionary_new_from_variant (
705                             g_variant_get_child_value (v_identities, 0));
706     fail_if (gsignond_identity_info_compare (info1, tmp_info) == FALSE);
707     gsignond_identity_info_unref (tmp_info);
708
709     tmp_info = gsignond_dictionary_new_from_variant (
710                             g_variant_get_child_value (v_identities, 1));
711     fail_if (gsignond_identity_info_compare (info3, tmp_info) == FALSE);
712     gsignond_identity_info_unref (tmp_info);
713
714     /* query identities for app-context: app_context_B, Identity type : 2 */
715     v_identities = NULL;
716     filter = gsignond_dictionary_new();
717     gsignond_dictionary_set_int32 (filter, "Type", 2);
718     res = gsignond_dbus_auth_service_call_query_identities_sync (auth_service,
719             gsignond_dictionary_to_variant (filter),
720             "app_context_B", &v_identities, NULL, &error);
721     gsignond_dictionary_unref (filter);
722     fail_if (res == FALSE || !v_identities, "Failed to query identities for "
723                            "app context 'app_context_B' and Type: 2 : %s",
724                            error ? error->message : "");
725     /* validated query results */
726     fail_if (g_variant_n_children (v_identities) != 1, 
727         "Expected no of identities '%d', got '%d'", 1,
728         g_variant_n_children(v_identities));
729     tmp_info = gsignond_dictionary_new_from_variant (
730                             g_variant_get_child_value (v_identities, 0));
731     fail_if (gsignond_identity_info_compare (info2, tmp_info) == FALSE);
732     gsignond_identity_info_unref (tmp_info);
733
734     /* query identities for app-context: app_context_A, Caption: "cap*" */
735     v_identities = NULL;
736     filter = gsignond_dictionary_new();
737     gsignond_dictionary_set_string (filter, "Caption", "cap");
738     res = gsignond_dbus_auth_service_call_query_identities_sync (auth_service,
739             gsignond_dictionary_to_variant (filter),
740             "app_context_B", &v_identities, NULL, &error);
741     gsignond_dictionary_unref (filter);
742     fail_if (res == FALSE || !v_identities, "Failed to query identities for "
743                            "app context 'app_context_A' : %s",
744                            error ? error->message : "");
745     /* validated query results */
746     fail_if (g_variant_n_children (v_identities) != 1, 
747         "Expected no of identities '%d', got '%d'", 1,
748         g_variant_n_children(v_identities));
749     tmp_info = gsignond_dictionary_new_from_variant (
750                             g_variant_get_child_value (v_identities, 0));
751     fail_if (gsignond_identity_info_compare 
752             (info2, tmp_info) == FALSE);
753     gsignond_identity_info_unref (tmp_info);
754
755     gsignond_identity_info_unref (info1);
756     gsignond_identity_info_unref (info2);
757     gsignond_identity_info_unref (info3);
758
759     g_object_unref (auth_service);
760     g_object_unref (connection);
761 }
762 END_TEST
763
764 Suite* daemon_suite (void)
765 {
766     Suite *s = suite_create ("Gsignon daemon");
767     
768     TCase *tc = tcase_create ("Identity");
769
770     tcase_set_timeout(tc, 10);
771     tcase_add_unchecked_fixture (tc, setup_daemon, teardown_daemon);
772
773     tcase_add_test (tc, test_register_new_identity);
774     tcase_add_test (tc, test_register_new_identity_with_no_app_context);
775     tcase_add_test (tc, test_identity_store);
776     tcase_add_test (tc, test_identity_get_identity);
777     tcase_add_test (tc, test_clear_database);
778     tcase_add_test (tc, test_identity_signout);
779     tcase_add_test (tc, test_query_identities);
780
781     suite_add_tcase (s, tc);
782
783     return s;
784 }
785
786 int main (int argc, char *argv[])
787 {
788     int number_failed;
789     Suite *s = 0;
790     SRunner *sr = 0;
791    
792 #if !GLIB_CHECK_VERSION (2, 36, 0)
793     g_type_init ();
794 #endif
795
796     s = daemon_suite();
797     sr = srunner_create(s);
798
799     srunner_run_all(sr, CK_VERBOSE);
800
801     number_failed = srunner_ntests_failed(sr);
802     srunner_free(sr);
803
804     return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
805 }