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