From 89550876ff1345e3f348d88a9be46261486c876f Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 28 Jun 2012 13:15:06 +0200 Subject: [PATCH] Remove varargs SecretService methods * The SecretService methods aren't used as frequently as the password methods, and it's not really necessary to have a whole bunch of extra varargs functions. * Add varargs functions for building a GHashTable of attributes --- docs/reference/libsecret/libsecret-docs.sgml | 1 + docs/reference/libsecret/libsecret-sections.txt | 13 +- library/Makefile.am | 2 + library/secret-attributes.c | 276 ++++++++++++++++ library/secret-attributes.h | 38 +++ library/secret-item.c | 8 +- library/secret-methods.c | 406 +++--------------------- library/secret-password.c | 61 ++-- library/secret-private.h | 11 +- library/secret-service.h | 45 --- library/secret-unstable.h | 1 + library/secret-util.c | 199 ------------ library/tests/test-methods.c | 201 +++++++----- tool/secret-tool.c | 6 +- 14 files changed, 539 insertions(+), 729 deletions(-) create mode 100644 library/secret-attributes.c create mode 100644 library/secret-attributes.h diff --git a/docs/reference/libsecret/libsecret-docs.sgml b/docs/reference/libsecret/libsecret-docs.sgml index 8225e61..3ec04c1 100644 --- a/docs/reference/libsecret/libsecret-docs.sgml +++ b/docs/reference/libsecret/libsecret-docs.sgml @@ -27,6 +27,7 @@ + diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt index 584bf30..c9fcdff 100644 --- a/docs/reference/libsecret/libsecret-sections.txt +++ b/docs/reference/libsecret/libsecret-sections.txt @@ -206,20 +206,14 @@ secret_service_unlock_paths secret_service_unlock_paths_finish secret_service_unlock_paths_sync secret_service_store -secret_service_storev secret_service_store_finish secret_service_store_sync -secret_service_storev_sync secret_service_lookup -secret_service_lookupv secret_service_lookup_finish secret_service_lookup_sync -secret_service_lookupv_sync secret_service_remove -secret_service_removev secret_service_remove_finish secret_service_remove_sync -secret_service_removev_sync secret_service_prompt secret_service_prompt_finish secret_service_prompt_sync @@ -276,6 +270,13 @@ secret_value_get_type
+secret-attributes +secret/secret-unstable.h +secret_attributes_build +secret_attributes_buildv +
+ +
SecretGenService
diff --git a/library/Makefile.am b/library/Makefile.am index 3acea9f..06ddfdf 100644 --- a/library/Makefile.am +++ b/library/Makefile.am @@ -22,6 +22,7 @@ incdir = $(includedir)/secret-@SECRET_MAJOR@/secret HEADER_FILES = \ secret.h \ + secret-attributes.h \ secret-collection.h \ secret-item.h \ secret-password.h \ @@ -45,6 +46,7 @@ BUILT_SOURCES = \ $(NULL) PUBLIC_FILES = \ + secret-attributes.h secret-attributes.c \ secret-collection.h secret-collection.c \ secret-item.h secret-item.c \ secret-methods.c \ diff --git a/library/secret-attributes.c b/library/secret-attributes.c new file mode 100644 index 0000000..298101b --- /dev/null +++ b/library/secret-attributes.c @@ -0,0 +1,276 @@ +/* libsecret - GLib wrapper for Secret Service + * + * Copyright 2011 Collabora Ltd. + * + * 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. + * + * Author: Stef Walter + */ + +#include "config.h" + +#include "secret-attributes.h" +#include "secret-private.h" + +#include + +/** + * SECTION:secret-attributes + * @title: Secret Attributes + * @short_description: secret attributes + * + * Each item has a set of attributes, which are used to locate the item later. + * These are not stored or transferred in a secure manner. Each attribute has + * a string name and a string value. These attributes are represented by a + * #GHashTable with string keys and values. + * + * Use secret_attributes_build() to simply build up a set of attributes. + */ + +GVariant * +_secret_attributes_to_variant (GHashTable *attributes, + const gchar *schema_name) +{ + GHashTableIter iter; + GVariantBuilder builder; + const gchar *name; + const gchar *value; + + g_return_val_if_fail (attributes != NULL, NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + + g_hash_table_iter_init (&iter, attributes); + while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&value)) { + if (!schema_name || !g_str_equal (name, "xdg:schema")) + g_variant_builder_add (&builder, "{ss}", name, value); + } + + if (schema_name) + g_variant_builder_add (&builder, "{ss}", "xdg:schema", schema_name); + + return g_variant_builder_end (&builder); +} + +GHashTable * +_secret_attributes_for_variant (GVariant *variant) +{ + GVariantIter iter; + GHashTable *attributes; + gchar *value; + gchar *key; + + attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "{ss}", &key, &value)) + g_hash_table_insert (attributes, key, value); + + return attributes; +} + +/** + * secret_attributes_build: (skip) + * @schema: the schema for the attributes + * @...: the attribute keys and values, terminated with %NULL + * + * Build up a hash table of attribute values. + * + * The variable argument list should contain pairs of a) The attribute name as + * a null-terminated string, followed by b) attribute value, either a character + * string, an int number, or a gboolean value, as defined in the password + * @schema. The list of attribtues should be terminated with a %NULL. + * + * Returns: (transfer full): a new table of attributes, to be released with + * g_hash_table_unref() + */ +GHashTable * +secret_attributes_build (const SecretSchema *schema, + ...) +{ + GHashTable *attributes; + va_list va; + + va_start (va, schema); + attributes = secret_attributes_buildv (schema, va); + va_end (va); + + return attributes; +} + +/** + * secret_attributes_buildv: (skip) + * @schema: the schema for the attributes + * @va: the attribute keys and values, terminated with %NULL + * + * Build up a hash table of attribute values. + * + * The variable argument list should contain pairs of a) The attribute name as + * a null-terminated string, followed by b) attribute value, either a character + * string, an int number, or a gboolean value, as defined in the password + * @schema. The list of attribtues should be terminated with a %NULL. + * + * Returns: (transfer full): a new table of attributes, to be released with + * g_hash_table_unref() + */ +GHashTable * +secret_attributes_buildv (const SecretSchema *schema, + va_list va) +{ + const gchar *attribute_name; + SecretSchemaAttributeType type; + GHashTable *attributes; + const gchar *string; + gboolean type_found; + gchar *value = NULL; + gboolean boolean; + gint integer; + gint i; + + g_return_val_if_fail (schema != NULL, NULL); + + attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + for (;;) { + attribute_name = va_arg (va, const gchar *); + if (attribute_name == NULL) + break; + + type_found = FALSE; + for (i = 0; i < G_N_ELEMENTS (schema->attributes); ++i) { + if (!schema->attributes[i].name) + break; + if (g_str_equal (schema->attributes[i].name, attribute_name)) { + type_found = TRUE; + type = schema->attributes[i].type; + break; + } + } + + if (!type_found) { + g_warning ("The attribute '%s' was not found in the password schema.", attribute_name); + g_hash_table_unref (attributes); + return NULL; + } + + switch (type) { + case SECRET_SCHEMA_ATTRIBUTE_BOOLEAN: + boolean = va_arg (va, gboolean); + value = g_strdup (boolean ? "true" : "false"); + break; + case SECRET_SCHEMA_ATTRIBUTE_STRING: + string = va_arg (va, gchar *); + if (!g_utf8_validate (string, -1, NULL)) { + g_warning ("The value for attribute '%s' was not a valid utf-8 string.", attribute_name); + g_hash_table_unref (attributes); + return NULL; + } + value = g_strdup (string); + break; + case SECRET_SCHEMA_ATTRIBUTE_INTEGER: + integer = va_arg (va, gint); + value = g_strdup_printf ("%d", integer); + break; + default: + g_warning ("The password attribute '%s' has an invalid type in the password schema.", attribute_name); + g_hash_table_unref (attributes); + return NULL; + } + + g_hash_table_insert (attributes, g_strdup (attribute_name), value); + } + + return attributes; +} + +gboolean +_secret_attributes_validate (const SecretSchema *schema, + GHashTable *attributes) +{ + const SecretSchemaAttribute *attribute; + GHashTableIter iter; + gchar *key; + gchar *value; + gchar *end; + gint i; + + g_return_val_if_fail (schema != NULL, FALSE); + + g_hash_table_iter_init (&iter, attributes); + while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value)) { + + /* Find the attribute */ + attribute = NULL; + for (i = 0; i < G_N_ELEMENTS (schema->attributes); i++) { + if (schema->attributes[i].name == NULL) + break; + if (g_str_equal (schema->attributes[i].name, key)) { + attribute = &schema->attributes[i]; + break; + } + } + + if (attribute == NULL) { + g_warning ("invalid %s attribute in for %s schema", + key, schema->name); + return FALSE; + } + + switch (attribute->type) { + case SECRET_SCHEMA_ATTRIBUTE_BOOLEAN: + if (!g_str_equal (value, "true") && !g_str_equal (value, "false")) { + g_warning ("invalid %s boolean value for %s schema: %s", + key, schema->name, value); + return FALSE; + } + break; + case SECRET_SCHEMA_ATTRIBUTE_INTEGER: + end = NULL; + g_ascii_strtoll (value, &end, 10); + if (!end || end[0] != '\0') { + g_warning ("invalid %s integer value for %s schema: %s", + key, schema->name, value); + return FALSE; + } + break; + case SECRET_SCHEMA_ATTRIBUTE_STRING: + if (!g_utf8_validate (value, -1, NULL)) { + g_warning ("invalid %s string value for %s schema: %s", + key, schema->name, value); + return FALSE; + } + break; + default: + g_warning ("invalid %s value type in %s schema", + key, schema->name); + return FALSE; + } + } + + return TRUE; +} + +GHashTable * +_secret_attributes_copy (GHashTable *attributes) +{ + GHashTableIter iter; + GHashTable *copy; + gchar *key; + gchar *value; + + if (attributes == NULL) + return NULL; + + copy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_hash_table_iter_init (&iter, attributes); + while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value)) + g_hash_table_insert (copy, g_strdup (key), g_strdup (value)); + + return copy; +} diff --git a/library/secret-attributes.h b/library/secret-attributes.h new file mode 100644 index 0000000..91c2735 --- /dev/null +++ b/library/secret-attributes.h @@ -0,0 +1,38 @@ +/* libsecret - GLib wrapper for Secret Service + * + * 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. + * + * Author: Stef Walter + */ + +#if !defined (__SECRET_INSIDE_HEADER__) && !defined (SECRET_COMPILATION) +#error "Only or can be included directly." +#endif + +#ifndef __SECRET_ATTRIBUTES_H__ +#define __SECRET_ATTRIBUTES_H__ + +#include +#include + +#include "secret-schema.h" + +G_BEGIN_DECLS + +GHashTable * secret_attributes_build (const SecretSchema *schema, + ...); + +GHashTable * secret_attributes_buildv (const SecretSchema *schema, + va_list va); + + +G_END_DECLS + +#endif /* __SECRET_ATTRIBUTES_H___ */ diff --git a/library/secret-item.c b/library/secret-item.c index 1b8a9fc..4435a91 100644 --- a/library/secret-item.c +++ b/library/secret-item.c @@ -641,7 +641,7 @@ item_properties_new (const gchar *label, SECRET_ITEM_INTERFACE ".Label", g_variant_ref_sink (value)); - value = _secret_util_variant_for_attributes (attributes, NULL); + value = _secret_attributes_to_variant (attributes, NULL); g_hash_table_insert (properties, SECRET_ITEM_INTERFACE ".Attributes", g_variant_ref_sink (value)); @@ -1348,7 +1348,7 @@ secret_item_get_attributes (SecretItem *self) variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Attributes"); g_return_val_if_fail (variant != NULL, NULL); - attributes = _secret_util_attributes_for_variant (variant); + attributes = _secret_attributes_for_variant (variant); g_variant_unref (variant); return attributes; @@ -1381,7 +1381,7 @@ secret_item_set_attributes (SecretItem *self, g_return_if_fail (attributes != NULL); _secret_util_set_property (G_DBUS_PROXY (self), "Attributes", - _secret_util_variant_for_attributes (attributes, NULL), + _secret_attributes_to_variant (attributes, NULL), secret_item_set_attributes, cancellable, callback, user_data); } @@ -1436,7 +1436,7 @@ secret_item_set_attributes_sync (SecretItem *self, g_return_val_if_fail (attributes != NULL, FALSE); return _secret_util_set_property_sync (G_DBUS_PROXY (self), "Attributes", - _secret_util_variant_for_attributes (attributes, NULL), + _secret_attributes_to_variant (attributes, NULL), cancellable, error); } diff --git a/library/secret-methods.c b/library/secret-methods.c index 816d3a0..b380939 100644 --- a/library/secret-methods.c +++ b/library/secret-methods.c @@ -73,7 +73,7 @@ secret_service_search_for_paths (SecretService *self, g_return_if_fail (attributes != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); - _secret_service_search_for_paths_variant (self, _secret_util_variant_for_attributes (attributes, NULL), + _secret_service_search_for_paths_variant (self, _secret_attributes_to_variant (attributes, NULL), cancellable, callback, user_data); } @@ -205,7 +205,7 @@ secret_service_search_for_paths_sync (SecretService *self, response = g_dbus_proxy_call_sync (G_DBUS_PROXY (self), "SearchItems", g_variant_new ("(@a{ss})", - _secret_util_variant_for_attributes (attributes, NULL)), + _secret_attributes_to_variant (attributes, NULL)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (response != NULL) { @@ -1758,21 +1758,18 @@ secret_service_unlock_sync (SecretService *self, /** * secret_service_store: * @self: the secret service - * @schema: the schema for the attributes + * @schema: (allow-none): the schema to use to check attributes + * @attributes: (element-type utf8 utf8): the attribute keys and values * @collection_path: (allow-none): the D-Bus path to the collection where to store the secret * @label: label for the secret * @value: the secret value * @cancellable: optional cancellation object * @callback: called when the operation completes * @user_data: data to be passed to the callback - * @...: the attribute keys and values, terminated with %NULL * * Store a secret value in the secret service. * - * The variable argument list should contain pairs of a) The attribute name as - * a null-terminated string, followed by b) attribute value, either a character - * string, an int number, or a gboolean value, as defined in the password - * @schema. The list of attribtues should be terminated with a %NULL. + * The @attributes should be a set of key and value string pairs. * * If the attributes match a secret item already stored in the collection, then * the item will be updated with these new values. @@ -1786,67 +1783,13 @@ secret_service_unlock_sync (SecretService *self, void secret_service_store (SecretService *self, const SecretSchema *schema, + GHashTable *attributes, const gchar *collection_path, const gchar *label, SecretValue *value, GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data, - ...) -{ - GHashTable *attributes; - va_list va; - - g_return_if_fail (SECRET_IS_SERVICE (self)); - g_return_if_fail (schema != NULL); - g_return_if_fail (label != NULL); - g_return_if_fail (value != NULL); - - va_start (va, user_data); - attributes = _secret_util_attributes_for_varargs (schema, va); - va_end (va); - - secret_service_storev (self, schema, attributes, collection_path, - label, value, cancellable, callback, user_data); - - g_hash_table_unref (attributes); -} - -/** - * secret_service_storev: - * @self: the secret service - * @schema: (allow-none): the schema to use to check attributes - * @attributes: (element-type utf8 utf8): the attribute keys and values - * @collection_path: (allow-none): the D-Bus path to the collection where to store the secret - * @label: label for the secret - * @value: the secret value - * @cancellable: optional cancellation object - * @callback: called when the operation completes - * @user_data: data to be passed to the callback - * - * Store a secret value in the secret service. - * - * The @attributes should be a set of key and value string pairs. - * - * If the attributes match a secret item already stored in the collection, then - * the item will be updated with these new values. - * - * If @collection_path is not specified, then the default collection will be - * used. Use #SECRET_COLLECTION_SESSION to store the password in the session - * collection, which doesn't get stored across login sessions. - * - * This method will return immediately and complete asynchronously. - */ -void -secret_service_storev (SecretService *self, - const SecretSchema *schema, - GHashTable *attributes, - const gchar *collection_path, - const gchar *label, - SecretValue *value, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) + gpointer user_data) { const gchar *schema_name; GHashTable *properties; @@ -1859,7 +1802,7 @@ secret_service_storev (SecretService *self, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* Warnings raised already */ - if (schema != NULL && !_secret_util_attributes_validate (schema, attributes)) + if (schema != NULL && !_secret_attributes_validate (schema, attributes)) return; properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, @@ -1872,7 +1815,7 @@ secret_service_storev (SecretService *self, /* Always store the schema name in the attributes */ schema_name = (schema == NULL) ? NULL : schema->name; - propval = _secret_util_variant_for_attributes (attributes, schema_name); + propval = _secret_attributes_to_variant (attributes, schema_name); g_hash_table_insert (properties, SECRET_ITEM_INTERFACE ".Attributes", g_variant_ref_sink (propval)); @@ -1912,20 +1855,17 @@ secret_service_store_finish (SecretService *self, /** * secret_service_store_sync: * @self: the secret service - * @schema: the schema for the attributes + * @schema: (allow-none): the schema for the attributes + * @attributes: (element-type utf8 utf8): the attribute keys and values * @collection_path: (allow-none): the D-Bus path to the collection where to store the secret * @label: label for the secret * @value: the secret value * @cancellable: optional cancellation object * @error: location to place an error on failure - * @...: the attribute keys and values, terminated with %NULL * * Store a secret value in the secret service. * - * The variable argument list should contain pairs of a) The attribute name as - * a null-terminated string, followed by b) attribute value, either a character - * string, an int number, or a gboolean value, as defined in the password - * @schema. The list of attribtues should be terminated with a %NULL. + * The @attributes should be a set of key and value string pairs. * * If the attributes match a secret item already stored in the collection, then * the item will be updated with these new values. @@ -1942,72 +1882,12 @@ secret_service_store_finish (SecretService *self, gboolean secret_service_store_sync (SecretService *self, const SecretSchema *schema, + GHashTable *attributes, const gchar *collection_path, const gchar *label, SecretValue *value, GCancellable *cancellable, - GError **error, - ...) -{ - GHashTable *attributes; - gboolean ret; - va_list va; - - g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE); - g_return_val_if_fail (schema != NULL, FALSE); - g_return_val_if_fail (label != NULL, FALSE); - g_return_val_if_fail (value != NULL, FALSE); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - va_start (va, error); - attributes = _secret_util_attributes_for_varargs (schema, va); - va_end (va); - - ret = secret_service_storev_sync (self, schema, attributes, collection_path, - label, value, cancellable, error); - - g_hash_table_unref (attributes); - - return ret; -} - -/** - * secret_service_storev_sync: - * @self: the secret service - * @schema: (allow-none): the schema for the attributes - * @attributes: (element-type utf8 utf8): the attribute keys and values - * @collection_path: (allow-none): the D-Bus path to the collection where to store the secret - * @label: label for the secret - * @value: the secret value - * @cancellable: optional cancellation object - * @error: location to place an error on failure - * - * Store a secret value in the secret service. - * - * The @attributes should be a set of key and value string pairs. - * - * If the attributes match a secret item already stored in the collection, then - * the item will be updated with these new values. - * - * If @collection_path is %NULL, then the default collection will be - * used. Use #SECRET_COLLECTION_SESSION to store the password in the session - * collection, which doesn't get stored across login sessions. - * - * This method may block indefinitely and should not be used in user interface - * threads. - * - * Returns: whether the storage was successful or not - */ -gboolean -secret_service_storev_sync (SecretService *self, - const SecretSchema *schema, - GHashTable *attributes, - const gchar *collection_path, - const gchar *label, - SecretValue *value, - GCancellable *cancellable, - GError **error) + GError **error) { SecretSync *sync; gboolean ret; @@ -2020,13 +1900,13 @@ secret_service_storev_sync (SecretService *self, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* Warnings raised already */ - if (schema != NULL && !_secret_util_attributes_validate (schema, attributes)) + if (schema != NULL && !_secret_attributes_validate (schema, attributes)) return FALSE; sync = _secret_sync_new (); g_main_context_push_thread_default (sync->context); - secret_service_storev (self, schema, attributes, collection_path, + secret_service_store (self, schema, attributes, collection_path, label, value, cancellable, _secret_sync_on_result, sync); g_main_loop_run (sync->loop); @@ -2054,49 +1934,6 @@ lookup_closure_free (gpointer data) g_slice_free (LookupClosure, closure); } -/** - * secret_service_lookup: - * @self: the secret service - * @schema: the schema for the attributes - * @cancellable: optional cancellation object - * @callback: called when the operation completes - * @user_data: data to be passed to the callback - * @...: the attribute keys and values, terminated with %NULL - * - * Lookup a secret value in the secret service. - * - * The variable argument list should contain pairs of a) The attribute name as - * a null-terminated string, followed by b) attribute value, either a character - * string, an int number, or a gboolean value, as defined in the password - * @schema. The list of attribtues should be terminated with a %NULL. - * - * This method will return immediately and complete asynchronously. - */ -void -secret_service_lookup (SecretService *self, - const SecretSchema *schema, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data, - ...) -{ - GHashTable *attributes; - va_list va; - - g_return_if_fail (SECRET_IS_SERVICE (self)); - g_return_if_fail (schema != NULL); - g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); - - va_start (va, user_data); - attributes = _secret_util_attributes_for_varargs (schema, va); - va_end (va); - - secret_service_lookupv (self, schema, attributes, cancellable, - callback, user_data); - - g_hash_table_unref (attributes); -} - static void on_lookup_get_secret (GObject *source, GAsyncResult *result, @@ -2186,7 +2023,7 @@ on_lookup_searched (GObject *source, } /** - * secret_service_lookupv: + * secret_service_lookup: * @self: the secret service * @schema: (allow-none): the schema for the attributes * @attributes: (element-type utf8 utf8): the attribute keys and values @@ -2201,12 +2038,12 @@ on_lookup_searched (GObject *source, * This method will return immediately and complete asynchronously. */ void -secret_service_lookupv (SecretService *self, - const SecretSchema *schema, - GHashTable *attributes, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +secret_service_lookup (SecretService *self, + const SecretSchema *schema, + GHashTable *attributes, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { const gchar *schema_name = NULL; GSimpleAsyncResult *res; @@ -2218,18 +2055,18 @@ secret_service_lookupv (SecretService *self, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* Warnings raised already */ - if (schema != NULL && !_secret_util_attributes_validate (schema, attributes)) + if (schema != NULL && !_secret_attributes_validate (schema, attributes)) return; res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, - secret_service_lookupv); + secret_service_lookup); closure = g_slice_new0 (LookupClosure); closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; g_simple_async_result_set_op_res_gpointer (res, closure, lookup_closure_free); if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME)) schema_name = schema->name; - variant = _secret_util_variant_for_attributes (attributes, schema_name); + variant = _secret_attributes_to_variant (attributes, schema_name); _secret_service_search_for_paths_variant (self, variant, cancellable, on_lookup_searched, g_object_ref (res)); @@ -2262,7 +2099,7 @@ secret_service_lookup_finish (SecretService *self, g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), - secret_service_lookupv), NULL); + secret_service_lookup), NULL); res = G_SIMPLE_ASYNC_RESULT (result); if (g_simple_async_result_propagate_error (res, error)) @@ -2277,55 +2114,6 @@ secret_service_lookup_finish (SecretService *self, /** * secret_service_lookup_sync: * @self: the secret service - * @schema: the schema for the attributes - * @cancellable: optional cancellation object - * @error: location to place an error on failure - * @...: the attribute keys and values, terminated with %NULL - * - * Lookup a secret value in the secret service. - * - * The variable argument list should contain pairs of a) The attribute name as - * a null-terminated string, followed by b) attribute value, either a character - * string, an int number, or a gboolean value, as defined in the password - * @schema. The list of attribtues should be terminated with a %NULL. - * - * If no secret is found then %NULL is returned. - * - * This method may block indefinitely and should not be used in user interface - * threads. - * - * Returns: (transfer full): a newly allocated #SecretValue, which should be - * released with secret_value_unref(), or %NULL if no secret found - */ -SecretValue * -secret_service_lookup_sync (SecretService *self, - const SecretSchema *schema, - GCancellable *cancellable, - GError **error, - ...) -{ - GHashTable *attributes; - SecretValue *value; - va_list va; - - g_return_val_if_fail (SECRET_IS_SERVICE (self), NULL); - g_return_val_if_fail (schema != NULL, NULL); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); - - va_start (va, error); - attributes = _secret_util_attributes_for_varargs (schema, va); - va_end (va); - - value = secret_service_lookupv_sync (self, schema, attributes, cancellable, error); - - g_hash_table_unref (attributes); - - return value; -} - -/** - * secret_service_lookupv_sync: - * @self: the secret service * @schema: (allow-none): the schema for the attributes * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object @@ -2342,11 +2130,11 @@ secret_service_lookup_sync (SecretService *self, * released with secret_value_unref(), or %NULL if no secret found */ SecretValue * -secret_service_lookupv_sync (SecretService *self, - const SecretSchema *schema, - GHashTable *attributes, - GCancellable *cancellable, - GError **error) +secret_service_lookup_sync (SecretService *self, + const SecretSchema *schema, + GHashTable *attributes, + GCancellable *cancellable, + GError **error) { SecretSync *sync; SecretValue *value; @@ -2356,14 +2144,14 @@ secret_service_lookupv_sync (SecretService *self, g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); /* Warnings raised already */ - if (schema != NULL && !_secret_util_attributes_validate (schema, attributes)) + if (schema != NULL && !_secret_attributes_validate (schema, attributes)) return NULL; sync = _secret_sync_new (); g_main_context_push_thread_default (sync->context); - secret_service_lookupv (self, schema, attributes, cancellable, - _secret_sync_on_result, sync); + secret_service_lookup (self, schema, attributes, cancellable, + _secret_sync_on_result, sync); g_main_loop_run (sync->loop); @@ -2661,18 +2449,15 @@ on_search_delete_password (GObject *source, /** * secret_service_remove: * @self: the secret service - * @schema: the schema for the attributes + * @schema: (allow-none): the schema for the attributes + * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object * @callback: called when the operation completes * @user_data: data to be passed to the callback - * @...: the attribute keys and values, terminated with %NULL * * Remove a secret value from the secret service. * - * The variable argument list should contain pairs of a) The attribute name as - * a null-terminated string, followed by b) attribute value, either a character - * string, an int number, or a gboolean value, as defined in the password - * @schema. The list of attribtues should be terminated with a %NULL. + * The @attributes should be a set of key and value string pairs. * * If multiple items match the attributes, then only one will be deleted. * @@ -2681,52 +2466,10 @@ on_search_delete_password (GObject *source, void secret_service_remove (SecretService *self, const SecretSchema *schema, + GHashTable *attributes, GCancellable *cancellable, GAsyncReadyCallback callback, - gpointer user_data, - ...) -{ - GHashTable *attributes; - va_list va; - - g_return_if_fail (SECRET_SERVICE (self)); - g_return_if_fail (schema != NULL); - g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); - - va_start (va, user_data); - attributes = _secret_util_attributes_for_varargs (schema, va); - va_end (va); - - secret_service_removev (self, schema, attributes, cancellable, - callback, user_data); - - g_hash_table_unref (attributes); -} - -/** - * secret_service_removev: - * @self: the secret service - * @schema: (allow-none): the schema for the attributes - * @attributes: (element-type utf8 utf8): the attribute keys and values - * @cancellable: optional cancellation object - * @callback: called when the operation completes - * @user_data: data to be passed to the callback - * - * Remove a secret value from the secret service. - * - * The @attributes should be a set of key and value string pairs. - * - * If multiple items match the attributes, then only one will be deleted. - * - * This method will return immediately and complete asynchronously. - */ -void -secret_service_removev (SecretService *self, - const SecretSchema *schema, - GHashTable *attributes, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) + gpointer user_data) { const gchar *schema_name = NULL; GSimpleAsyncResult *res; @@ -2738,7 +2481,7 @@ secret_service_removev (SecretService *self, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* Warnings raised already */ - if (schema != NULL && !_secret_util_attributes_validate (schema, attributes)) + if (schema != NULL && !_secret_attributes_validate (schema, attributes)) return; res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, @@ -2749,7 +2492,7 @@ secret_service_removev (SecretService *self, if (schema != NULL && !(schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME)) schema_name = schema->name; - variant = _secret_util_variant_for_attributes (attributes, schema_name); + variant = _secret_attributes_to_variant (attributes, schema_name); _secret_service_search_for_paths_variant (self, variant, cancellable, on_search_delete_password, g_object_ref (res)); @@ -2792,55 +2535,6 @@ secret_service_remove_finish (SecretService *self, /** * secret_service_remove_sync: * @self: the secret service - * @schema: the schema for the attributes - * @cancellable: optional cancellation object - * @error: location to place an error on failure - * @...: the attribute keys and values, terminated with %NULL - * - * Remove a secret value from the secret service. - * - * The variable argument list should contain pairs of a) The attribute name as - * a null-terminated string, followed by b) attribute value, either a character - * string, an int number, or a gboolean value, as defined in the password - * @schema. The list of attribtues should be terminated with a %NULL. - * - * If multiple items match the attributes, then only one will be deleted. - * - * This method may block indefinitely and should not be used in user interface - * threads. - * - * Returns: whether the removal was successful or not - */ -gboolean -secret_service_remove_sync (SecretService *self, - const SecretSchema* schema, - GCancellable *cancellable, - GError **error, - ...) -{ - GHashTable *attributes; - gboolean result; - va_list va; - - g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE); - g_return_val_if_fail (schema != NULL, FALSE); - g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - va_start (va, error); - attributes = _secret_util_attributes_for_varargs (schema, va); - va_end (va); - - result = secret_service_removev_sync (self, schema, attributes, cancellable, error); - - g_hash_table_unref (attributes); - - return result; -} - -/** - * secret_service_removev_sync: - * @self: the secret service * @schema: (allow-none): the schema for the attributes * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object @@ -2858,11 +2552,11 @@ secret_service_remove_sync (SecretService *self, * Returns: whether the removal was successful or not */ gboolean -secret_service_removev_sync (SecretService *self, - const SecretSchema *schema, - GHashTable *attributes, - GCancellable *cancellable, - GError **error) +secret_service_remove_sync (SecretService *self, + const SecretSchema *schema, + GHashTable *attributes, + GCancellable *cancellable, + GError **error) { SecretSync *sync; gboolean result; @@ -2872,14 +2566,14 @@ secret_service_removev_sync (SecretService *self, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* Warnings raised already */ - if (schema != NULL && !_secret_util_attributes_validate (schema, attributes)) + if (schema != NULL && !_secret_attributes_validate (schema, attributes)) return FALSE; sync = _secret_sync_new (); g_main_context_push_thread_default (sync->context); - secret_service_removev (self, schema, attributes, cancellable, - _secret_sync_on_result, sync); + secret_service_remove (self, schema, attributes, cancellable, + _secret_sync_on_result, sync); g_main_loop_run (sync->loop); diff --git a/library/secret-password.c b/library/secret-password.c index 1ca6044..0f34010 100644 --- a/library/secret-password.c +++ b/library/secret-password.c @@ -14,6 +14,7 @@ #include "config.h" +#include "secret-attributes.h" #include "secret-password.h" #include "secret-private.h" #include "secret-value.h" @@ -94,13 +95,13 @@ on_store_connected (GObject *source, service = secret_service_get_finish (result, &error); if (error == NULL) { - secret_service_storev (service, closure->schema, - closure->attributes, - closure->collection_path, - closure->label, closure->value, - closure->cancellable, - on_store_complete, - g_object_ref (res)); + secret_service_store (service, closure->schema, + closure->attributes, + closure->collection_path, + closure->label, closure->value, + closure->cancellable, + on_store_complete, + g_object_ref (res)); g_object_unref (service); } else { @@ -157,7 +158,7 @@ secret_password_store (const SecretSchema *schema, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); va_start (va, user_data); - attributes = _secret_util_attributes_for_varargs (schema, va); + attributes = secret_attributes_buildv (schema, va); va_end (va); secret_password_storev (schema, attributes, collection_path, label, password, @@ -212,7 +213,7 @@ secret_password_storev (const SecretSchema *schema, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* Warnings raised already */ - if (!_secret_util_attributes_validate (schema, attributes)) + if (!_secret_attributes_validate (schema, attributes)) return; res = g_simple_async_result_new (NULL, callback, user_data, @@ -222,7 +223,7 @@ secret_password_storev (const SecretSchema *schema, closure->collection_path = g_strdup (collection_path); closure->label = g_strdup (label); closure->value = secret_value_new (password, -1, "text/plain"); - closure->attributes = _secret_util_attributes_copy (attributes); + closure->attributes = _secret_attributes_copy (attributes); closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; g_simple_async_result_set_op_res_gpointer (res, closure, store_closure_free); @@ -309,7 +310,7 @@ secret_password_store_sync (const SecretSchema *schema, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); va_start (va, error); - attributes = _secret_util_attributes_for_varargs (schema, va); + attributes = secret_attributes_buildv (schema, va); va_end (va); ret = secret_password_storev_sync (schema, attributes, collection_path, @@ -367,7 +368,7 @@ secret_password_storev_sync (const SecretSchema *schema, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* Warnings raised already */ - if (!_secret_util_attributes_validate (schema, attributes)) + if (!_secret_attributes_validate (schema, attributes)) return FALSE; sync = _secret_sync_new (); @@ -438,7 +439,7 @@ secret_password_lookup (const SecretSchema *schema, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); va_start (va, user_data); - attributes = _secret_util_attributes_for_varargs (schema, va); + attributes = secret_attributes_buildv (schema, va); va_end (va); secret_password_lookupv (schema, attributes, cancellable, @@ -482,9 +483,9 @@ on_lookup_connected (GObject *source, g_simple_async_result_complete (res); } else { - secret_service_lookupv (service, closure->schema, closure->attributes, - closure->cancellable, on_lookup_complete, - g_object_ref (res)); + secret_service_lookup (service, closure->schema, closure->attributes, + closure->cancellable, on_lookup_complete, + g_object_ref (res)); g_object_unref (service); } @@ -524,7 +525,7 @@ secret_password_lookupv (const SecretSchema *schema, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* Warnings raised already */ - if (!_secret_util_attributes_validate (schema, attributes)) + if (!_secret_attributes_validate (schema, attributes)) return; res = g_simple_async_result_new (NULL, callback, user_data, @@ -532,7 +533,7 @@ secret_password_lookupv (const SecretSchema *schema, closure = g_slice_new0 (LookupClosure); closure->schema = _secret_schema_ref_if_nonstatic (schema); closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - closure->attributes = _secret_util_attributes_copy (attributes); + closure->attributes = _secret_attributes_copy (attributes); g_simple_async_result_set_op_res_gpointer (res, closure, lookup_closure_free); secret_service_get (SECRET_SERVICE_OPEN_SESSION, cancellable, @@ -648,7 +649,7 @@ secret_password_lookup_sync (const SecretSchema *schema, g_return_val_if_fail (error == NULL || *error == NULL, NULL); va_start (va, error); - attributes = _secret_util_attributes_for_varargs (schema, va); + attributes = secret_attributes_buildv (schema, va); va_end (va); password = secret_password_lookupv_sync (schema, attributes, @@ -696,7 +697,7 @@ secret_password_lookup_nonpageable_sync (const SecretSchema *schema, g_return_val_if_fail (error == NULL || *error == NULL, NULL); va_start (va, error); - attributes = _secret_util_attributes_for_varargs (schema, va); + attributes = secret_attributes_buildv (schema, va); va_end (va); password = secret_password_lookupv_nonpageable_sync (schema, attributes, @@ -741,7 +742,7 @@ secret_password_lookupv_nonpageable_sync (const SecretSchema *schema, g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* Warnings raised already */ - if (!_secret_util_attributes_validate (schema, attributes)) + if (!_secret_attributes_validate (schema, attributes)) return FALSE; sync = _secret_sync_new (); @@ -796,7 +797,7 @@ secret_password_lookupv_sync (const SecretSchema *schema, g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* Warnings raised already */ - if (!_secret_util_attributes_validate (schema, attributes)) + if (!_secret_attributes_validate (schema, attributes)) return FALSE; sync = _secret_sync_new (); @@ -865,7 +866,7 @@ secret_password_remove (const SecretSchema *schema, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); va_start (va, user_data); - attributes = _secret_util_attributes_for_varargs (schema, va); + attributes = secret_attributes_buildv (schema, va); va_end (va); secret_password_removev (schema, attributes, cancellable, @@ -904,9 +905,9 @@ on_delete_connect (GObject *source, service = secret_service_get_finish (result, &error); if (error == NULL) { - secret_service_removev (service, closure->schema, closure->attributes, - closure->cancellable, on_delete_complete, - g_object_ref (res)); + secret_service_remove (service, closure->schema, closure->attributes, + closure->cancellable, on_delete_complete, + g_object_ref (res)); g_object_unref (service); } else { @@ -950,14 +951,14 @@ secret_password_removev (const SecretSchema *schema, g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); /* Warnings raised already */ - if (!_secret_util_attributes_validate (schema, attributes)) + if (!_secret_attributes_validate (schema, attributes)) return; res = g_simple_async_result_new (NULL, callback, user_data, secret_password_removev); closure = g_slice_new0 (DeleteClosure); closure->schema = _secret_schema_ref_if_nonstatic (schema); - closure->attributes = _secret_util_attributes_copy (attributes); + closure->attributes = _secret_attributes_copy (attributes); closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free); @@ -1032,7 +1033,7 @@ secret_password_remove_sync (const SecretSchema* schema, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); va_start (va, error); - attributes = _secret_util_attributes_for_varargs (schema, va); + attributes = secret_attributes_buildv (schema, va); va_end (va); result = secret_password_removev_sync (schema, attributes, @@ -1078,7 +1079,7 @@ secret_password_removev_sync (const SecretSchema *schema, g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* Warnings raised already */ - if (!_secret_util_attributes_validate (schema, attributes)) + if (!_secret_attributes_validate (schema, attributes)) return FALSE; sync = _secret_sync_new (); diff --git a/library/secret-private.h b/library/secret-private.h index c079758..6afb92e 100644 --- a/library/secret-private.h +++ b/library/secret-private.h @@ -69,17 +69,14 @@ gint _secret_util_array_index_of (GVariant *array, GType _secret_list_get_type (void) G_GNUC_CONST; -GVariant * _secret_util_variant_for_attributes (GHashTable *attributes, +GVariant * _secret_attributes_to_variant (GHashTable *attributes, const gchar *schema_name); -GHashTable * _secret_util_attributes_for_variant (GVariant *variant); +GHashTable * _secret_attributes_for_variant (GVariant *variant); -GHashTable * _secret_util_attributes_for_varargs (const SecretSchema *schema, - va_list va); +GHashTable * _secret_attributes_copy (GHashTable *attributes); -GHashTable * _secret_util_attributes_copy (GHashTable *attributes); - -gboolean _secret_util_attributes_validate (const SecretSchema *schema, +gboolean _secret_attributes_validate (const SecretSchema *schema, GHashTable *attributes); GVariant * _secret_util_variant_for_properties (GHashTable *properties); diff --git a/library/secret-service.h b/library/secret-service.h index 751a5d3..8bb4e7a 100644 --- a/library/secret-service.h +++ b/library/secret-service.h @@ -330,16 +330,6 @@ GVariant * secret_service_prompt_path_finish (SecretService void secret_service_store (SecretService *self, const SecretSchema *schema, - const gchar *collection_path, - const gchar *label, - SecretValue *value, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data, - ...) G_GNUC_NULL_TERMINATED; - -void secret_service_storev (SecretService *self, - const SecretSchema *schema, GHashTable *attributes, const gchar *collection_path, const gchar *label, @@ -354,15 +344,6 @@ gboolean secret_service_store_finish (SecretService gboolean secret_service_store_sync (SecretService *self, const SecretSchema *schema, - const gchar *collection_path, - const gchar *label, - SecretValue *value, - GCancellable *cancellable, - GError **error, - ...) G_GNUC_NULL_TERMINATED; - -gboolean secret_service_storev_sync (SecretService *self, - const SecretSchema *schema, GHashTable *attributes, const gchar *collection_path, const gchar *label, @@ -372,13 +353,6 @@ gboolean secret_service_storev_sync (SecretService void secret_service_lookup (SecretService *self, const SecretSchema *schema, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data, - ...) G_GNUC_NULL_TERMINATED; - -void secret_service_lookupv (SecretService *self, - const SecretSchema *schema, GHashTable *attributes, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -390,12 +364,6 @@ SecretValue * secret_service_lookup_finish (SecretService SecretValue * secret_service_lookup_sync (SecretService *self, const SecretSchema *schema, - GCancellable *cancellable, - GError **error, - ...) G_GNUC_NULL_TERMINATED; - -SecretValue * secret_service_lookupv_sync (SecretService *self, - const SecretSchema *schema, GHashTable *attributes, GCancellable *cancellable, GError **error); @@ -417,13 +385,6 @@ gboolean secret_service_delete_path_sync (SecretService void secret_service_remove (SecretService *self, const SecretSchema *schema, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data, - ...) G_GNUC_NULL_TERMINATED; - -void secret_service_removev (SecretService *self, - const SecretSchema *schema, GHashTable *attributes, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -434,12 +395,6 @@ gboolean secret_service_remove_finish (SecretService GError **error); gboolean secret_service_remove_sync (SecretService *self, - const SecretSchema* schema, - GCancellable *cancellable, - GError **error, - ...) G_GNUC_NULL_TERMINATED; - -gboolean secret_service_removev_sync (SecretService *self, const SecretSchema *schema, GHashTable *attributes, GCancellable *cancellable, diff --git a/library/secret-unstable.h b/library/secret-unstable.h index 34395e0..2d1a629 100644 --- a/library/secret-unstable.h +++ b/library/secret-unstable.h @@ -25,6 +25,7 @@ #define __SECRET_INSIDE_HEADER__ +#include #include #include #include diff --git a/library/secret-util.c b/library/secret-util.c index 8a22014..bbb27c4 100644 --- a/library/secret-util.c +++ b/library/secret-util.c @@ -128,205 +128,6 @@ _secret_util_variant_for_properties (GHashTable *properties) return g_variant_builder_end (&builder); } -GVariant * -_secret_util_variant_for_attributes (GHashTable *attributes, - const gchar *schema_name) -{ - GHashTableIter iter; - GVariantBuilder builder; - const gchar *name; - const gchar *value; - - g_return_val_if_fail (attributes != NULL, NULL); - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); - - g_hash_table_iter_init (&iter, attributes); - while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&value)) { - if (!schema_name || !g_str_equal (name, "xdg:schema")) - g_variant_builder_add (&builder, "{ss}", name, value); - } - - if (schema_name) - g_variant_builder_add (&builder, "{ss}", "xdg:schema", schema_name); - - return g_variant_builder_end (&builder); -} - -GHashTable * -_secret_util_attributes_for_variant (GVariant *variant) -{ - GVariantIter iter; - GHashTable *attributes; - gchar *value; - gchar *key; - - attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - g_variant_iter_init (&iter, variant); - while (g_variant_iter_next (&iter, "{ss}", &key, &value)) - g_hash_table_insert (attributes, key, value); - - return attributes; -} - -GHashTable * -_secret_util_attributes_for_varargs (const SecretSchema *schema, - va_list args) -{ - const gchar *attribute_name; - SecretSchemaAttributeType type; - GHashTable *attributes; - const gchar *string; - gboolean type_found; - gchar *value = NULL; - gboolean boolean; - gint integer; - gint i; - - g_return_val_if_fail (schema != NULL, NULL); - - attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - for (;;) { - attribute_name = va_arg (args, const gchar *); - if (attribute_name == NULL) - break; - - type_found = FALSE; - for (i = 0; i < G_N_ELEMENTS (schema->attributes); ++i) { - if (!schema->attributes[i].name) - break; - if (g_str_equal (schema->attributes[i].name, attribute_name)) { - type_found = TRUE; - type = schema->attributes[i].type; - break; - } - } - - if (!type_found) { - g_warning ("The attribute '%s' was not found in the password schema.", attribute_name); - g_hash_table_unref (attributes); - return NULL; - } - - switch (type) { - case SECRET_SCHEMA_ATTRIBUTE_BOOLEAN: - boolean = va_arg (args, gboolean); - value = g_strdup (boolean ? "true" : "false"); - break; - case SECRET_SCHEMA_ATTRIBUTE_STRING: - string = va_arg (args, gchar *); - if (!g_utf8_validate (string, -1, NULL)) { - g_warning ("The value for attribute '%s' was not a valid utf-8 string.", attribute_name); - g_hash_table_unref (attributes); - return NULL; - } - value = g_strdup (string); - break; - case SECRET_SCHEMA_ATTRIBUTE_INTEGER: - integer = va_arg (args, gint); - value = g_strdup_printf ("%d", integer); - break; - default: - g_warning ("The password attribute '%s' has an invalid type in the password schema.", attribute_name); - g_hash_table_unref (attributes); - return NULL; - } - - g_hash_table_insert (attributes, g_strdup (attribute_name), value); - } - - return attributes; -} - -gboolean -_secret_util_attributes_validate (const SecretSchema *schema, - GHashTable *attributes) -{ - const SecretSchemaAttribute *attribute; - GHashTableIter iter; - gchar *key; - gchar *value; - gchar *end; - gint i; - - g_return_val_if_fail (schema != NULL, FALSE); - - g_hash_table_iter_init (&iter, attributes); - while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value)) { - - /* Find the attribute */ - attribute = NULL; - for (i = 0; i < G_N_ELEMENTS (schema->attributes); i++) { - if (schema->attributes[i].name == NULL) - break; - if (g_str_equal (schema->attributes[i].name, key)) { - attribute = &schema->attributes[i]; - break; - } - } - - if (attribute == NULL) { - g_warning ("invalid %s attribute in for %s schema", - key, schema->name); - return FALSE; - } - - switch (attribute->type) { - case SECRET_SCHEMA_ATTRIBUTE_BOOLEAN: - if (!g_str_equal (value, "true") && !g_str_equal (value, "false")) { - g_warning ("invalid %s boolean value for %s schema: %s", - key, schema->name, value); - return FALSE; - } - break; - case SECRET_SCHEMA_ATTRIBUTE_INTEGER: - end = NULL; - g_ascii_strtoll (value, &end, 10); - if (!end || end[0] != '\0') { - g_warning ("invalid %s integer value for %s schema: %s", - key, schema->name, value); - return FALSE; - } - break; - case SECRET_SCHEMA_ATTRIBUTE_STRING: - if (!g_utf8_validate (value, -1, NULL)) { - g_warning ("invalid %s string value for %s schema: %s", - key, schema->name, value); - return FALSE; - } - break; - default: - g_warning ("invalid %s value type in %s schema", - key, schema->name); - return FALSE; - } - } - - return TRUE; -} - -GHashTable * -_secret_util_attributes_copy (GHashTable *attributes) -{ - GHashTableIter iter; - GHashTable *copy; - gchar *key; - gchar *value; - - if (attributes == NULL) - return NULL; - - copy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - g_hash_table_iter_init (&iter, attributes); - while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value)) - g_hash_table_insert (copy, g_strdup (key), g_strdup (value)); - - return copy; -} - static void process_get_all_reply (GDBusProxy *proxy, GVariant *retval) diff --git a/library/tests/test-methods.c b/library/tests/test-methods.c index c699d4f..c0d049c 100644 --- a/library/tests/test-methods.c +++ b/library/tests/test-methods.c @@ -13,6 +13,7 @@ #include "config.h" +#include "secret-attributes.h" #include "secret-collection.h" #include "secret-item.h" #include "secret-service.h" @@ -914,7 +915,7 @@ test_item_sync (Test *test, g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label", g_variant_ref_sink (g_variant_new_string ("Wheeee"))); g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Attributes", - g_variant_ref_sink (_secret_util_variant_for_attributes (attributes, "org.gnome.Test"))); + g_variant_ref_sink (_secret_attributes_to_variant (attributes, "org.gnome.Test"))); g_hash_table_unref (attributes); @@ -956,7 +957,7 @@ test_item_async (Test *test, g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Label", g_variant_ref_sink (g_variant_new_string ("Wheeee"))); g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Attributes", - g_variant_ref_sink (_secret_util_variant_for_attributes (attributes, NULL))); + g_variant_ref_sink (_secret_attributes_to_variant (attributes, NULL))); g_hash_table_unref (attributes); @@ -987,16 +988,21 @@ test_remove_sync (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; gboolean ret; - ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "even", FALSE, - "string", "one", - "number", 1, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "one", + "number", 1, + NULL); + + ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); g_assert (ret == TRUE); + + g_hash_table_unref (attributes); } static void @@ -1005,15 +1011,19 @@ test_remove_async (Test *test, { GError *error = NULL; GAsyncResult *result = NULL; + GHashTable *attributes; gboolean ret; - secret_service_remove (test->service, &MOCK_SCHEMA, NULL, - on_complete_get_result, &result, - "even", FALSE, - "string", "one", - "number", 1, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "one", + "number", 1, + NULL); + secret_service_remove (test->service, &MOCK_SCHEMA, attributes, NULL, + on_complete_get_result, &result); + + g_hash_table_unref (attributes); g_assert (result == NULL); egg_test_wait (); @@ -1030,14 +1040,18 @@ test_remove_locked (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; gboolean ret; - ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "even", FALSE, - "string", "tres", - "number", 3, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "tres", + "number", 3, + NULL); + ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); + + g_hash_table_unref (attributes); g_assert_no_error (error); g_assert (ret == TRUE); } @@ -1047,14 +1061,18 @@ test_remove_no_match (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; gboolean ret; + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", TRUE, + "string", "one", + NULL); + /* Won't match anything */ - ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "even", TRUE, - "string", "one", - NULL); + ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); + g_hash_table_unref (attributes); g_assert_no_error (error); g_assert (ret == FALSE); } @@ -1064,22 +1082,24 @@ test_remove_no_name (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; gboolean ret; + attributes = secret_attributes_build (&MOCK_SCHEMA, + "number", 5, + NULL); + /* Shouldn't match anything, because no item with 5 in mock schema */ - ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "number", 5, - NULL); + ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); g_assert (ret == FALSE); /* We have an item with 5 in prime schema, but should match anyway becase of flags */ - ret = secret_service_remove_sync (test->service, &NO_NAME_SCHEMA, NULL, &error, - "number", 5, - NULL); - + ret = secret_service_remove_sync (test->service, &NO_NAME_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); g_assert (ret == TRUE); + + g_hash_table_unref (attributes); } static void @@ -1087,16 +1107,20 @@ test_lookup_sync (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; SecretValue *value; gsize length; - value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "even", FALSE, - "string", "one", - "number", 1, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "one", + "number", 1, + NULL); + + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); + g_hash_table_unref (attributes); g_assert (value != NULL); g_assert_cmpstr (secret_value_get (value, &length), ==, "111"); @@ -1110,18 +1134,22 @@ test_lookup_async (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; GAsyncResult *result = NULL; SecretValue *value; gsize length; - secret_service_lookup (test->service, &MOCK_SCHEMA, NULL, - on_complete_get_result, &result, - "even", FALSE, - "string", "one", - "number", 1, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "one", + "number", 1, + NULL); + + secret_service_lookup (test->service, &MOCK_SCHEMA, attributes, NULL, + on_complete_get_result, &result); g_assert (result == NULL); + g_hash_table_unref (attributes); egg_test_wait (); @@ -1141,16 +1169,20 @@ test_lookup_locked (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; SecretValue *value; gsize length; - value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "even", FALSE, - "string", "tres", - "number", 3, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "tres", + "number", 3, + NULL); + + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); + g_hash_table_unref (attributes); g_assert (value != NULL); g_assert_cmpstr (secret_value_get (value, &length), ==, "3333"); @@ -1164,16 +1196,20 @@ test_lookup_no_match (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; SecretValue *value; + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", TRUE, + "string", "one", + NULL); + /* Won't match anything */ - value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "even", TRUE, - "string", "one", - NULL); + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); g_assert (value == NULL); + g_hash_table_unref (attributes); } static void @@ -1181,20 +1217,21 @@ test_lookup_no_name (Test *test, gconstpointer used) { GError *error = NULL; + GHashTable *attributes; SecretValue *value; gsize length; + attributes = secret_attributes_build (&MOCK_SCHEMA, + "number", 5, + NULL); + /* should return null, because nothing with mock schema and 5 */ - value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, - "number", 5, - NULL); + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); g_assert (value == NULL); /* should return an item, because we have a prime schema with 5, and flags not to match name */ - value = secret_service_lookup_sync (test->service, &NO_NAME_SCHEMA, NULL, &error, - "number", 5, - NULL); + value = secret_service_lookup_sync (test->service, &NO_NAME_SCHEMA, attributes, NULL, &error); g_assert_no_error (error); @@ -1203,6 +1240,7 @@ test_lookup_no_name (Test *test, g_assert_cmpuint (length, ==, 3); secret_value_unref (value); + g_hash_table_unref (attributes); } static void @@ -1217,14 +1255,17 @@ test_store_sync (Test *test, gboolean ret; gsize length; - ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, collection_path, - "New Item Label", value, NULL, &error, - "even", FALSE, - "string", "seventeen", - "number", 17, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "seventeen", + "number", 17, + NULL); + + ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, attributes, collection_path, + "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"); @@ -1263,22 +1304,21 @@ test_store_replace (Test *test, gchar **paths; gboolean ret; - ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, collection_path, - "New Item Label", value, NULL, &error, - "even", FALSE, - "string", "seventeen", - "number", 17, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "seventeen", + "number", 17, + NULL); + + ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, attributes, collection_path, + "New Item Label", value, NULL, &error); g_assert_no_error (error); - ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, collection_path, - "Another Label", value, NULL, &error, - "even", FALSE, - "string", "seventeen", - "number", 17, - NULL); + ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, attributes, collection_path, + "Another 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"); @@ -1310,14 +1350,17 @@ test_store_async (Test *test, gboolean ret; gsize length; - secret_service_store (test->service, &MOCK_SCHEMA, collection_path, - "New Item Label", value, NULL, on_complete_get_result, &result, - "even", FALSE, - "string", "seventeen", - "number", 17, - NULL); + attributes = secret_attributes_build (&MOCK_SCHEMA, + "even", FALSE, + "string", "seventeen", + "number", 17, + NULL); + + secret_service_store (test->service, &MOCK_SCHEMA, attributes, collection_path, + "New Item Label", value, NULL, on_complete_get_result, &result); g_assert (result == NULL); secret_value_unref (value); + g_hash_table_unref (attributes); egg_test_wait (); diff --git a/tool/secret-tool.c b/tool/secret-tool.c index 80226ce..c393112 100644 --- a/tool/secret-tool.c +++ b/tool/secret-tool.c @@ -135,7 +135,7 @@ secret_tool_action_remove (int argc, service = secret_service_get_sync (SECRET_SERVICE_NONE, NULL, &error); if (error == NULL) - secret_service_removev_sync (service, NULL, attributes, NULL, &error); + secret_service_remove_sync (service, NULL, attributes, NULL, &error); g_object_unref (service); g_hash_table_unref (attributes); @@ -205,7 +205,7 @@ secret_tool_action_lookup (int argc, service = secret_service_get_sync (SECRET_SERVICE_NONE, NULL, &error); if (error == NULL) - value = secret_service_lookupv_sync (service, NULL, attributes, NULL, &error); + value = secret_service_lookup_sync (service, NULL, attributes, NULL, &error); g_object_unref (service); g_hash_table_unref (attributes); @@ -312,7 +312,7 @@ secret_tool_action_store (int argc, else value = read_password_stdin (); - secret_service_storev_sync (service, NULL, attributes, collection, store_label, value, NULL, &error); + secret_service_store_sync (service, NULL, attributes, collection, store_label, value, NULL, &error); secret_value_unref (value); } -- 2.7.4