diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt index c68850c..15cb5f7 100644 --- a/docs/reference/libsecret/libsecret-sections.txt +++ b/docs/reference/libsecret/libsecret-sections.txt @@ -55,7 +55,6 @@ secret_item_set_label_finish secret_item_set_label_sync secret_item_get_locked secret_item_get_modified -secret_item_get_schema secret_item_get_secret secret_item_get_secret_finish secret_item_get_secret_sync @@ -113,12 +112,6 @@ secret_password_free
secret-schema SecretSchema -SECRET_SCHEMA_IDENTIFIER_GENERIC -SECRET_SCHEMA_IDENTIFIER_NETWORK -SECRET_SCHEMA_IDENTIFIER_NOTE -SECRET_SCHEMA_GENERIC -SECRET_SCHEMA_NETWORK -SECRET_SCHEMA_NOTE SecretSchemaFlags SecretSchemaAttribute SecretSchemaAttributeType @@ -132,6 +125,7 @@ secret_schema_attribute_type_get_type secret_schema_flags_get_type SECRET_TYPE_SCHEMA_FLAGS SECRET_TYPE_SCHEMA_ATTRIBUTE_TYPE +SECRET_SCHEMA_COMPAT_NETWORK
diff --git a/library/Makefile.am b/library/Makefile.am index 0c8b8bc..fcddb01 100644 --- a/library/Makefile.am +++ b/library/Makefile.am @@ -27,6 +27,7 @@ HEADER_FILES = \ secret-password.h \ secret-prompt.h \ secret-schema.h \ + secret-schemas.h \ secret-service.h \ secret-types.h \ secret-value.h \ @@ -49,6 +50,7 @@ PUBLIC_FILES = \ secret-password.h secret-password.c \ secret-prompt.h secret-prompt.c \ secret-schema.h secret-schema.c \ + secret-schemas.h secret-schemas.c \ secret-service.h secret-service.c \ secret-types.h \ secret-value.h secret-value.c \ diff --git a/library/org.freedesktop.Secrets.xml b/library/org.freedesktop.Secrets.xml index bbcffdc..8182df4 100644 --- a/library/org.freedesktop.Secrets.xml +++ b/library/org.freedesktop.Secrets.xml @@ -119,8 +119,6 @@ - - diff --git a/library/secret-item.c b/library/secret-item.c index 5099678..b1e297f 100644 --- a/library/secret-item.c +++ b/library/secret-item.c @@ -65,7 +65,6 @@ enum { PROP_SERVICE, PROP_ATTRIBUTES, PROP_LABEL, - PROP_SCHEMA, PROP_LOCKED, PROP_CREATED, PROP_MODIFIED @@ -181,9 +180,6 @@ secret_item_get_property (GObject *obj, case PROP_LABEL: g_value_take_string (value, secret_item_get_label (self)); break; - case PROP_SCHEMA: - g_value_take_string (value, secret_item_get_schema (self)); - break; case PROP_LOCKED: g_value_set_boolean (value, secret_item_get_locked (self)); break; @@ -233,9 +229,6 @@ handle_property_changed (GObject *object, else if (g_str_equal (property_name, "Label")) g_object_notify (object, "label"); - else if (g_str_equal (property_name, "Type")) - g_object_notify (object, "schema"); - else if (g_str_equal (property_name, "Locked")) g_object_notify (object, "locked"); @@ -293,8 +286,6 @@ secret_item_class_init (SecretItemClass *klass) * * The attributes set on this item. Attributes are used to locate an * item. They are not guaranteed to be stored or transferred securely. - * - * The schema describes which attributes should be present and their types. */ g_object_class_install_property (gobject_class, PROP_ATTRIBUTES, g_param_spec_boxed ("attributes", "Attributes", "Item attributes", @@ -313,17 +304,6 @@ secret_item_class_init (SecretItemClass *klass) g_param_spec_string ("label", "Label", "Item label", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - /** - * SecretItem:schema: - * - * The schema for this item. This is a dotted string that describes - * which attributes should be present and the types of values on - * those attributes. - */ - g_object_class_install_property (gobject_class, PROP_SCHEMA, - g_param_spec_string ("schema", "Schema", "Item schema", - NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - /** * SecretItem:locked: * @@ -643,8 +623,7 @@ on_create_path (GObject *source, } static GHashTable * -item_properties_new (const gchar *schema_name, - const gchar *label, +item_properties_new (const gchar *label, GHashTable *attributes) { GHashTable *properties; @@ -658,12 +637,7 @@ item_properties_new (const gchar *schema_name, SECRET_ITEM_INTERFACE ".Label", g_variant_ref_sink (value)); - value = g_variant_new_string (schema_name); - g_hash_table_insert (properties, - SECRET_ITEM_INTERFACE ".Schema", - g_variant_ref_sink (value)); - - value = _secret_util_variant_for_attributes (attributes); + value = _secret_util_variant_for_attributes (attributes, NULL); g_hash_table_insert (properties, SECRET_ITEM_INTERFACE ".Attributes", g_variant_ref_sink (value)); @@ -674,7 +648,6 @@ item_properties_new (const gchar *schema_name, /** * secret_item_create: * @collection: a secret collection to create this item in - * @schema_name: schema name for the new item * @label: label for the new item * @attributes: (element-type utf8 utf8): attributes for the new item * @value: secret value for the new item @@ -695,7 +668,6 @@ item_properties_new (const gchar *schema_name, */ void secret_item_create (SecretCollection *collection, - const gchar *schema_name, const gchar *label, GHashTable *attributes, SecretValue *value, @@ -722,7 +694,7 @@ secret_item_create (SecretCollection *collection, closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; g_simple_async_result_set_op_res_gpointer (res, closure, create_closure_free); - properties = item_properties_new (schema_name, label, attributes); + properties = item_properties_new (label, attributes); g_object_get (collection, "service", &service, NULL); collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); @@ -772,7 +744,6 @@ secret_item_create_finish (GAsyncResult *result, /** * secret_item_create_sync: * @collection: a secret collection to create this item in - * @schema_name: schema name for the new item * @label: label for the new item * @attributes: (element-type utf8 utf8): attributes for the new item * @value: secret value for the new item @@ -795,7 +766,6 @@ secret_item_create_finish (GAsyncResult *result, */ SecretItem * secret_item_create_sync (SecretCollection *collection, - const gchar *schema_name, const gchar *label, GHashTable *attributes, SecretValue *value, @@ -816,7 +786,7 @@ secret_item_create_sync (SecretCollection *collection, g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - properties = item_properties_new (schema_name, label, attributes); + properties = item_properties_new (label, attributes); g_object_get (collection, "service", &service, NULL); collection_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (collection)); @@ -1393,7 +1363,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), + _secret_util_variant_for_attributes (attributes, NULL), secret_item_set_attributes, cancellable, callback, user_data); } @@ -1448,39 +1418,10 @@ 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), + _secret_util_variant_for_attributes (attributes, NULL), cancellable, error); } -/** - * secret_item_get_schema: - * @self: an item - * - * Get the schema of this item. - * - * The schema is a dotted string like org.freedesktop.Secret.Generic. - * A schema describes the set of attributes that should be set on this item. - * - * Returns: (transfer full): the schema, which should be freed with g_free() - */ -gchar * -secret_item_get_schema (SecretItem *self) -{ - GVariant *variant; - gchar *label; - - g_return_val_if_fail (SECRET_IS_ITEM (self), NULL); - - variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Type"); - if (variant == NULL) - return NULL; - - label = g_variant_dup_string (variant, NULL); - g_variant_unref (variant); - - return label; -} - /** * secret_item_get_label: * @self: an item diff --git a/library/secret-item.h b/library/secret-item.h index 645ab5c..21b8e8a 100644 --- a/library/secret-item.h +++ b/library/secret-item.h @@ -68,7 +68,6 @@ SecretItem * secret_item_new_sync (SecretService *servi void secret_item_refresh (SecretItem *self); void secret_item_create (SecretCollection *collection, - const gchar *schema_name, const gchar *label, GHashTable *attributes, SecretValue *value, @@ -81,7 +80,6 @@ SecretItem * secret_item_create_finish (GAsyncResult *result GError **error); SecretItem * secret_item_create_sync (SecretCollection *collection, - const gchar *schema_name, const gchar *label, GHashTable *attributes, SecretValue *value, @@ -164,8 +162,6 @@ gboolean secret_item_set_label_sync (SecretItem *self, GCancellable *cancellable, GError **error); -gchar * secret_item_get_schema (SecretItem *self); - gboolean secret_item_get_locked (SecretItem *self); guint64 secret_item_get_created (SecretItem *self); diff --git a/library/secret-methods.c b/library/secret-methods.c index 86ff008..48f7e77 100644 --- a/library/secret-methods.c +++ b/library/secret-methods.c @@ -60,6 +60,21 @@ secret_service_search_for_paths (SecretService *self, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) +{ + g_return_if_fail (SECRET_IS_SERVICE (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), + cancellable, callback, user_data); +} + +void +_secret_service_search_for_paths_variant (SecretService *self, + GVariant *attributes, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { GSimpleAsyncResult *res; @@ -71,8 +86,7 @@ secret_service_search_for_paths (SecretService *self, secret_service_search_for_paths); g_dbus_proxy_call (G_DBUS_PROXY (self), "SearchItems", - g_variant_new ("(@a{ss})", - _secret_util_variant_for_attributes (attributes)), + g_variant_new ("(@a{ss})", attributes), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, on_search_items_complete, g_object_ref (res)); @@ -172,7 +186,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)), + _secret_util_variant_for_attributes (attributes, NULL)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (response != NULL) { @@ -1770,12 +1784,8 @@ secret_service_storev (SecretService *self, SECRET_ITEM_INTERFACE ".Label", g_variant_ref_sink (propval)); - propval = g_variant_new_string (schema->identifier); - g_hash_table_insert (properties, - SECRET_ITEM_INTERFACE ".Schema", - g_variant_ref_sink (propval)); - - propval = _secret_util_variant_for_attributes (attributes); + /* Always store the schema name in the attributes */ + propval = _secret_util_variant_for_attributes (attributes, schema->name); g_hash_table_insert (properties, SECRET_ITEM_INTERFACE ".Attributes", g_variant_ref_sink (propval)); @@ -2114,6 +2124,8 @@ secret_service_lookupv (SecretService *self, { GSimpleAsyncResult *res; LookupClosure *closure; + const gchar *schema_name; + GVariant *variant; g_return_if_fail (SECRET_IS_SERVICE (self)); g_return_if_fail (schema != NULL); @@ -2130,8 +2142,11 @@ secret_service_lookupv (SecretService *self, closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; g_simple_async_result_set_op_res_gpointer (res, closure, lookup_closure_free); - secret_service_search_for_paths (self, attributes, cancellable, - on_lookup_searched, g_object_ref (res)); + schema_name = (schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME) ? NULL : schema->name; + variant = _secret_util_variant_for_attributes (attributes, schema_name); + + _secret_service_search_for_paths_variant (self, variant, cancellable, + on_lookup_searched, g_object_ref (res)); g_object_unref (res); } @@ -2621,6 +2636,8 @@ secret_service_removev (SecretService *self, { GSimpleAsyncResult *res; DeleteClosure *closure; + const gchar *schema_name; + GVariant *variant; g_return_if_fail (SECRET_SERVICE (self)); g_return_if_fail (schema != NULL); @@ -2637,8 +2654,11 @@ secret_service_removev (SecretService *self, closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free); - secret_service_search_for_paths (self, attributes, cancellable, - on_search_delete_password, g_object_ref (res)); + schema_name = (schema->flags & SECRET_SCHEMA_DONT_MATCH_NAME) ? NULL : schema->name; + variant = _secret_util_variant_for_attributes (attributes, schema_name); + + _secret_service_search_for_paths_variant (self, variant, cancellable, + on_search_delete_password, g_object_ref (res)); g_object_unref (res); } diff --git a/library/secret-password.c b/library/secret-password.c index 2f5a4cd..d832fbb 100644 --- a/library/secret-password.c +++ b/library/secret-password.c @@ -490,7 +490,7 @@ on_lookup_connected (GObject *source, /** * secret_password_lookupv: - * @schema: (allow-none): the schema for attributes + * @schema: the schema for attributes * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object * @callback: called when the operation completes @@ -516,6 +516,7 @@ secret_password_lookupv (const SecretSchema *schema, GSimpleAsyncResult *res; LookupClosure *closure; + g_return_if_fail (schema != NULL); g_return_if_fail (attributes != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); @@ -715,7 +716,7 @@ secret_password_lookup_nonpageable_sync (const SecretSchema *schema, /** * secret_password_lookupv_nonpageable_sync: (skip) - * @schema: (allow-none): the schema for attributes + * @schema: the schema for attributes * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object * @error: location to place an error on failure @@ -741,6 +742,7 @@ secret_password_lookupv_nonpageable_sync (const SecretSchema *schema, SecretSync *sync; gchar *password; + g_return_val_if_fail (schema != NULL, NULL); g_return_val_if_fail (attributes != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); @@ -767,7 +769,7 @@ secret_password_lookupv_nonpageable_sync (const SecretSchema *schema, /** * secret_password_lookupv_sync: - * @schema: (allow-none): the schema for attributes + * @schema: the schema for attributes * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object * @error: location to place an error on failure @@ -795,6 +797,7 @@ secret_password_lookupv_sync (const SecretSchema *schema, SecretSync *sync; gchar *string; + g_return_val_if_fail (schema != NULL, NULL); g_return_val_if_fail (attributes != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); @@ -923,7 +926,7 @@ on_delete_connect (GObject *source, /** * secret_password_removev: - * @schema: (allow-none): the schema to for attributes + * @schema: the schema to for attributes * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object * @callback: called when the operation completes @@ -949,6 +952,7 @@ secret_password_removev (const SecretSchema *schema, GSimpleAsyncResult *res; DeleteClosure *closure; + g_return_if_fail (schema != NULL); g_return_if_fail (attributes != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); @@ -1048,7 +1052,7 @@ secret_password_remove_sync (const SecretSchema* schema, /** * secret_password_removev_sync: - * @schema: (allow-none): the schema to for attributes + * @schema: the schema to for attributes * @attributes: (element-type utf8 utf8): the attribute keys and values * @cancellable: optional cancellation object * @error: location to place an error on failure @@ -1075,6 +1079,7 @@ secret_password_removev_sync (const SecretSchema *schema, SecretSync *sync; gboolean result; + g_return_val_if_fail (schema != NULL, FALSE); g_return_val_if_fail (attributes != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); diff --git a/library/secret-private.h b/library/secret-private.h index 0aad92a..08e850b 100644 --- a/library/secret-private.h +++ b/library/secret-private.h @@ -67,7 +67,8 @@ 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_util_variant_for_attributes (GHashTable *attributes, + const gchar *schema_name); GHashTable * _secret_util_attributes_for_variant (GVariant *variant); @@ -127,6 +128,12 @@ void _secret_service_delete_path (SecretService *se GAsyncReadyCallback callback, gpointer user_data); +void _secret_service_search_for_paths_variant (SecretService *self, + GVariant *attributes, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + SecretItem * _secret_service_find_item_instance (SecretService *self, const gchar *item_path); diff --git a/library/secret-schema.c b/library/secret-schema.c index 68cc7a4..3c18716 100644 --- a/library/secret-schema.c +++ b/library/secret-schema.c @@ -28,17 +28,40 @@ * be either strings, integers or booleans. * * The names and types of allowed attributes for a given password are defined - * with a schema. Certain schemas are predefined like %SECRET_SCHEMA_NETWORK. + * with a schema. * * Additional schemas can be defined via the %SecretSchema structure like this: * - * If the schema flags contain the %SECRET_SCHEMA_ALLOW_UNDEFINED flag, then - * undefined attributes are permitted. + * + * /* in a header: */ + * + * const SecretSchema * example_get_schema (void) G_GNUC_CONST; + * + * #define EXAMPLE_SCHEMA example_get_schema () + * + * + * /* in a .c file: */ + * + * const SecretSchema * + * example_get_schema (void) + * { + * static const SecretSchema the_schema = { + * "org.example.Password", SECRET_SCHEMA_NONE, + * { + * { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, + * { "string", SECRET_SCHEMA_ATTRIBUTE_STRING }, + * { "even", SECRET_SCHEMA_ATTRIBUTE_BOOLEAN }, + * { "NULL", 0 }, + * } + * }; + * return &the_schema; + * } + * s */ /** * SecretSchema: - * @identifier: the dotted identifer of the schema + * @name: the dotted name of the schema * @flags: flags for the schema * @attributes: the attribute names and types of those attributes * @@ -46,20 +69,28 @@ * are used for interoperability between various services storing the same types * of items. * - * Each schema has a identifier like "org.gnome.keyring.NetworkPassword", and defines + * Each schema has a name like "org.gnome.keyring.NetworkPassword", and defines * a set of attributes, and types (string, integer, boolean) for those attributes. * * Attributes are stored as strings in the Secret Service, and the attribute * types simply define standard ways to store integer and boolean values as strings. * - * If @flags contains the %SECRET_SCHEMA_ALLOW_UNDEFINED flag, then attributes - * not listed in @attributes are permitted. + * Schemas are handled entirely on the client side by this library. The name of the + * schema is automatically stored as an attribute on the item. + * + * Normally when looking up passwords only those with matching schema names are + * returned. If the schema @flags contain the %SECRET_SCHEMA_DONT_MATCH_NAME flag, + * then lookups will not check that the schema name matches that on the item, only + * the schema's attributes are matched. This is useful when you are looking up items + * that are not stored by the libsecret library. Other libraries such as libgnome-keyring + * don't store the schema name. */ /** * SecretSchemaFlags: * @SECRET_SCHEMA_NONE: no flags for the schema - * @SECRET_SCHEMA_ALLOW_UNDEFINED: allow undefined attributes + * @SECRET_SCHEMA_DONT_MATCH_NAME: don't match the schema name when looking up or + * removing passwords * * Flags for a #SecretSchema definition. */ @@ -107,7 +138,7 @@ G_DEFINE_BOXED_TYPE (SecretSchemaAttribute, secret_schema_attribute, /** * secret_schema_new: - * @identifier: the dotted identifier of the schema + * @name: the dotted name of the schema * @flags: the flags for the schema * @attributes: (element-type utf8 Secret.SchemaAttributeType): the attribute names and types of those attributes * @@ -118,7 +149,7 @@ G_DEFINE_BOXED_TYPE (SecretSchemaAttribute, secret_schema_attribute, * schemas are used for interoperability between various services storing the * same types of items. * - * Each schema has an @identifier like "org.gnome.keyring.NetworkPassword", and + * Each schema has an @name like "org.gnome.keyring.NetworkPassword", and * defines a set of attributes names, and types (string, integer, boolean) for * those attributes. * @@ -126,14 +157,18 @@ G_DEFINE_BOXED_TYPE (SecretSchemaAttribute, secret_schema_attribute, * the values in the table should be integers from the #SecretSchemaAttributeType * enumeration, representing the attribute type for each attribute name. * - * If @flags contains the %SECRET_SCHEMA_ALLOW_UNDEFINED flag, then attributes - * not listed in @attributes are permitted. + * Normally when looking up passwords only those with matching schema names are + * returned. If the schema @flags contain the %SECRET_SCHEMA_DONT_MATCH_NAME flag, + * then lookups will not check that the schema name matches that on the item, only + * the schema's attributes are matched. This is useful when you are looking up items + * that are not stored by the libsecret library. Other libraries such as libgnome-keyring + * don't store the schema name. * * Returns: (transfer full): the new schema, which should be unreferenced with * secret_schema_unref() when done */ SecretSchema * -secret_schema_new (const gchar *identifier, +secret_schema_new (const gchar *name, SecretSchemaFlags flags, GHashTable *attributes) { @@ -145,10 +180,10 @@ secret_schema_new (const gchar *identifier, gint type; gint ind = 0; - g_return_val_if_fail (identifier != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); schema = g_slice_new0 (SecretSchema); - schema->identifier = g_strdup (identifier); + schema->name = g_strdup (name); schema->flags = flags; schema->reserved = 1; @@ -212,7 +247,7 @@ secret_schema_ref (SecretSchema *schema) } else { result = g_slice_new0 (SecretSchema); result->reserved = 1; - result->identifier = g_strdup (schema->identifier); + result->name = g_strdup (schema->name); for (i = 0; i < G_N_ELEMENTS (schema->attributes); i++) { result->attributes[i].name = g_strdup (schema->attributes[i].name); @@ -256,7 +291,7 @@ secret_schema_unref (SecretSchema *schema) g_warning ("should not unreference a static or invalid SecretSchema"); } else if (refs == 0) { - g_free ((gpointer)schema->identifier); + g_free ((gpointer)schema->name); for (i = 0; i < G_N_ELEMENTS (schema->attributes); i++) g_free ((gpointer)schema->attributes[i].name); g_slice_free (SecretSchema, schema); diff --git a/library/secret-schema.h b/library/secret-schema.h index 3bf7ab4..8298ff1 100644 --- a/library/secret-schema.h +++ b/library/secret-schema.h @@ -18,6 +18,7 @@ #define __SECRET_SCHEMA_H__ #include +#include G_BEGIN_DECLS @@ -34,12 +35,11 @@ typedef struct { typedef enum { SECRET_SCHEMA_NONE = 0, - SECRET_SCHEMA_ALLOW_UNDEFINED = 1 << 0, - SECRET_SCHEMA_IGNORE_IDENTIFIER = 1 << 1 + SECRET_SCHEMA_DONT_MATCH_NAME = 1 << 1 } SecretSchemaFlags; typedef struct { - const gchar *identifier; + const gchar *name; SecretSchemaFlags flags; SecretSchemaAttribute attributes[32]; @@ -56,7 +56,7 @@ typedef struct { GType secret_schema_get_type (void) G_GNUC_CONST; -SecretSchema * secret_schema_new (const gchar *identifier, +SecretSchema * secret_schema_new (const gchar *name, SecretSchemaFlags flags, GHashTable *attributes); diff --git a/library/secret-schemas.c b/library/secret-schemas.c index ad6056b..66d89cb 100644 --- a/library/secret-schemas.c +++ b/library/secret-schemas.c @@ -16,7 +16,7 @@ static const SecretSchema network_schema = { "org.gnome.keyring.NetworkPassword", - SECRET_SCHEMA_NONE, + SECRET_SCHEMA_DONT_MATCH_NAME, { { "user", SECRET_SCHEMA_ATTRIBUTE_STRING }, { "domain", SECRET_SCHEMA_ATTRIBUTE_STRING }, diff --git a/library/secret-util.c b/library/secret-util.c index a65b503..c193057 100644 --- a/library/secret-util.c +++ b/library/secret-util.c @@ -115,7 +115,8 @@ _secret_util_variant_for_properties (GHashTable *properties) } GVariant * -_secret_util_variant_for_attributes (GHashTable *attributes) +_secret_util_variant_for_attributes (GHashTable *attributes, + const gchar *schema_name) { GHashTableIter iter; GVariantBuilder builder; @@ -127,8 +128,13 @@ _secret_util_variant_for_attributes (GHashTable *attributes) 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)) - g_variant_builder_add (&builder, "{ss}", name, value); + 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); } @@ -164,6 +170,8 @@ _secret_util_attributes_for_varargs (const SecretSchema *schema, 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 (;;) { @@ -229,9 +237,7 @@ _secret_util_attributes_validate (const SecretSchema *schema, gchar *end; gint i; - /* If no schema, then assume attributes are valid */ - if (schema == NULL) - return TRUE; + 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)) { @@ -248,21 +254,16 @@ _secret_util_attributes_validate (const SecretSchema *schema, } if (attribute == NULL) { - if (!(schema->flags & SECRET_SCHEMA_ALLOW_UNDEFINED)) { - g_warning ("invalid %s attribute in for %s schema", - key, schema->identifier); - return FALSE; - } - - /* Undefined attribute allowed */ - continue; + 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->identifier, value); + key, schema->name, value); return FALSE; } break; @@ -271,20 +272,20 @@ _secret_util_attributes_validate (const SecretSchema *schema, g_ascii_strtoll (value, &end, 10); if (!end || end[0] != '\0') { g_warning ("invalid %s integer value for %s schema: %s", - key, schema->identifier, value); + 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->identifier, value); + key, schema->name, value); return FALSE; } break; default: g_warning ("invalid %s value type in %s schema", - key, schema->identifier); + key, schema->name); return FALSE; } } diff --git a/library/secret.h b/library/secret.h index 09ad77f..62ba243 100644 --- a/library/secret.h +++ b/library/secret.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/library/tests/mock/service.py b/library/tests/mock/service.py index 484286d..b36c2b1 100644 --- a/library/tests/mock/service.py +++ b/library/tests/mock/service.py @@ -282,6 +282,8 @@ class SecretItem(dbus.service.Object): 'Label': self.label, 'Created': dbus.UInt64(self.created), 'Modified': dbus.UInt64(self.modified), + + # For compatibility with libgnome-keyring, not part of spec 'Type': self.type } else: @@ -295,6 +297,7 @@ class SecretItem(dbus.service.Object): self.label = str(new_value) elif property_name == "Attributes": self.attributes = dict(new_value) + # For compatibility with libgnome-keyring, not part of spec elif property_name == "Type": self.type = str(new_value) else: @@ -390,12 +393,14 @@ class SecretCollection(dbus.service.Object): if not session or session.sender != sender: raise InvalidArgs("session invalid: %s" % session_path) - attributes = properties.get("org.freedesktop.Secret.Item.Attributes", None) + attributes = properties.get("org.freedesktop.Secret.Item.Attributes", { }) label = properties.get("org.freedesktop.Secret.Item.Label", None) - type = properties.get("org.freedesktop.Secret.Item.Type", None) (secret, content_type) = session.decode_secret(value) item = None + # This is done for compatibility with libgnome-keyring, not part of spec + type = properties.get("org.freedesktop.Secret.Item.Type", None) + if replace: items = self.search_items(attributes) if items: @@ -487,22 +492,38 @@ class SecretService(dbus.service.Object): def add_standard_objects(self): collection = SecretCollection(self, "english", label="Collection One", locked=False) - SecretItem(collection, "1", label="Item One", - attributes={ "number": "1", "string": "one", "even": "false" }, - secret="111", type="org.mock.type.Store") - SecretItem(collection, "2", attributes={ "number": "2", "string": "two", "even": "true" }, secret="222") - SecretItem(collection, "3", attributes={ "number": "3", "string": "three", "even": "false" }, secret="3333") + SecretItem(collection, "1", label="Item One", secret="111", + attributes={ "number": "1", "string": "one", "even": "false", "xdg:schema": "org.mock.Schema" }) + SecretItem(collection, "2", label="Item Two", secret="222", + attributes={ "number": "2", "string": "two", "even": "true", "xdg:schema": "org.mock.Schema" }) + SecretItem(collection, "3", label="Item Three", secret="333", + attributes={ "number": "3", "string": "three", "even": "false", "xdg:schema": "org.mock.Schema" }) self.set_alias('default', collection) collection = SecretCollection(self, "spanish", locked=True) - SecretItem(collection, "10", attributes={ "number": "1", "string": "uno", "even": "false" }, secret="111") - SecretItem(collection, "20", attributes={ "number": "2", "string": "dos", "even": "true" }, secret="222") - SecretItem(collection, "30", attributes={ "number": "3", "string": "tres", "even": "false" }, secret="3333") + SecretItem(collection, "10", secret="111", + attributes={ "number": "1", "string": "uno", "even": "false", "xdg:schema": "org.mock.Schema" }) + SecretItem(collection, "20", secret="222", + attributes={ "number": "2", "string": "dos", "even": "true", "xdg:schema": "org.mock.Schema" }) + SecretItem(collection, "30", secret="3333", + attributes={ "number": "3", "string": "tres", "even": "false", "xdg:schema": "org.mock.Schema" }) + + collection = SecretCollection(self, "german", locked=True) + SecretItem(collection, "300", secret="333", + attributes={ "number": "3", "string": "drei", "prime": "true", "xdg:schema": "org.mock.Primes" }) + SecretItem(collection, "400", secret="444", + attributes={ "number": "4", "string": "vier", "prime": "false", "xdg:schema": "org.mock.Primes" }) + SecretItem(collection, "500", secret="555", + attributes={ "number": "5", "string": "fuenf", "prime": "true", "xdg:schema": "org.mock.Primes" }) + SecretItem(collection, "600", secret="666", + attributes={ "number": "6", "string": "sechs", "prime": "false", "xdg:schema": "org.mock.Primes" }) collection = SecretCollection(self, "empty", locked=False) collection = SecretCollection(self, "session", label="Session Keyring", locked=False) + self.set_alias('session', collection) + def listen(self): global ready_pipe loop = gobject.MainLoop() diff --git a/library/tests/test-item.c b/library/tests/test-item.c index 3bc994e..da71f7e 100644 --- a/library/tests/test-item.c +++ b/library/tests/test-item.c @@ -174,7 +174,7 @@ test_create_sync (Test *test, value = secret_value_new ("Hoohah", -1, "text/plain"); - item = secret_item_create_sync (collection, "org.mock.Schema", "Tunnel", + item = secret_item_create_sync (collection, "Tunnel", attributes, value, FALSE, NULL, &error); g_assert_no_error (error); @@ -185,7 +185,6 @@ test_create_sync (Test *test, g_assert (g_str_has_prefix (g_dbus_proxy_get_object_path (G_DBUS_PROXY (item)), collection_path)); g_assert_cmpstr (secret_item_get_label (item), ==, "Tunnel"); g_assert (secret_item_get_locked (item) == FALSE); - g_assert_cmpstr (secret_item_get_schema (item), ==, "org.freedesktop.Secret.Generic"); g_object_unref (item); egg_assert_not_object (item); @@ -213,7 +212,7 @@ test_create_async (Test *test, value = secret_value_new ("Hoohah", -1, "text/plain"); - secret_item_create (collection, "org.mock.Schema", "Tunnel", + secret_item_create (collection, "Tunnel", attributes, value, FALSE, NULL, on_async_result, &result); g_assert_no_error (error); @@ -230,7 +229,6 @@ test_create_async (Test *test, g_assert (g_str_has_prefix (g_dbus_proxy_get_object_path (G_DBUS_PROXY (item)), collection_path)); g_assert_cmpstr (secret_item_get_label (item), ==, "Tunnel"); g_assert (secret_item_get_locked (item) == FALSE); - g_assert_cmpstr (secret_item_get_schema (item), ==, "org.freedesktop.Secret.Generic"); g_object_unref (item); egg_assert_not_object (item); @@ -248,7 +246,6 @@ test_properties (Test *test, guint64 created; guint64 modified; gboolean locked; - gchar *schema; gchar *label; item = secret_item_new_sync (test->service, item_path, NULL, &error); @@ -258,10 +255,6 @@ test_properties (Test *test, g_assert_cmpuint (secret_item_get_created (item), <=, time (NULL)); g_assert_cmpuint (secret_item_get_modified (item), <=, time (NULL)); - schema = secret_item_get_schema (item); - g_assert_cmpstr (schema, ==, "org.mock.type.Store"); - g_free (schema); - label = secret_item_get_label (item); g_assert_cmpstr (label, ==, "Item One"); g_free (label); @@ -270,7 +263,7 @@ test_properties (Test *test, g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); - g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); + g_assert_cmpuint (g_hash_table_size (attributes), ==, 4); g_hash_table_unref (attributes); g_object_get (item, @@ -278,7 +271,6 @@ test_properties (Test *test, "created", &created, "modified", &modified, "label", &label, - "schema", &schema, "attributes", &attributes, "service", &service, NULL); @@ -290,13 +282,10 @@ test_properties (Test *test, g_assert_cmpstr (label, ==, "Item One"); g_free (label); - g_assert_cmpstr (schema, ==, "org.mock.type.Store"); - g_free (schema); - g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); - g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); + g_assert_cmpuint (g_hash_table_size (attributes), ==, 4); g_hash_table_unref (attributes); g_assert (service == test->service); @@ -415,7 +404,7 @@ test_set_attributes_sync (Test *test, g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); - g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); + g_assert_cmpuint (g_hash_table_size (attributes), ==, 4); g_hash_table_unref (attributes); attributes = g_hash_table_new (g_str_hash, g_str_equal); @@ -453,7 +442,7 @@ test_set_attributes_async (Test *test, g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); - g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); + g_assert_cmpuint (g_hash_table_size (attributes), ==, 4); g_hash_table_unref (attributes); attributes = g_hash_table_new (g_str_hash, g_str_equal); @@ -495,7 +484,7 @@ test_set_attributes_prop (Test *test, g_assert_cmpstr (g_hash_table_lookup (attributes, "string"), ==, "one"); g_assert_cmpstr (g_hash_table_lookup (attributes, "number"), ==, "1"); g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false"); - g_assert_cmpuint (g_hash_table_size (attributes), ==, 3); + g_assert_cmpuint (g_hash_table_size (attributes), ==, 4); g_hash_table_unref (attributes); g_signal_connect (item, "notify::attributes", G_CALLBACK (on_notify_stop), &sigs); diff --git a/library/tests/test-lookup-password.js b/library/tests/test-lookup-password.js index 32de442..03af5eb 100644 --- a/library/tests/test-lookup-password.js +++ b/library/tests/test-lookup-password.js @@ -10,7 +10,7 @@ const assertTrue = JsUnit.assertTrue; Mock.start("mock-service-normal.py"); -const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store", +const STORE_SCHEMA = new Secret.Schema.new("org.mock.Schema", Secret.SchemaFlags.NONE, { "number": Secret.SchemaAttributeType.INTEGER, diff --git a/library/tests/test-lookup-password.py b/library/tests/test-lookup-password.py index 27b6d2c..aa548aa 100644 --- a/library/tests/test-lookup-password.py +++ b/library/tests/test-lookup-password.py @@ -7,7 +7,7 @@ from gi.repository import Secret, GLib Mock.start("mock-service-normal.py") -STORE_SCHEMA = Secret.Schema.new("org.mock.type.Store", +STORE_SCHEMA = Secret.Schema.new("org.mock.Schema", Secret.SchemaFlags.NONE, { "number": Secret.SchemaAttributeType.INTEGER, diff --git a/library/tests/test-methods.c b/library/tests/test-methods.c index 8c256fc..377fb85 100644 --- a/library/tests/test-methods.c +++ b/library/tests/test-methods.c @@ -27,8 +27,8 @@ #include #include -static const SecretSchema DELETE_SCHEMA = { - "org.mock.schema.Delete", +static const SecretSchema MOCK_SCHEMA = { + "org.mock.Schema", SECRET_SCHEMA_NONE, { { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, @@ -37,13 +37,22 @@ static const SecretSchema DELETE_SCHEMA = { } }; -static const SecretSchema STORE_SCHEMA = { - "org.mock.type.Store", +static const SecretSchema PRIME_SCHEMA = { + "org.mock.Prime", SECRET_SCHEMA_NONE, { { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, { "string", SECRET_SCHEMA_ATTRIBUTE_STRING }, - { "even", SECRET_SCHEMA_ATTRIBUTE_BOOLEAN }, + { "prime", SECRET_SCHEMA_ATTRIBUTE_BOOLEAN }, + } +}; + +static const SecretSchema NO_NAME_SCHEMA = { + "unused.Schema.Name", + SECRET_SCHEMA_DONT_MATCH_NAME, + { + { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, + { "string", SECRET_SCHEMA_ATTRIBUTE_STRING }, } }; @@ -905,9 +914,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))); - g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Type", - g_variant_ref_sink (g_variant_new_string ("org.gnome.Test"))); + g_variant_ref_sink (_secret_util_variant_for_attributes (attributes, "org.gnome.Test"))); g_hash_table_unref (attributes); @@ -949,9 +956,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))); - g_hash_table_insert (properties, SECRET_COLLECTION_INTERFACE ".Type", - g_variant_ref_sink (g_variant_new_string ("org.gnome.Test"))); + g_variant_ref_sink (_secret_util_variant_for_attributes (attributes, NULL))); g_hash_table_unref (attributes); @@ -984,7 +989,7 @@ test_remove_sync (Test *test, GError *error = NULL; gboolean ret; - ret = secret_service_remove_sync (test->service, &DELETE_SCHEMA, NULL, &error, + ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, NULL, &error, "even", FALSE, "string", "one", "number", 1, @@ -1002,7 +1007,7 @@ test_remove_async (Test *test, GAsyncResult *result = NULL; gboolean ret; - secret_service_remove (test->service, &DELETE_SCHEMA, NULL, + secret_service_remove (test->service, &MOCK_SCHEMA, NULL, on_complete_get_result, &result, "even", FALSE, "string", "one", @@ -1027,7 +1032,7 @@ test_remove_locked (Test *test, GError *error = NULL; gboolean ret; - ret = secret_service_remove_sync (test->service, &DELETE_SCHEMA, NULL, &error, + ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, NULL, &error, "even", FALSE, "string", "tres", "number", 3, @@ -1045,7 +1050,7 @@ test_remove_no_match (Test *test, gboolean ret; /* Won't match anything */ - ret = secret_service_remove_sync (test->service, &DELETE_SCHEMA, NULL, &error, + ret = secret_service_remove_sync (test->service, &MOCK_SCHEMA, NULL, &error, "even", TRUE, "string", "one", NULL); @@ -1054,6 +1059,29 @@ test_remove_no_match (Test *test, g_assert (ret == FALSE); } +static void +test_remove_no_name (Test *test, + gconstpointer used) +{ + GError *error = NULL; + gboolean ret; + + /* 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); + 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); + + g_assert_no_error (error); + g_assert (ret == TRUE); +} + static void test_lookup_sync (Test *test, gconstpointer used) @@ -1062,7 +1090,7 @@ test_lookup_sync (Test *test, SecretValue *value; gsize length; - value = secret_service_lookup_sync (test->service, &STORE_SCHEMA, NULL, &error, + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, "even", FALSE, "string", "one", "number", 1, @@ -1086,7 +1114,7 @@ test_lookup_async (Test *test, SecretValue *value; gsize length; - secret_service_lookup (test->service, &STORE_SCHEMA, NULL, + secret_service_lookup (test->service, &MOCK_SCHEMA, NULL, on_complete_get_result, &result, "even", FALSE, "string", "one", @@ -1116,7 +1144,7 @@ test_lookup_locked (Test *test, SecretValue *value; gsize length; - value = secret_service_lookup_sync (test->service, &STORE_SCHEMA, NULL, &error, + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, "even", FALSE, "string", "tres", "number", 3, @@ -1139,7 +1167,7 @@ test_lookup_no_match (Test *test, SecretValue *value; /* Won't match anything */ - value = secret_service_lookup_sync (test->service, &STORE_SCHEMA, NULL, &error, + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, "even", TRUE, "string", "one", NULL); @@ -1148,6 +1176,35 @@ test_lookup_no_match (Test *test, g_assert (value == NULL); } +static void +test_lookup_no_name (Test *test, + gconstpointer used) +{ + GError *error = NULL; + SecretValue *value; + gsize length; + + /* should return null, because nothing with mock schema and 5 */ + value = secret_service_lookup_sync (test->service, &MOCK_SCHEMA, NULL, &error, + "number", 5, + NULL); + 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); + + g_assert_no_error (error); + + g_assert (value != NULL); + g_assert_cmpstr (secret_value_get (value, &length), ==, "555"); + g_assert_cmpuint (length, ==, 3); + + secret_value_unref (value); +} + static void test_store_sync (Test *test, gconstpointer used) @@ -1160,7 +1217,7 @@ test_store_sync (Test *test, gboolean ret; gsize length; - ret = secret_service_store_sync (test->service, &STORE_SCHEMA, collection_path, + ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, collection_path, "New Item Label", value, NULL, &error, "even", FALSE, "string", "seventeen", @@ -1206,7 +1263,7 @@ test_store_replace (Test *test, gchar **paths; gboolean ret; - ret = secret_service_store_sync (test->service, &STORE_SCHEMA, collection_path, + ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, collection_path, "New Item Label", value, NULL, &error, "even", FALSE, "string", "seventeen", @@ -1214,7 +1271,7 @@ test_store_replace (Test *test, NULL); g_assert_no_error (error); - ret = secret_service_store_sync (test->service, &STORE_SCHEMA, collection_path, + ret = secret_service_store_sync (test->service, &MOCK_SCHEMA, collection_path, "Another Label", value, NULL, &error, "even", FALSE, "string", "seventeen", @@ -1253,7 +1310,7 @@ test_store_async (Test *test, gboolean ret; gsize length; - secret_service_store (test->service, &STORE_SCHEMA, collection_path, + secret_service_store (test->service, &MOCK_SCHEMA, collection_path, "New Item Label", value, NULL, on_complete_get_result, &result, "even", FALSE, "string", "seventeen", @@ -1337,11 +1394,13 @@ main (int argc, char **argv) g_test_add ("/service/lookup-async", Test, "mock-service-normal.py", setup, test_lookup_async, teardown); g_test_add ("/service/lookup-locked", Test, "mock-service-normal.py", setup, test_lookup_locked, teardown); g_test_add ("/service/lookup-no-match", Test, "mock-service-normal.py", setup, test_lookup_no_match, teardown); + g_test_add ("/service/lookup-no-name", Test, "mock-service-normal.py", setup, test_lookup_no_name, teardown); g_test_add ("/service/remove-sync", Test, "mock-service-delete.py", setup, test_remove_sync, teardown); g_test_add ("/service/remove-async", Test, "mock-service-delete.py", setup, test_remove_async, teardown); g_test_add ("/service/remove-locked", Test, "mock-service-delete.py", setup, test_remove_locked, teardown); g_test_add ("/service/remove-no-match", Test, "mock-service-delete.py", setup, test_remove_no_match, teardown); + g_test_add ("/service/remove-no-name", Test, "mock-service-delete.py", setup, test_remove_no_name, teardown); 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); diff --git a/library/tests/test-password.c b/library/tests/test-password.c index 65ecca7..d5829df 100644 --- a/library/tests/test-password.c +++ b/library/tests/test-password.c @@ -26,8 +26,8 @@ #include #include -static const SecretSchema PASSWORD_SCHEMA = { - "org.mock.schema.Password", +static const SecretSchema MOCK_SCHEMA = { + "org.mock.Schema", SECRET_SCHEMA_NONE, { { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, @@ -36,6 +36,25 @@ static const SecretSchema PASSWORD_SCHEMA = { } }; +static const SecretSchema PRIME_SCHEMA = { + "org.mock.Prime", + SECRET_SCHEMA_NONE, + { + { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, + { "string", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "prime", SECRET_SCHEMA_ATTRIBUTE_BOOLEAN }, + } +}; + +static const SecretSchema NO_NAME_SCHEMA = { + "unused.Schema.Name", + SECRET_SCHEMA_DONT_MATCH_NAME, + { + { "number", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, + { "string", SECRET_SCHEMA_ATTRIBUTE_STRING }, + } +}; + typedef struct { GPid pid; } Test; @@ -77,7 +96,7 @@ test_lookup_sync (Test *test, gchar *password; GError *error = NULL; - password = secret_password_lookup_nonpageable_sync (&PASSWORD_SCHEMA, NULL, &error, + password = secret_password_lookup_nonpageable_sync (&MOCK_SCHEMA, NULL, &error, "even", FALSE, "string", "one", "number", 1, @@ -97,7 +116,7 @@ test_lookup_async (Test *test, GError *error = NULL; gchar *password; - secret_password_lookup (&PASSWORD_SCHEMA, NULL, on_complete_get_result, &result, + secret_password_lookup (&MOCK_SCHEMA, NULL, on_complete_get_result, &result, "even", FALSE, "string", "one", "number", 1, @@ -114,6 +133,31 @@ test_lookup_async (Test *test, secret_password_free (password); } +static void +test_lookup_no_name (Test *test, + gconstpointer used) +{ + GError *error = NULL; + gchar *password; + + /* should return null, because nothing with mock schema and 5 */ + password = secret_password_lookup_sync (&MOCK_SCHEMA, NULL, &error, + "number", 5, + NULL); + g_assert_no_error (error); + g_assert (password == NULL); + + /* should return an item, because we have a prime schema with 5, and flags not to match name */ + password = secret_password_lookup_sync (&NO_NAME_SCHEMA, NULL, &error, + "number", 5, + NULL); + + g_assert_no_error (error); + g_assert_cmpstr (password, ==, "555"); + + secret_password_free (password); +} + static void test_store_sync (Test *test, gconstpointer used) @@ -123,7 +167,7 @@ test_store_sync (Test *test, gchar *password; gboolean ret; - ret = secret_password_store_sync (&PASSWORD_SCHEMA, collection_path, + ret = secret_password_store_sync (&MOCK_SCHEMA, collection_path, "Label here", "the password", NULL, &error, "even", TRUE, "string", "twelve", @@ -133,7 +177,7 @@ test_store_sync (Test *test, g_assert_no_error (error); g_assert (ret == TRUE); - password = secret_password_lookup_nonpageable_sync (&PASSWORD_SCHEMA, NULL, &error, + password = secret_password_lookup_nonpageable_sync (&MOCK_SCHEMA, NULL, &error, "string", "twelve", NULL); @@ -153,7 +197,7 @@ test_store_async (Test *test, gchar *password; gboolean ret; - secret_password_store (&PASSWORD_SCHEMA, collection_path, "Label here", + secret_password_store (&MOCK_SCHEMA, collection_path, "Label here", "the password", NULL, on_complete_get_result, &result, "even", TRUE, "string", "twelve", @@ -168,7 +212,7 @@ test_store_async (Test *test, g_assert (ret == TRUE); g_object_unref (result); - password = secret_password_lookup_nonpageable_sync (&PASSWORD_SCHEMA, NULL, &error, + password = secret_password_lookup_nonpageable_sync (&MOCK_SCHEMA, NULL, &error, "string", "twelve", NULL); @@ -185,7 +229,7 @@ test_delete_sync (Test *test, GError *error = NULL; gboolean ret; - ret = secret_password_remove_sync (&PASSWORD_SCHEMA, NULL, &error, + ret = secret_password_remove_sync (&MOCK_SCHEMA, NULL, &error, "even", FALSE, "string", "one", "number", 1, @@ -203,7 +247,7 @@ test_delete_async (Test *test, GAsyncResult *result = NULL; gboolean ret; - secret_password_remove (&PASSWORD_SCHEMA, NULL, + secret_password_remove (&MOCK_SCHEMA, NULL, on_complete_get_result, &result, "even", FALSE, "string", "one", @@ -221,6 +265,29 @@ test_delete_async (Test *test, g_object_unref (result); } +static void +test_remove_no_name (Test *test, + gconstpointer used) +{ + GError *error = NULL; + gboolean ret; + + /* Shouldn't match anything, because no item with 5 in mock schema */ + ret = secret_password_remove_sync (&MOCK_SCHEMA, NULL, &error, + "number", 5, + NULL); + 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_password_remove_sync (&NO_NAME_SCHEMA, NULL, &error, + "number", 5, + NULL); + + g_assert_no_error (error); + g_assert (ret == TRUE); +} + static void test_password_free_null (void) { @@ -236,12 +303,14 @@ main (int argc, char **argv) g_test_add ("/password/lookup-sync", Test, "mock-service-normal.py", setup, test_lookup_sync, teardown); g_test_add ("/password/lookup-async", Test, "mock-service-normal.py", setup, test_lookup_async, teardown); + g_test_add ("/password/lookup-no-name", Test, "mock-service-normal.py", setup, test_lookup_no_name, teardown); g_test_add ("/password/store-sync", Test, "mock-service-normal.py", setup, test_store_sync, teardown); g_test_add ("/password/store-async", Test, "mock-service-normal.py", setup, test_store_async, teardown); g_test_add ("/password/delete-sync", Test, "mock-service-delete.py", setup, test_delete_sync, teardown); g_test_add ("/password/delete-async", Test, "mock-service-delete.py", setup, test_delete_async, teardown); + g_test_add ("/password/remove-no-name", Test, "mock-service-delete.py", setup, test_remove_no_name, teardown); g_test_add_func ("/password/free-null", test_password_free_null); diff --git a/library/tests/test-remove-password.js b/library/tests/test-remove-password.js index 8425cef..2d5a978 100644 --- a/library/tests/test-remove-password.js +++ b/library/tests/test-remove-password.js @@ -10,7 +10,7 @@ const assertTrue = JsUnit.assertTrue; Mock.start("mock-service-normal.py"); -const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store", +const STORE_SCHEMA = new Secret.Schema.new("org.mock.Schema", Secret.SchemaFlags.NONE, { "number": Secret.SchemaAttributeType.INTEGER, diff --git a/library/tests/test-remove-password.py b/library/tests/test-remove-password.py index 06ac1bb..b7c770b 100644 --- a/library/tests/test-remove-password.py +++ b/library/tests/test-remove-password.py @@ -7,7 +7,7 @@ from gi.repository import Secret, GLib Mock.start("mock-service-normal.py") -STORE_SCHEMA = Secret.Schema.new("org.mock.type.Store", +STORE_SCHEMA = Secret.Schema.new("org.mock.Schema", Secret.SchemaFlags.NONE, { "number": Secret.SchemaAttributeType.INTEGER, diff --git a/library/tests/test-store-password.js b/library/tests/test-store-password.js index 254c162..802765b 100644 --- a/library/tests/test-store-password.js +++ b/library/tests/test-store-password.js @@ -10,7 +10,7 @@ const assertTrue = JsUnit.assertTrue; Mock.start("mock-service-normal.py"); -const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store", +const STORE_SCHEMA = new Secret.Schema.new("org.mock.Schema", Secret.SchemaFlags.NONE, { "number": Secret.SchemaAttributeType.INTEGER, diff --git a/library/tests/test-store-password.py b/library/tests/test-store-password.py index 93d1f30..8e0762b 100644 --- a/library/tests/test-store-password.py +++ b/library/tests/test-store-password.py @@ -7,7 +7,7 @@ from gi.repository import Secret, GLib Mock.start("mock-service-normal.py") -STORE_SCHEMA = Secret.Schema.new("org.mock.type.Store", +STORE_SCHEMA = Secret.Schema.new("org.mock.Schema", Secret.SchemaFlags.NONE, { "number": Secret.SchemaAttributeType.INTEGER,