g_object_unref (async);
}
-static GHashTable *
-collection_properties_new (const gchar *label)
+GHashTable *
+_secret_collection_properties_new (const gchar *label)
{
GHashTable *properties;
GVariant *value;
secret_collection_create);
closure = g_slice_new0 (CreateClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- closure->properties = collection_properties_new (label);
+ closure->properties = _secret_collection_properties_new (label);
closure->alias = g_strdup (alias);
closure->flags = flags;
g_simple_async_result_set_op_res_gpointer (res, closure, create_closure_free);
g_object_ref (service);
}
- properties = collection_properties_new (label);
+ properties = _secret_collection_properties_new (label);
path = secret_service_create_collection_dbus_path_sync (service, properties, alias,
flags, cancellable, error);
gchar *collection_path;
SecretValue *value;
GHashTable *properties;
+ gboolean created_collection;
} StoreClosure;
static void
static void
on_store_create (GObject *source,
GAsyncResult *result,
- gpointer user_data)
+ gpointer user_data);
+
+static void
+on_store_keyring (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
{
GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
+ StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
+ SecretService *service = SECRET_SERVICE (source);
GError *error = NULL;
gchar *path;
- path = secret_service_create_item_dbus_path_finish (SECRET_SERVICE (source), result, &error);
- if (error != NULL)
+ path = secret_service_create_collection_dbus_path_finish (service, result, &error);
+ if (error == NULL) {
+ store->created_collection = TRUE;
+ secret_service_create_item_dbus_path (service, store->collection_path,
+ store->properties, store->value,
+ SECRET_ITEM_CREATE_REPLACE, store->cancellable,
+ on_store_create, g_object_ref (async));
+ } else {
g_simple_async_result_take_error (async, error);
+ g_simple_async_result_complete (async);
+ }
+
+ g_object_unref (async);
g_free (path);
+}
- g_simple_async_result_complete (async);
+static void
+on_store_create (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data);
+ StoreClosure *store = g_simple_async_result_get_op_res_gpointer (async);
+ SecretService *service = SECRET_SERVICE (source);
+ GError *error = NULL;
+ GHashTable *properties;
+ gchar *path;
+
+ path = secret_service_create_item_dbus_path_finish (service, result, &error);
+
+ /*
+ * This happens when the collection doesn't exist. If the collection is
+ * the default alias, we should try and create it
+ */
+
+ if (!store->created_collection &&
+ (g_error_matches (error, SECRET_ERROR, SECRET_ERROR_NO_SUCH_OBJECT) ||
+ g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) &&
+ g_strcmp0 (store->collection_path, SECRET_ALIAS_PREFIX "default") == 0) {
+ properties = _secret_collection_properties_new ("Default keyring");
+ secret_service_create_collection_dbus_path (service, properties, "default",
+ SECRET_COLLECTION_CREATE_NONE, store->cancellable,
+ on_store_keyring, g_object_ref (async));
+ g_hash_table_unref (properties);
+ g_error_free (error);
+
+ } else {
+ if (error != NULL)
+ g_simple_async_result_take_error (async, error);
+ g_simple_async_result_complete (async);
+ }
+
+ g_free (path);
g_object_unref (async);
}
typedef struct _SecretSession SecretSession;
+#define SECRET_ALIAS_PREFIX "/org/freedesktop/secrets/aliases/"
+
#define SECRET_SERVICE_PATH "/org/freedesktop/secrets"
#define SECRET_SERVICE_BUS_NAME "org.freedesktop.secrets"
gchar ***xlocked,
GError **error);
+GHashTable * _secret_collection_properties_new (const gchar *label);
+
SecretItem * _secret_collection_find_item_instance (SecretCollection *self,
const gchar *item_path);
--- /dev/null
+#!/usr/bin/env python
+
+#
+# Copyright 2012 Red Hat Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the licence or (at
+# your option) any later version.
+#
+# See the included COPYING file for more information.
+#
+
+import mock
+
+service = mock.SecretService()
+service.listen()
}
static void
+test_store_no_default (Test *test,
+ gconstpointer used)
+{
+ SecretValue *value = secret_value_new ("apassword", -1, "text/plain");
+ GHashTable *attributes;
+ GError *error = NULL;
+ gchar **paths;
+ gboolean ret;
+ gsize length;
+
+ attributes = secret_attributes_build (&MOCK_SCHEMA,
+ "even", FALSE,
+ "string", "seventeen",
+ "number", 17,
+ NULL);
+
+ ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, attributes, SECRET_COLLECTION_DEFAULT,
+ "New Item Label", value, NULL, &error);
+ g_assert_no_error (error);
+ secret_value_unref (value);
+ g_hash_table_unref (attributes);
+
+ attributes = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (attributes, "even", "false");
+ g_hash_table_insert (attributes, "string", "seventeen");
+ g_hash_table_insert (attributes, "number", "17");
+
+ ret = secret_service_search_for_dbus_paths_sync (test->service, &MOCK_SCHEMA, attributes,
+ NULL, &paths, NULL, &error);
+ g_hash_table_unref (attributes);
+ g_assert (ret == TRUE);
+
+ g_assert (paths != NULL);
+ g_assert (paths[0] != NULL);
+ g_assert (paths[1] == NULL);
+
+ value = secret_service_get_secret_for_dbus_path_sync (test->service, paths[0],
+ NULL, &error);
+ g_assert_no_error (error);
+
+ g_assert (value != NULL);
+ g_assert_cmpstr (secret_value_get (value, &length), ==, "apassword");
+ g_assert_cmpuint (length, ==, 9);
+
+ secret_value_unref (value);
+ g_strfreev (paths);
+}
+
+static void
test_set_alias_sync (Test *test,
gconstpointer used)
{
g_test_add ("/service/store-sync", Test, "mock-service-normal.py", setup, test_store_sync, teardown);
g_test_add ("/service/store-async", Test, "mock-service-normal.py", setup, test_store_async, teardown);
g_test_add ("/service/store-replace", Test, "mock-service-normal.py", setup, test_store_replace, teardown);
+ g_test_add ("/service/store-no-default", Test, "mock-service-empty.py", setup, test_store_no_default, teardown);
g_test_add ("/service/set-alias-sync", Test, "mock-service-normal.py", setup, test_set_alias_sync, teardown);