summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@src.gnome.org>2019-06-17 15:30:00 +0200
committerDaiki Ueno <ueno@gnu.org>2019-07-18 13:54:12 +0000
commit5fedca8ffc1e57c55ee564c39d1c2d579a15f01f (patch)
tree41f49a539b3b609503efa858fc0493cb0b9a595e
parent092d4ef47dfbc3e37fdca6c924a9421f3b098665 (diff)
downloadlibsecret-5fedca8ffc1e57c55ee564c39d1c2d579a15f01f.tar.gz
secret-password: Add search functions
This adds a set of functions that expose secret_service_search* from the simple API.
-rw-r--r--docs/reference/libsecret/libsecret-sections.txt5
-rw-r--r--libsecret/secret-password.c220
-rw-r--r--libsecret/secret-password.h29
-rw-r--r--libsecret/secret-service.h7
-rw-r--r--libsecret/secret-types.h7
-rw-r--r--libsecret/test-password.c88
6 files changed, 349 insertions, 7 deletions
diff --git a/docs/reference/libsecret/libsecret-sections.txt b/docs/reference/libsecret/libsecret-sections.txt
index 17ee05f..b561366 100644
--- a/docs/reference/libsecret/libsecret-sections.txt
+++ b/docs/reference/libsecret/libsecret-sections.txt
@@ -133,6 +133,11 @@ secret_password_clearv
secret_password_clear_finish
secret_password_clear_sync
secret_password_clearv_sync
+secret_password_search
+secret_password_search_finish
+secret_password_search_sync
+secret_password_searchv
+secret_password_searchv_sync
secret_password_wipe
secret_password_free
</SECTION>
diff --git a/libsecret/secret-password.c b/libsecret/secret-password.c
index 149995d..fc0ea0c 100644
--- a/libsecret/secret-password.c
+++ b/libsecret/secret-password.c
@@ -17,6 +17,7 @@
#include "secret-attributes.h"
#include "secret-password.h"
#include "secret-private.h"
+#include "secret-retrievable.h"
#include "secret-value.h"
#include <egg/egg-secure-memory.h>
@@ -845,6 +846,225 @@ secret_password_clearv_sync (const SecretSchema *schema,
}
/**
+ * secret_password_search: (skip)
+ * @schema: the schema for the attributes
+ * @flags: search option flags
+ * @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
+ *
+ * Search for items 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.
+ *
+ * Since: 0.19.0
+ */
+void
+secret_password_search (const SecretSchema *schema,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ ...)
+{
+ GHashTable *attributes;
+ va_list va;
+
+ g_return_if_fail (schema != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ va_start (va, user_data);
+ attributes = secret_attributes_buildv (schema, va);
+ va_end (va);
+
+ /* Precondition failed, already warned */
+ if (!attributes)
+ return;
+
+ secret_password_searchv (schema, attributes, flags, cancellable,
+ callback, user_data);
+
+ g_hash_table_unref (attributes);
+}
+
+/**
+ * secret_password_searchv: (rename-to secret_password_search)
+ * @schema: the schema for attributes
+ * @attributes: (element-type utf8 utf8): the attribute keys and values
+ * @flags: search option flags
+ * @cancellable: optional cancellation object
+ * @callback: called when the operation completes
+ * @user_data: data to be passed to the callback
+ *
+ * Search for items in the secret service.
+ *
+ * The @attributes should be a set of key and value string pairs.
+ *
+ * This method will return immediately and complete asynchronously.
+ *
+ * Since: 0.19.0
+ */
+void
+secret_password_searchv (const SecretSchema *schema,
+ GHashTable *attributes,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (schema != NULL);
+ g_return_if_fail (attributes != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ /* Warnings raised already */
+ if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
+ return;
+
+ secret_service_search (NULL, schema, attributes, flags,
+ cancellable, callback, user_data);
+}
+
+/**
+ * secret_password_search_finish:
+ * @result: the asynchronous result passed to the callback
+ * @error: location to place an error on failure
+ *
+ * Finish an asynchronous operation to search for items in the secret service.
+ *
+ * Returns: (transfer full) (element-type Secret.Retrievable): a list of
+ * #SecretRetrievable containing attributes of the matched items
+ *
+ * Since: 0.19.0
+ */
+GList *
+secret_password_search_finish (GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ return secret_service_search_finish (NULL, result, error);
+}
+
+/**
+ * secret_password_search_sync: (skip)
+ * @schema: the schema for the attributes
+ * @flags: search option flags
+ * @cancellable: optional cancellation object
+ * @error: location to place an error on failure
+ * @...: the attribute keys and values, terminated with %NULL
+ *
+ * Search for items 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 attributes 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) (element-type Secret.Retrievable): a list of
+ * #SecretRetrievable containing attributes of the matched items
+ *
+ * Since: 0.19.0
+ */
+GList *
+secret_password_search_sync (const SecretSchema *schema,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GError **error,
+ ...)
+{
+ GHashTable *attributes;
+ GList *items;
+ va_list va;
+
+ g_return_val_if_fail (schema != NULL, NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ va_start (va, error);
+ attributes = secret_attributes_buildv (schema, va);
+ va_end (va);
+
+ /* Precondition failed, already warned */
+ if (!attributes)
+ return NULL;
+
+ items = secret_password_searchv_sync (schema, attributes, flags,
+ cancellable, error);
+
+ g_hash_table_unref (attributes);
+
+ return items;
+}
+
+/**
+ * secret_password_searchv_sync: (rename-to secret_password_search_sync)
+ * @schema: the schema for attributes
+ * @attributes: (element-type utf8 utf8): the attribute keys and values
+ * @flags: search option flags
+ * @cancellable: optional cancellation object
+ * @error: location to place an error on failure
+ *
+ * Search for items in the secret service.
+ *
+ * The @attributes should be a set of key and value string pairs.
+ *
+ * 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) (element-type Secret.Retrievable): a list of
+ * #SecretRetrievable containing attributes of the matched items
+ *
+ * Since: 0.19.0
+ */
+GList *
+secret_password_searchv_sync (const SecretSchema *schema,
+ GHashTable *attributes,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SecretSync *sync;
+ GList *items;
+
+ 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);
+
+ /* Warnings raised already */
+ if (!_secret_attributes_validate (schema, attributes, G_STRFUNC, TRUE))
+ return NULL;
+
+ sync = _secret_sync_new ();
+ g_main_context_push_thread_default (sync->context);
+
+ secret_password_searchv (schema, attributes, flags, cancellable,
+ _secret_sync_on_result, sync);
+
+ g_main_loop_run (sync->loop);
+
+ items = secret_password_search_finish (sync->result, error);
+
+ g_main_context_pop_thread_default (sync->context);
+ _secret_sync_free (sync);
+
+ return items;
+}
+
+/**
* secret_password_free: (skip)
* @password: (allow-none): password to free
*
diff --git a/libsecret/secret-password.h b/libsecret/secret-password.h
index d47abb3..725d11b 100644
--- a/libsecret/secret-password.h
+++ b/libsecret/secret-password.h
@@ -126,6 +126,35 @@ gboolean secret_password_clearv_sync (const SecretSchema *sche
GCancellable *cancellable,
GError **error);
+void secret_password_search (const SecretSchema *schema,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data,
+ ...) G_GNUC_NULL_TERMINATED;
+
+void secret_password_searchv (const SecretSchema *schema,
+ GHashTable *attributes,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GList * secret_password_search_sync (const SecretSchema *schema,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GError **error,
+ ...) G_GNUC_NULL_TERMINATED;
+
+GList * secret_password_searchv_sync (const SecretSchema *schema,
+ GHashTable *attributes,
+ SecretSearchFlags flags,
+ GCancellable *cancellable,
+ GError **error);
+
+GList * secret_password_search_finish (GAsyncResult *result,
+ GError **error);
+
void secret_password_free (gchar *password);
void secret_password_wipe (gchar *password);
diff --git a/libsecret/secret-service.h b/libsecret/secret-service.h
index 4c3a827..44cbc1e 100644
--- a/libsecret/secret-service.h
+++ b/libsecret/secret-service.h
@@ -35,13 +35,6 @@ typedef enum {
SECRET_SERVICE_LOAD_COLLECTIONS = 1 << 2,
} SecretServiceFlags;
-typedef enum {
- SECRET_SEARCH_NONE = 0,
- SECRET_SEARCH_ALL = 1 << 1,
- SECRET_SEARCH_UNLOCK = 1 << 2,
- SECRET_SEARCH_LOAD_SECRETS = 1 << 3,
-} SecretSearchFlags;
-
#define SECRET_TYPE_SERVICE (secret_service_get_type ())
#define SECRET_SERVICE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), SECRET_TYPE_SERVICE, SecretService))
#define SECRET_SERVICE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), SECRET_TYPE_SERVICE, SecretServiceClass))
diff --git a/libsecret/secret-types.h b/libsecret/secret-types.h
index 708c53f..cbbd3b1 100644
--- a/libsecret/secret-types.h
+++ b/libsecret/secret-types.h
@@ -38,6 +38,13 @@ typedef enum {
#define SECRET_COLLECTION_SESSION "session"
+typedef enum {
+ SECRET_SEARCH_NONE = 0,
+ SECRET_SEARCH_ALL = 1 << 1,
+ SECRET_SEARCH_UNLOCK = 1 << 2,
+ SECRET_SEARCH_LOAD_SECRETS = 1 << 3,
+} SecretSearchFlags;
+
G_END_DECLS
#endif /* __G_SERVICE_H___ */
diff --git a/libsecret/test-password.c b/libsecret/test-password.c
index cbfb561..01053eb 100644
--- a/libsecret/test-password.c
+++ b/libsecret/test-password.c
@@ -357,6 +357,90 @@ test_clear_no_name (Test *test,
}
static void
+free_attributes (gpointer data,
+ gpointer user_data)
+{
+ g_object_unref ((GObject *)data);
+}
+
+static void
+test_search_sync (Test *test,
+ gconstpointer used)
+{
+ GList *items;
+ GError *error = NULL;
+
+ items = secret_password_search_sync (&MOCK_SCHEMA, SECRET_SEARCH_ALL,
+ NULL, &error,
+ "even", FALSE,
+ "string", "one",
+ "number", 1,
+ NULL);
+
+ g_assert_no_error (error);
+ g_assert_cmpint (g_list_length (items), ==, 1);
+
+ g_list_foreach (items, free_attributes, NULL);
+ g_list_free (items);
+}
+
+static void
+test_search_async (Test *test,
+ gconstpointer used)
+{
+ GAsyncResult *result = NULL;
+ GError *error = NULL;
+ GList *items;
+
+ secret_password_search (&MOCK_SCHEMA, SECRET_SEARCH_ALL,
+ NULL, on_complete_get_result, &result,
+ "even", FALSE,
+ "string", "one",
+ "number", 1,
+ NULL);
+ g_assert (result == NULL);
+
+ egg_test_wait ();
+
+ items = secret_password_search_finish (result, &error);
+ g_assert_no_error (error);
+ g_object_unref (result);
+
+ g_assert_cmpint (g_list_length (items), ==, 1);
+
+ g_list_foreach (items, free_attributes, NULL);
+ g_list_free (items);
+}
+
+static void
+test_search_no_name (Test *test,
+ gconstpointer used)
+{
+ GError *error = NULL;
+ GList *items;
+
+ /* should return null, because nothing with mock schema and 5 */
+ items = secret_password_search_sync (&MOCK_SCHEMA, SECRET_SEARCH_ALL,
+ NULL, &error,
+ "number", 5,
+ NULL);
+ g_assert_no_error (error);
+ g_assert (items == NULL);
+
+ /* should return an item, because we have a prime schema with 5, and flags not to match name */
+ items = secret_password_search_sync (&NO_NAME_SCHEMA, SECRET_SEARCH_ALL,
+ NULL, &error,
+ "number", 5,
+ NULL);
+
+ g_assert_no_error (error);
+ g_assert_cmpint (g_list_length (items), ==, 1);
+
+ g_list_foreach (items, free_attributes, NULL);
+ g_list_free (items);
+}
+
+static void
test_password_free_null (void)
{
secret_password_free (NULL);
@@ -380,6 +464,10 @@ main (int argc, char **argv)
g_test_add ("/password/delete-async", Test, "mock-service-delete.py", setup, test_delete_async, teardown);
g_test_add ("/password/clear-no-name", Test, "mock-service-delete.py", setup, test_clear_no_name, teardown);
+ g_test_add ("/password/search-sync", Test, "mock-service-normal.py", setup, test_search_sync, teardown);
+ g_test_add ("/password/search-async", Test, "mock-service-normal.py", setup, test_search_async, teardown);
+ g_test_add ("/password/search-no-name", Test, "mock-service-normal.py", setup, test_search_no_name, teardown);
+
g_test_add_func ("/password/free-null", test_password_free_null);
return egg_tests_run_with_loop ();