Line data Source code
1 : /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 : /* test-secret-util.c: Test secret utils
3 :
4 : Copyright (C) 2012 Red Hat Inc
5 :
6 : The Gnome Keyring Library is free software; you can redistribute it and/or
7 : modify it under the terms of the GNU Library General Public License as
8 : published by the Free Software Foundation; either version 2 of the
9 : License, or (at your option) any later version.
10 :
11 : The Gnome Keyring Library is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Library General Public License for more details.
15 :
16 : You should have received a copy of the GNU Library General Public
17 : License along with the Gnome Library; see the file COPYING.LIB. If not,
18 : <http://www.gnu.org/licenses/>.
19 :
20 : Author: Stef Walter <stefw@gnome.org>
21 : */
22 :
23 : #include "config.h"
24 :
25 : #include "test-service.h"
26 :
27 : #include "gkd-secret-types.h"
28 :
29 : #include "egg/egg-testing.h"
30 :
31 : #include <gcr/gcr-base.h>
32 :
33 : #include <glib.h>
34 : #include <glib/gstdio.h>
35 : #include <gio/gio.h>
36 :
37 : #include <fcntl.h>
38 :
39 : typedef struct {
40 : gchar *path;
41 : gchar *iface;
42 : gchar *name;
43 : GVariant *parameters;
44 : } ReceivedSignal;
45 :
46 : typedef struct {
47 : TestService service;
48 : guint signal_id;
49 : GList *received_signals;
50 : gboolean expecting_properties;
51 : } Test;
52 :
53 : static void
54 32 : on_signal_received (GDBusConnection *connection,
55 : const gchar *sender_name,
56 : const gchar *object_path,
57 : const gchar *interface_name,
58 : const gchar *signal_name,
59 : GVariant *parameters,
60 : gpointer user_data)
61 : {
62 32 : Test *test = user_data;
63 : ReceivedSignal *sig;
64 :
65 32 : g_assert (object_path != NULL);
66 32 : g_assert (interface_name != NULL);
67 32 : g_assert (signal_name != NULL);
68 32 : g_assert (parameters != NULL);
69 :
70 32 : sig = g_slice_new0 (ReceivedSignal);
71 32 : sig->path = g_strdup (object_path);
72 32 : sig->iface = g_strdup (interface_name);
73 32 : sig->name = g_strdup (signal_name);
74 32 : sig->parameters = g_variant_ref (parameters);
75 32 : test->received_signals = g_list_prepend (test->received_signals, sig);
76 :
77 32 : if (test->expecting_properties &&
78 8 : g_str_equal ("org.freedesktop.DBus.Properties", interface_name) &&
79 8 : g_str_equal ("PropertiesChanged", signal_name)) {
80 8 : egg_test_wait_stop ();
81 : }
82 32 : }
83 :
84 : static void
85 32 : received_signal_free (gpointer data)
86 : {
87 32 : ReceivedSignal *sig = data;
88 32 : g_free (sig->path);
89 32 : g_free (sig->iface);
90 32 : g_free (sig->name);
91 32 : g_variant_unref (sig->parameters);
92 32 : g_slice_free (ReceivedSignal, sig);
93 32 : }
94 :
95 : static void
96 22 : received_signals_flush (Test *test)
97 : {
98 22 : g_list_free_full (test->received_signals, received_signal_free);
99 22 : test->received_signals = NULL;
100 22 : }
101 :
102 : static void
103 13 : expect_signal_with_path (Test *test,
104 : const gchar *signal_path,
105 : const gchar *signal_iface,
106 : const gchar *signal_name,
107 : const gchar *param_path)
108 : {
109 : ReceivedSignal *sig;
110 : const gchar *path;
111 : GList *l;
112 :
113 13 : g_assert (signal_path != NULL);
114 13 : g_assert (signal_iface != NULL);
115 13 : g_assert (signal_name != NULL);
116 13 : g_assert (param_path != NULL);
117 :
118 20 : for (l = test->received_signals; l != NULL; l = g_list_next (l)) {
119 20 : sig = l->data;
120 :
121 20 : if (g_str_equal (signal_path, sig->path) &&
122 14 : g_str_equal (signal_iface, sig->iface) &&
123 13 : g_str_equal (signal_name, sig->name)) {
124 13 : g_assert (g_variant_is_of_type (sig->parameters, G_VARIANT_TYPE ("(o)")));
125 13 : g_variant_get (sig->parameters, "(&o)", &path);
126 13 : if (!g_str_equal (path, param_path)) {
127 0 : g_critical ("received invalid path from signal %s on interface %s at object %s: "
128 : "expected path %s but got %s",
129 : sig->name, sig->iface, sig->path, param_path, path);
130 : }
131 :
132 13 : return;
133 : }
134 : }
135 :
136 0 : g_critical ("didn't receive signal %s on interface %s at object %s",
137 : signal_name, signal_iface, signal_path);
138 : }
139 :
140 : static gboolean
141 34 : has_property_changed (Test *test,
142 : const gchar *signal_path,
143 : const gchar *property_iface,
144 : const gchar *property_name)
145 : {
146 : ReceivedSignal *sig;
147 : const gchar *iface;
148 : GVariant *properties;
149 : GVariant *invalidated;
150 : GVariant *value;
151 : GList *l;
152 :
153 34 : g_assert (signal_path != NULL);
154 34 : g_assert (property_iface != NULL);
155 34 : g_assert (property_name != NULL);
156 :
157 72 : for (l = test->received_signals; l != NULL; l = g_list_next (l)) {
158 64 : sig = l->data;
159 :
160 64 : if (g_str_equal (signal_path, sig->path) &&
161 36 : g_str_equal ("org.freedesktop.DBus.Properties", sig->iface) &&
162 26 : g_str_equal ("PropertiesChanged", sig->name)) {
163 26 : value = NULL;
164 26 : g_assert (g_variant_is_of_type (sig->parameters, G_VARIANT_TYPE ("(sa{sv}as)")));
165 :
166 26 : g_variant_get (sig->parameters, "(&s@a{sv}@as)", &iface, &properties, &invalidated);
167 26 : if (g_str_equal (iface, property_iface)) {
168 26 : value = g_variant_lookup_value (properties, property_name, NULL);
169 26 : g_variant_unref (value);
170 : }
171 :
172 26 : g_variant_unref (properties);
173 26 : g_variant_unref (invalidated);
174 :
175 26 : if (value != NULL)
176 26 : return TRUE;
177 : }
178 : }
179 :
180 8 : return FALSE;
181 : }
182 :
183 : static void
184 13 : expect_property_changed (Test *test,
185 : const gchar *signal_path,
186 : const gchar *property_iface,
187 : const gchar *property_name)
188 : {
189 : /* GDBus queues property change signal emissions in an idle,
190 : * so we cannot rely on PropertiesChanged to have arrived by
191 : * the time we have returned from the method call - but we cannot
192 : * rely on it *not* having arrived either!
193 : * If the property notification hasn't been received, we set up
194 : * ourselves to wake up at every property change.
195 : * Eventually, if we don't receive any that match our arguments,
196 : * we're going to fail.
197 : */
198 21 : while (!has_property_changed (test, signal_path, property_iface, property_name)) {
199 8 : test->expecting_properties = TRUE;
200 8 : egg_test_wait_until (2000);
201 8 : test->expecting_properties = FALSE;
202 : }
203 :
204 13 : if (!has_property_changed (test, signal_path, property_iface, property_name))
205 0 : g_critical ("didn't receive PropertiesChanged for %s property on interface %s at object %s",
206 : property_name, property_iface, signal_path);
207 13 : }
208 :
209 : static void
210 12 : on_complete_get_result (GObject *source,
211 : GAsyncResult *result,
212 : gpointer user_data)
213 : {
214 12 : GAsyncResult **res = user_data;
215 12 : g_assert (res != NULL);
216 12 : g_assert (*res == NULL);
217 12 : *res = g_object_ref (result);
218 12 : egg_test_wait_stop ();
219 12 : }
220 :
221 : static GVariant *
222 12 : dbus_call_perform (Test *test,
223 : const gchar *object_path,
224 : const gchar *interface,
225 : const gchar *member,
226 : GVariant *parameters,
227 : const GVariantType *restype,
228 : GError **error)
229 : {
230 12 : GAsyncResult *result = NULL;
231 : GVariant *retval;
232 :
233 : /*
234 : * Do an async call with a full main loop, so that the signals
235 : * arrive before the method result.
236 : */
237 :
238 12 : g_dbus_connection_call (test->service.connection,
239 12 : test->service.bus_name,
240 : object_path,
241 : interface,
242 : member,
243 : parameters,
244 : restype,
245 : G_DBUS_CALL_FLAGS_NO_AUTO_START,
246 : -1, NULL,
247 : on_complete_get_result,
248 : &result);
249 :
250 12 : g_assert (result == NULL);
251 12 : egg_test_wait ();
252 12 : g_assert (result != NULL);
253 :
254 12 : retval = g_dbus_connection_call_finish (test->service.connection,
255 : result, error);
256 12 : g_object_unref (result);
257 :
258 12 : return retval;
259 : }
260 :
261 : static void
262 10 : setup (Test *test,
263 : gconstpointer unused)
264 : {
265 10 : GError *error = NULL;
266 : GVariant *retval;
267 :
268 10 : test->service.mock_prompter = gcr_mock_prompter_start ();
269 10 : g_assert (test->service.mock_prompter != NULL);
270 :
271 10 : test_service_setup (&test->service);
272 :
273 : /* Unlock the test collection */
274 10 : retval = g_dbus_connection_call_sync (test->service.connection,
275 10 : test->service.bus_name,
276 : SECRET_SERVICE_PATH,
277 : INTERNAL_SERVICE_INTERFACE,
278 : "UnlockWithMasterPassword",
279 : g_variant_new ("(o@(oayays))",
280 : "/org/freedesktop/secrets/collection/test",
281 : test_service_build_secret (&test->service, "booo")),
282 : G_VARIANT_TYPE ("()"),
283 : G_DBUS_CALL_FLAGS_NO_AUTO_START,
284 : -1, NULL, &error);
285 10 : g_assert_no_error (error);
286 10 : g_variant_unref (retval);
287 :
288 : /* Wait for the prompt's completed signal */
289 20 : test->signal_id = g_dbus_connection_signal_subscribe (test->service.connection,
290 10 : test->service.bus_name,
291 : NULL, NULL, NULL, NULL,
292 : G_DBUS_SIGNAL_FLAGS_NONE,
293 : on_signal_received,
294 : test, NULL);
295 :
296 10 : received_signals_flush (test);
297 10 : }
298 :
299 : static void
300 2 : setup_locked (Test *test,
301 : gconstpointer unused)
302 : {
303 : GVariant *element;
304 : GVariant *retval;
305 2 : GError *error = NULL;
306 : const gchar *prompt;
307 : GVariant *locked;
308 :
309 : /* Main setup */
310 2 : setup (test, unused);
311 :
312 2 : element = g_variant_new_object_path ("/org/freedesktop/secrets/collection/test");
313 2 : retval = dbus_call_perform (test,
314 : SECRET_SERVICE_PATH,
315 : SECRET_SERVICE_INTERFACE,
316 : "Lock",
317 : g_variant_new ("(@ao)",
318 : g_variant_new_array (G_VARIANT_TYPE ("o"), &element, 1)),
319 : G_VARIANT_TYPE ("(aoo)"),
320 : &error);
321 2 : g_assert_no_error (error);
322 :
323 : /* Not expecting a prompt */
324 2 : g_variant_get (retval, "(@ao&o)", &locked, &prompt);
325 2 : g_assert_cmpstr (prompt, ==, "/");
326 2 : g_variant_unref (locked);
327 2 : g_variant_unref (retval);
328 :
329 : /* Don't carry over any received signals into test */
330 2 : received_signals_flush (test);
331 2 : }
332 :
333 : static void
334 10 : teardown (Test *test,
335 : gconstpointer unused)
336 : {
337 10 : received_signals_flush (test);
338 :
339 10 : g_dbus_connection_signal_unsubscribe (test->service.connection, test->signal_id);
340 :
341 10 : test_service_teardown (&test->service);
342 :
343 10 : gcr_mock_prompter_stop ();
344 10 : }
345 :
346 : static void
347 2 : on_prompt_completed (GDBusConnection *connection,
348 : const gchar *sender_name,
349 : const gchar *object_path,
350 : const gchar *interface_name,
351 : const gchar *signal_name,
352 : GVariant *parameters,
353 : gpointer user_data)
354 : {
355 2 : GVariant **prompt_result = user_data;
356 : gboolean dismissed;
357 : GVariant *result;
358 :
359 2 : g_assert (prompt_result != NULL);
360 2 : g_assert (*prompt_result == NULL);
361 :
362 2 : g_assert (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(bv)")));
363 2 : g_variant_get (parameters, "(b@v)", &dismissed, &result);
364 :
365 2 : if (dismissed)
366 0 : *prompt_result = NULL;
367 : else
368 2 : *prompt_result = g_variant_ref (result);
369 2 : g_variant_unref (result);
370 :
371 2 : egg_test_wait_stop ();
372 2 : }
373 :
374 : static GVariant *
375 2 : prompt_password_perform (Test *test,
376 : const gchar *prompt_path,
377 : const gchar *password,
378 : const GVariantType *type)
379 : {
380 2 : GVariant *prompt_result = NULL;
381 2 : GError *error = NULL;
382 : GVariant *inside;
383 : GVariant *retval;
384 : guint sig;
385 :
386 : /* Tell the mock prompter which password to use */
387 2 : gcr_mock_prompter_expect_password_ok (password, NULL);
388 :
389 : /* Wait for the prompt's completed signal */
390 2 : sig = g_dbus_connection_signal_subscribe (test->service.connection,
391 2 : test->service.bus_name,
392 : SECRET_PROMPT_INTERFACE,
393 : "Completed",
394 : prompt_path,
395 : NULL,
396 : G_DBUS_SIGNAL_FLAGS_NONE,
397 : on_prompt_completed,
398 : &prompt_result,
399 : NULL);
400 :
401 : /* Perform the prompt, this will use the mock prompter */
402 2 : retval = g_dbus_connection_call_sync (test->service.connection,
403 2 : test->service.bus_name,
404 : prompt_path,
405 : SECRET_PROMPT_INTERFACE,
406 : "Prompt",
407 : g_variant_new ("(s)", ""),
408 : G_VARIANT_TYPE ("()"),
409 : G_DBUS_CALL_FLAGS_NONE,
410 : -1, NULL, &error);
411 2 : g_assert_no_error (error);
412 2 : g_variant_unref (retval);
413 :
414 2 : egg_test_wait ();
415 :
416 : /* Done, now stop waiting for the prompts signal, make sure mock was used */
417 2 : g_dbus_connection_signal_unsubscribe (test->service.connection, sig);
418 2 : g_assert (!gcr_mock_prompter_is_expecting ());
419 :
420 : /* Check prompt result for right type */
421 2 : g_assert (prompt_result != NULL);
422 2 : inside = g_variant_get_variant (prompt_result);
423 2 : g_assert (g_variant_is_of_type (inside, type));
424 2 : g_variant_unref (prompt_result);
425 :
426 2 : return inside;
427 : }
428 :
429 : static void
430 1 : test_collection_created (Test *test,
431 : gconstpointer unused)
432 : {
433 : const gchar *collection;
434 1 : GError *error = NULL;
435 : const gchar *prompt;
436 : GVariant *properties;
437 : GVariant *retval;
438 : GVariant *result;
439 : GVariant *label;
440 :
441 : /* Create a new collection */
442 1 : label = g_variant_new_dict_entry (g_variant_new_string ("org.freedesktop.Secret.Collection.Label"),
443 : g_variant_new_variant (g_variant_new_string ("My Collection")));
444 1 : properties = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), &label, 1);
445 :
446 1 : retval = dbus_call_perform (test,
447 : SECRET_SERVICE_PATH,
448 : SECRET_SERVICE_INTERFACE,
449 : "CreateCollection",
450 : g_variant_new ("(@a{sv}s)", properties, ""),
451 : G_VARIANT_TYPE ("(oo)"),
452 : &error);
453 1 : g_assert_no_error (error);
454 :
455 : /* We expect that a prompt is necessary */
456 1 : g_variant_get (retval, "(&o&o)", &collection, &prompt);
457 1 : g_assert_cmpstr (collection, ==, "/");
458 1 : g_assert_cmpstr (prompt, !=, "/");
459 :
460 : /*
461 : * Perform the password prompt to create the collection, which returns
462 : * the new collection path
463 : */
464 1 : result = prompt_password_perform (test, prompt, "booo", G_VARIANT_TYPE_OBJECT_PATH);
465 1 : g_variant_unref (retval);
466 :
467 1 : expect_signal_with_path (test, SECRET_SERVICE_PATH, SECRET_SERVICE_INTERFACE,
468 : "CollectionCreated", g_variant_get_string (result, NULL));
469 1 : expect_property_changed (test, SECRET_SERVICE_PATH,
470 : SECRET_SERVICE_INTERFACE, "Collections");
471 :
472 1 : g_variant_unref (result);
473 1 : }
474 :
475 : static void
476 1 : test_collection_created_no_prompt (Test *test,
477 : gconstpointer unused)
478 : {
479 : const gchar *collection;
480 1 : GError *error = NULL;
481 : GVariant *properties;
482 : GVariant *retval;
483 : GVariant *label;
484 :
485 : /* Create a new collection */
486 1 : label = g_variant_new_dict_entry (g_variant_new_string ("org.freedesktop.Secret.Collection.Label"),
487 : g_variant_new_variant (g_variant_new_string ("Without Prompt")));
488 1 : properties = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), &label, 1);
489 :
490 1 : retval = dbus_call_perform (test,
491 : SECRET_SERVICE_PATH,
492 : INTERNAL_SERVICE_INTERFACE,
493 : "CreateWithMasterPassword",
494 : g_variant_new ("(@a{sv}@(oayays))",
495 : properties,
496 : test_service_build_secret (&test->service, "booo")),
497 : G_VARIANT_TYPE ("(o)"),
498 : &error);
499 1 : g_assert_no_error (error);
500 :
501 1 : g_variant_get (retval, "(&o)", &collection);
502 1 : g_assert_cmpstr (collection, !=, "/");
503 :
504 1 : expect_signal_with_path (test, SECRET_SERVICE_PATH, SECRET_SERVICE_INTERFACE,
505 : "CollectionCreated", collection);
506 1 : expect_property_changed (test, SECRET_SERVICE_PATH,
507 : SECRET_SERVICE_INTERFACE, "Collections");
508 :
509 1 : g_variant_unref (retval);
510 1 : }
511 :
512 : static void
513 1 : test_collection_deleted (Test *test,
514 : gconstpointer unused)
515 : {
516 : const gchar *prompt;
517 1 : GError *error = NULL;
518 : GVariant *retval;
519 :
520 : /* Delete a collection */
521 1 : retval = dbus_call_perform (test,
522 : "/org/freedesktop/secrets/collection/test",
523 : SECRET_COLLECTION_INTERFACE,
524 : "Delete",
525 : g_variant_new ("()"),
526 : G_VARIANT_TYPE ("(o)"),
527 : &error);
528 1 : g_assert_no_error (error);
529 :
530 : /* Expect that no prompt is returned */
531 1 : g_variant_get (retval, "(&o)", &prompt);
532 1 : g_assert_cmpstr (prompt, ==, "/");
533 :
534 1 : expect_signal_with_path (test, SECRET_SERVICE_PATH, SECRET_SERVICE_INTERFACE,
535 : "CollectionDeleted", "/org/freedesktop/secrets/collection/test");
536 1 : expect_property_changed (test, SECRET_SERVICE_PATH,
537 : SECRET_SERVICE_INTERFACE, "Collections");
538 :
539 1 : g_variant_unref (retval);
540 1 : }
541 :
542 : static void
543 1 : test_collection_changed (Test *test,
544 : gconstpointer unused)
545 : {
546 1 : GError *error = NULL;
547 : GVariant *retval;
548 :
549 1 : retval = dbus_call_perform (test,
550 : "/org/freedesktop/secrets/collection/test",
551 : "org.freedesktop.DBus.Properties",
552 : "Set",
553 : g_variant_new ("(ssv)",
554 : SECRET_COLLECTION_INTERFACE,
555 : "Label",
556 : g_variant_new_string ("New label")),
557 : G_VARIANT_TYPE ("()"),
558 : &error);
559 1 : g_assert_no_error (error);
560 :
561 1 : expect_signal_with_path (test, SECRET_SERVICE_PATH,
562 : SECRET_SERVICE_INTERFACE, "CollectionChanged",
563 : "/org/freedesktop/secrets/collection/test");
564 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test",
565 : SECRET_COLLECTION_INTERFACE, "Label");
566 :
567 1 : g_variant_unref (retval);
568 1 : }
569 :
570 : static void
571 1 : test_collection_lock (Test *test,
572 : gconstpointer unused)
573 : {
574 1 : GError *error = NULL;
575 : const gchar *prompt;
576 : GVariant *element;
577 : GVariant *locked;
578 : GVariant *retval;
579 :
580 1 : element = g_variant_new_object_path ("/org/freedesktop/secrets/collection/test");
581 1 : retval = dbus_call_perform (test,
582 : SECRET_SERVICE_PATH,
583 : SECRET_SERVICE_INTERFACE,
584 : "Lock",
585 : g_variant_new ("(@ao)",
586 : g_variant_new_array (G_VARIANT_TYPE ("o"), &element, 1)),
587 : G_VARIANT_TYPE ("(aoo)"),
588 : &error);
589 1 : g_assert_no_error (error);
590 :
591 : /* Not expecting a prompt */
592 1 : g_variant_get (retval, "(@ao&o)", &locked, &prompt);
593 1 : g_assert_cmpstr (prompt, ==, "/");
594 1 : g_variant_unref (locked);
595 :
596 1 : expect_signal_with_path (test, SECRET_SERVICE_PATH,
597 : SECRET_SERVICE_INTERFACE, "CollectionChanged",
598 : "/org/freedesktop/secrets/collection/test");
599 1 : expect_signal_with_path (test, "/org/freedesktop/secrets/collection/test",
600 : SECRET_COLLECTION_INTERFACE, "ItemChanged",
601 : "/org/freedesktop/secrets/collection/test/1");
602 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test",
603 : SECRET_COLLECTION_INTERFACE, "Locked");
604 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test/1",
605 : SECRET_ITEM_INTERFACE, "Locked");
606 :
607 1 : g_variant_unref (retval);
608 1 : }
609 :
610 : static void
611 1 : test_collection_unlock (Test *test,
612 : gconstpointer unused)
613 : {
614 1 : GError *error = NULL;
615 : const gchar *prompt;
616 : GVariant *unlocked;
617 : GVariant *retval;
618 : GVariant *element;
619 :
620 1 : element = g_variant_new_object_path ("/org/freedesktop/secrets/collection/test");
621 1 : retval = dbus_call_perform (test,
622 : SECRET_SERVICE_PATH,
623 : SECRET_SERVICE_INTERFACE,
624 : "Unlock",
625 : g_variant_new ("(@ao)",
626 : g_variant_new_array (G_VARIANT_TYPE ("o"), &element, 1)),
627 : G_VARIANT_TYPE ("(aoo)"),
628 : &error);
629 1 : g_assert_no_error (error);
630 :
631 : /* Not expecting a prompt */
632 1 : g_variant_get (retval, "(@ao&o)", &unlocked, &prompt);
633 1 : g_assert_cmpstr (prompt, !=, "/");
634 1 : g_variant_unref (unlocked);
635 :
636 1 : unlocked = prompt_password_perform (test, prompt, "booo", G_VARIANT_TYPE ("ao"));
637 1 : g_variant_unref (unlocked);
638 :
639 1 : expect_signal_with_path (test, SECRET_SERVICE_PATH,
640 : SECRET_SERVICE_INTERFACE, "CollectionChanged",
641 : "/org/freedesktop/secrets/collection/test");
642 1 : expect_signal_with_path (test, "/org/freedesktop/secrets/collection/test",
643 : SECRET_COLLECTION_INTERFACE, "ItemChanged",
644 : "/org/freedesktop/secrets/collection/test/1");
645 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test",
646 : SECRET_COLLECTION_INTERFACE, "Locked");
647 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test/1",
648 : SECRET_ITEM_INTERFACE, "Locked");
649 :
650 1 : g_variant_unref (retval);
651 1 : }
652 :
653 : static void
654 1 : test_collection_unlock_no_prompt (Test *test,
655 : gconstpointer unused)
656 : {
657 1 : GError *error = NULL;
658 : GVariant *retval;
659 :
660 1 : retval = dbus_call_perform (test,
661 : SECRET_SERVICE_PATH,
662 : INTERNAL_SERVICE_INTERFACE,
663 : "UnlockWithMasterPassword",
664 : g_variant_new ("(o@(oayays))",
665 : "/org/freedesktop/secrets/collection/test",
666 : test_service_build_secret (&test->service, "booo")),
667 : G_VARIANT_TYPE ("()"),
668 : &error);
669 1 : g_assert_no_error (error);
670 :
671 1 : expect_signal_with_path (test, SECRET_SERVICE_PATH,
672 : SECRET_SERVICE_INTERFACE, "CollectionChanged",
673 : "/org/freedesktop/secrets/collection/test");
674 1 : expect_signal_with_path (test, "/org/freedesktop/secrets/collection/test",
675 : SECRET_COLLECTION_INTERFACE, "ItemChanged",
676 : "/org/freedesktop/secrets/collection/test/1");
677 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test",
678 : SECRET_COLLECTION_INTERFACE, "Locked");
679 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test/1",
680 : SECRET_ITEM_INTERFACE, "Locked");
681 :
682 1 : g_variant_unref (retval);
683 1 : }
684 :
685 : static void
686 1 : test_item_created (Test *test,
687 : gconstpointer unused)
688 : {
689 : const gchar *item;
690 : const gchar *prompt;
691 1 : GError *error = NULL;
692 : GVariant *properties;
693 : GVariant *retval;
694 : GVariant *label;
695 :
696 : /* Create a new collection */
697 1 : label = g_variant_new_dict_entry (g_variant_new_string ("org.freedesktop.Secret.Item.Label"),
698 : g_variant_new_variant (g_variant_new_string ("My Item")));
699 1 : properties = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), &label, 1);
700 :
701 1 : retval = dbus_call_perform (test,
702 : "/org/freedesktop/secrets/collection/test",
703 : SECRET_COLLECTION_INTERFACE,
704 : "CreateItem",
705 : g_variant_new ("(@a{sv}@(oayays)b)",
706 : properties,
707 : test_service_build_secret (&test->service, "booo"),
708 : FALSE),
709 : G_VARIANT_TYPE ("(oo)"),
710 : &error);
711 1 : g_assert_no_error (error);
712 :
713 : /* Not expecting a prompt */
714 1 : g_variant_get (retval, "(&o&o)", &item, &prompt);
715 1 : g_assert_cmpstr (item, !=, "/");
716 1 : g_assert_cmpstr (prompt, ==, "/");
717 :
718 1 : expect_signal_with_path (test, "/org/freedesktop/secrets/collection/test",
719 : SECRET_COLLECTION_INTERFACE, "ItemCreated", item);
720 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test",
721 : SECRET_COLLECTION_INTERFACE, "Items");
722 :
723 1 : g_variant_unref (retval);
724 1 : }
725 :
726 : static void
727 1 : test_item_deleted (Test *test,
728 : gconstpointer unused)
729 : {
730 : const gchar *prompt;
731 1 : GError *error = NULL;
732 : GVariant *retval;
733 :
734 1 : retval = dbus_call_perform (test,
735 : "/org/freedesktop/secrets/collection/test/1",
736 : SECRET_ITEM_INTERFACE,
737 : "Delete",
738 : g_variant_new ("()"),
739 : G_VARIANT_TYPE ("(o)"),
740 : &error);
741 1 : g_assert_no_error (error);
742 :
743 : /* Not expecting a prompt */
744 1 : g_variant_get (retval, "(&o)", &prompt);
745 1 : g_assert_cmpstr (prompt, ==, "/");
746 :
747 1 : expect_signal_with_path (test, "/org/freedesktop/secrets/collection/test",
748 : SECRET_COLLECTION_INTERFACE, "ItemDeleted",
749 : "/org/freedesktop/secrets/collection/test/1");
750 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test",
751 : SECRET_COLLECTION_INTERFACE, "Items");
752 :
753 1 : g_variant_unref (retval);
754 1 : }
755 :
756 : static void
757 1 : test_item_changed (Test *test,
758 : gconstpointer unused)
759 : {
760 1 : GError *error = NULL;
761 : GVariant *retval;
762 :
763 1 : retval = dbus_call_perform (test,
764 : "/org/freedesktop/secrets/collection/test/1",
765 : "org.freedesktop.DBus.Properties",
766 : "Set",
767 : g_variant_new ("(ssv)",
768 : SECRET_ITEM_INTERFACE,
769 : "Label",
770 : g_variant_new_string ("New label")),
771 : G_VARIANT_TYPE ("()"),
772 : &error);
773 1 : g_assert_no_error (error);
774 :
775 1 : expect_signal_with_path (test, "/org/freedesktop/secrets/collection/test",
776 : SECRET_COLLECTION_INTERFACE, "ItemChanged",
777 : "/org/freedesktop/secrets/collection/test/1");
778 1 : expect_property_changed (test, "/org/freedesktop/secrets/collection/test/1",
779 : SECRET_ITEM_INTERFACE, "Label");
780 :
781 1 : g_variant_unref (retval);
782 1 : }
783 :
784 : int
785 1 : main (int argc, char **argv)
786 : {
787 : #if !GLIB_CHECK_VERSION(2,35,0)
788 : g_type_init ();
789 : #endif
790 1 : g_test_init (&argc, &argv, NULL);
791 :
792 1 : g_test_add ("/secret-signals/collection-created", Test, NULL,
793 : setup, test_collection_created, teardown);
794 1 : g_test_add ("/secret-signals/collection-created-no-prompt", Test, NULL,
795 : setup, test_collection_created_no_prompt, teardown);
796 1 : g_test_add ("/secret-signals/collection-changed", Test, NULL,
797 : setup, test_collection_changed, teardown);
798 1 : g_test_add ("/secret-signals/collection-deleted", Test, NULL,
799 : setup, test_collection_deleted, teardown);
800 1 : g_test_add ("/secret-signals/collection-lock", Test, NULL,
801 : setup, test_collection_lock, teardown);
802 1 : g_test_add ("/secret-signals/collection-unlock", Test, NULL,
803 : setup_locked, test_collection_unlock, teardown);
804 1 : g_test_add ("/secret-signals/collection-unlock-no-prompt", Test, NULL,
805 : setup_locked, test_collection_unlock_no_prompt, teardown);
806 1 : g_test_add ("/secret-signals/item-created", Test, NULL,
807 : setup, test_item_created, teardown);
808 1 : g_test_add ("/secret-signals/item-changed", Test, NULL,
809 : setup, test_item_changed, teardown);
810 1 : g_test_add ("/secret-signals/item-deleted", Test, NULL,
811 : setup, test_item_deleted, teardown);
812 :
813 1 : return egg_tests_run_with_loop ();
814 : }
|