Commit 89550876 authored by Stef Walter's avatar Stef Walter
Browse files

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
parent d0df587f
......@@ -27,6 +27,7 @@
<xi:include href="xml/secret-collection.xml"/>
<xi:include href="xml/secret-item.xml"/>
<xi:include href="xml/secret-value.xml"/>
<xi:include href="xml/secret-attributes.xml"/>
<xi:include href="xml/secret-prompt.xml"/>
<xi:include href="xml/secret-error.xml"/>
</part>
......
......@@ -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
......@@ -275,6 +269,13 @@ SECRET_TYPE_VALUE
secret_value_get_type
</SECTION>
<SECTION>
<FILE>secret-attributes</FILE>
<INCLUDE>secret/secret-unstable.h</INCLUDE>
secret_attributes_build
secret_attributes_buildv
</SECTION>
<SECTION>
<FILE>SecretGenService</FILE>
</SECTION>
......
......@@ -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 \
......
/* 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 <stefw@gnome.org>
*/
#include "config.h"
#include "secret-attributes.h"
#include "secret-private.h"
#include <string.h>
/**
* 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;
}
/* 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 <stefw@gnome.org>
*/
#if !defined (__SECRET_INSIDE_HEADER__) && !defined (SECRET_COMPILATION)
#error "Only <secret/secret.h> or <secret/secret-unstable.h> can be included directly."
#endif
#ifndef __SECRET_ATTRIBUTES_H__
#define __SECRET_ATTRIBUTES_H__
#include <glib.h>
#include <stdarg.h>
#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___ */
......@@ -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);
}
......
This diff is collapsed.
......@@ -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 ();
......
......@@ -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);