summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--library/secret-methods.c47
-rw-r--r--library/secret-password.c27
-rw-r--r--library/secret-types.h4
-rw-r--r--library/tests/Makefile.am20
-rw-r--r--library/tests/test-javascript.js14
-rw-r--r--library/tests/test-lookup-password.js52
-rw-r--r--library/tests/test-remove-password.js68
-rw-r--r--library/tests/test-store-password.js58
9 files changed, 266 insertions, 26 deletions
diff --git a/.gitignore b/.gitignore
index 94b017b..e9f73af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,4 +65,6 @@ stamp*
/library/secret-enum-types.[ch]
/library/tests/test-*
!/library/tests/test-*.c
+!/library/tests/test-*.js
+!/library/tests/test-*.py
diff --git a/library/secret-methods.c b/library/secret-methods.c
index 42a8f60..86ff008 100644
--- a/library/secret-methods.c
+++ b/library/secret-methods.c
@@ -1659,7 +1659,7 @@ secret_service_unlock_sync (SecretService *self,
* secret_service_store:
* @self: the secret service
* @schema: the schema to for attributes
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@@ -1677,6 +1677,10 @@ secret_service_unlock_sync (SecretService *self,
* 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
@@ -1695,7 +1699,6 @@ secret_service_store (SecretService *self,
g_return_if_fail (SECRET_IS_SERVICE (self));
g_return_if_fail (schema != NULL);
- g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (value != NULL);
@@ -1704,7 +1707,7 @@ secret_service_store (SecretService *self,
va_end (va);
secret_service_storev (self, schema, attributes, collection_path,
- label, value, cancellable, callback, user_data);
+ label, value, cancellable, callback, user_data);
g_hash_table_unref (attributes);
}
@@ -1714,7 +1717,7 @@ secret_service_store (SecretService *self,
* @self: the secret service
* @schema: the schema to for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@@ -1728,6 +1731,10 @@ secret_service_store (SecretService *self,
* 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
@@ -1747,7 +1754,6 @@ secret_service_storev (SecretService *self,
g_return_if_fail (SECRET_IS_SERVICE (self));
g_return_if_fail (schema != NULL);
g_return_if_fail (attributes != NULL);
- g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (value != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@@ -1775,7 +1781,7 @@ secret_service_storev (SecretService *self,
g_variant_ref_sink (propval));
secret_service_create_item_path (self, collection_path, properties, value,
- TRUE, cancellable, callback, user_data);
+ TRUE, cancellable, callback, user_data);
g_hash_table_unref (properties);
}
@@ -1810,7 +1816,7 @@ secret_service_store_finish (SecretService *self,
* secret_service_store_sync:
* @self: the secret service
* @schema: the schema to for attributes
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@@ -1827,6 +1833,10 @@ secret_service_store_finish (SecretService *self,
* 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.
*
@@ -1848,7 +1858,6 @@ secret_service_store_sync (SecretService *self,
g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
g_return_val_if_fail (schema != NULL, FALSE);
- g_return_val_if_fail (collection_path != 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);
@@ -1859,7 +1868,7 @@ secret_service_store_sync (SecretService *self,
va_end (va);
ret = secret_service_storev_sync (self, schema, attributes, collection_path,
- label, value, cancellable, error);
+ label, value, cancellable, error);
g_hash_table_unref (attributes);
@@ -1871,7 +1880,7 @@ secret_service_store_sync (SecretService *self,
* @self: the secret service
* @schema: the schema to for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @value: the secret value
* @cancellable: optional cancellation object
@@ -1884,6 +1893,10 @@ secret_service_store_sync (SecretService *self,
* 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.
*
@@ -1905,7 +1918,6 @@ secret_service_storev_sync (SecretService *self,
g_return_val_if_fail (SECRET_IS_SERVICE (self), FALSE);
g_return_val_if_fail (schema != NULL, FALSE);
g_return_val_if_fail (attributes != NULL, FALSE);
- g_return_val_if_fail (collection_path != 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);
@@ -1919,7 +1931,7 @@ secret_service_storev_sync (SecretService *self,
g_main_context_push_thread_default (sync->context);
secret_service_storev (self, schema, attributes, collection_path,
- label, value, cancellable, _secret_sync_on_result, sync);
+ label, value, cancellable, _secret_sync_on_result, sync);
g_main_loop_run (sync->loop);
@@ -3137,7 +3149,7 @@ on_create_item_session (GObject *source,
/**
* secret_service_create_item_path:
* @self: a secret service object
- * @collection_path: dbus path to collection in which to create item
+ * @collection_path: (allow-none): dbus path to collection in which to create item
* @properties: hash table of properties for the new collection
* @value: the secret value to store in the item
* @replace: whether to replace an item with the matching attributes
@@ -3159,6 +3171,10 @@ on_create_item_session (GObject *source,
* <literal>org.freedesktop.Secret.Item.Label</literal>. The values
* in the hash table should be #GVariant values of the properties.
*
+ * 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 will return immediately and complete asynchronously. The secret
* service may prompt the user. secret_service_prompt() will be used to handle
* any prompts that are required.
@@ -3181,6 +3197,9 @@ secret_service_create_item_path (SecretService *self,
g_return_if_fail (value != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ if (collection_path == NULL)
+ collection_path = SECRET_COLLECTION_DEFAULT;
+
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
secret_service_create_item_path);
closure = g_slice_new0 (ItemClosure);
@@ -3238,7 +3257,7 @@ secret_service_create_item_path_finish (SecretService *self,
/**
* secret_service_create_item_path_sync:
* @self: a secret service object
- * @collection_path: dbus path to collection in which to create item
+ * @collection_path: (allow-none): dbus path to collection in which to create item
* @properties: hash table of properties for the new collection
* @value: the secret value to store in the item
* @replace: whether to replace an item with the matching attributes
diff --git a/library/secret-password.c b/library/secret-password.c
index e40a29d..2f5a4cd 100644
--- a/library/secret-password.c
+++ b/library/secret-password.c
@@ -110,7 +110,7 @@ on_store_connected (GObject *source,
/**
* secret_password_store:
* @schema: the schema for attributes
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@@ -128,6 +128,10 @@ on_store_connected (GObject *source,
* 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 will return immediately and complete asynchronously.
*/
void
@@ -144,7 +148,6 @@ secret_password_store (const SecretSchema *schema,
va_list va;
g_return_if_fail (schema != NULL);
- g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (password != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
@@ -163,7 +166,7 @@ secret_password_store (const SecretSchema *schema,
* secret_password_storev:
* @schema: the schema for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@@ -177,6 +180,10 @@ secret_password_store (const SecretSchema *schema,
* 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 will return immediately and complete asynchronously.
*
* Rename to: secret_password_store
@@ -195,7 +202,6 @@ secret_password_storev (const SecretSchema *schema,
StoreClosure *closure;
g_return_if_fail (schema != NULL);
- g_return_if_fail (collection_path != NULL);
g_return_if_fail (label != NULL);
g_return_if_fail (password != NULL);
g_return_if_fail (attributes != NULL);
@@ -254,7 +260,7 @@ secret_password_store_finish (GAsyncResult *result,
/**
* secret_password_store_sync:
* @schema: the schema for attributes
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@@ -271,6 +277,10 @@ secret_password_store_finish (GAsyncResult *result,
* 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.
*
@@ -310,7 +320,7 @@ secret_password_store_sync (const SecretSchema *schema,
* secret_password_storev_sync:
* @schema: the schema for attributes
* @attributes: (element-type utf8 utf8): the attribute keys and values
- * @collection_path: the dbus path to the collection where to store the secret
+ * @collection_path: (allow-none): the dbus path to the collection where to store the secret
* @label: label for the secret
* @password: the null-terminated password to store
* @cancellable: optional cancellation object
@@ -323,6 +333,10 @@ secret_password_store_sync (const SecretSchema *schema,
* 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.
*
@@ -343,7 +357,6 @@ secret_password_storev_sync (const SecretSchema *schema,
gboolean ret;
g_return_val_if_fail (schema != NULL, FALSE);
- g_return_val_if_fail (collection_path != NULL, FALSE);
g_return_val_if_fail (label != NULL, FALSE);
g_return_val_if_fail (password != NULL, FALSE);
g_return_val_if_fail (attributes != NULL, FALSE);
diff --git a/library/secret-types.h b/library/secret-types.h
index 96d8637..c7f61fa 100644
--- a/library/secret-types.h
+++ b/library/secret-types.h
@@ -35,6 +35,10 @@ typedef struct _SecretPrompt SecretPrompt;
typedef struct _SecretService SecretService;
typedef struct _SecretValue SecretValue;
+#define SECRET_COLLECTION_DEFAULT "/org/freedesktop/secrets/aliases/default"
+
+#define SECRET_COLLECTION_SESSION "/org/freedesktop/secrets/aliases/session"
+
G_END_DECLS
#endif /* __G_SERVICE_H___ */
diff --git a/library/tests/Makefile.am b/library/tests/Makefile.am
index db8c0e3..9490f65 100644
--- a/library/tests/Makefile.am
+++ b/library/tests/Makefile.am
@@ -56,12 +56,22 @@ EXTRA_DIST = \
mock-service-prompt.py \
$(NULL)
-test: $(TEST_PROGS)
- gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(TEST_PROGS)
+JS_TESTS = \
+ test-lookup-password.js \
+ test-remove-password.js \
+ test-store-password.js
-test-javascript:
- LD_LIBRARY_PATH=$(builddir)/.libs GI_TYPELIB_PATH=$(builddir)/..:$(builddir) \
- gjs test-lookup-password.js
+JS_ENV = \
+ LD_LIBRARY_PATH=$(builddir)/.libs \
+ GI_TYPELIB_PATH=$(builddir)/..:$(builddir)
+
+test: test-c test-js
+
+test-c: $(TEST_PROGS)
+ @gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(TEST_PROGS)
+
+test-js:
+ @for js in $(JS_TESTS); do echo "TEST: $$js"; $(JS_ENV) gjs $$js; done
# ------------------------------------------------------------------
# INTROSPECTION
diff --git a/library/tests/test-javascript.js b/library/tests/test-javascript.js
new file mode 100644
index 0000000..95b3c3f
--- /dev/null
+++ b/library/tests/test-javascript.js
@@ -0,0 +1,14 @@
+
+const Mock = imports.gi.MockService;
+const Secret = imports.gi.Secret;
+
+Mock.start("mock-service-normal.py");
+
+var schema = new Secret.Schema.new("org.test",
+ Secret.SchemaFlags.NONE,
+ { "blah": Secret.SchemaAttributeType.STRING });
+log(schema.identifier);
+log(schema.flags);
+/* log(schema.attributes); */
+
+Mock.stop(); \ No newline at end of file
diff --git a/library/tests/test-lookup-password.js b/library/tests/test-lookup-password.js
new file mode 100644
index 0000000..32de442
--- /dev/null
+++ b/library/tests/test-lookup-password.js
@@ -0,0 +1,52 @@
+
+const Mock = imports.gi.MockService;
+const Secret = imports.gi.Secret;
+const GLib = imports.gi.GLib;
+
+const JsUnit = imports.jsUnit;
+const assertEquals = JsUnit.assertEquals;
+const assertRaises = JsUnit.assertRaises;
+const assertTrue = JsUnit.assertTrue;
+
+Mock.start("mock-service-normal.py");
+
+const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store",
+ Secret.SchemaFlags.NONE,
+ {
+ "number": Secret.SchemaAttributeType.INTEGER,
+ "string": Secret.SchemaAttributeType.STRING,
+ "even": Secret.SchemaAttributeType.BOOLEAN,
+ }
+);
+
+/* Synchronous */
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, { "number": "1", "even": "false" }, null);
+assertEquals("111", password);
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, { "number": "5", "even": "true" }, null);
+assertEquals(null, password);
+
+/* Asynchronous */
+
+var loop = new GLib.MainLoop.new(null, false);
+
+Secret.password_lookup (STORE_SCHEMA, { "number": "2", "string": "two" },
+ null, function(source, result) {
+ loop.quit();
+ var password = Secret.password_lookup_finish(result);
+ assertEquals("222", password);
+});
+
+loop.run();
+
+Secret.password_lookup (STORE_SCHEMA, { "number": "7", "string": "five" },
+ null, function(source, result) {
+ loop.quit();
+ var password = Secret.password_lookup_finish(result);
+ assertEquals(null, password);
+});
+
+loop.run();
+
+Mock.stop();
diff --git a/library/tests/test-remove-password.js b/library/tests/test-remove-password.js
new file mode 100644
index 0000000..8425cef
--- /dev/null
+++ b/library/tests/test-remove-password.js
@@ -0,0 +1,68 @@
+
+const Mock = imports.gi.MockService;
+const Secret = imports.gi.Secret;
+const GLib = imports.gi.GLib;
+
+const JsUnit = imports.jsUnit;
+const assertEquals = JsUnit.assertEquals;
+const assertRaises = JsUnit.assertRaises;
+const assertTrue = JsUnit.assertTrue;
+
+Mock.start("mock-service-normal.py");
+
+const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store",
+ Secret.SchemaFlags.NONE,
+ {
+ "number": Secret.SchemaAttributeType.INTEGER,
+ "string": Secret.SchemaAttributeType.STRING,
+ "even": Secret.SchemaAttributeType.BOOLEAN,
+ }
+);
+
+/* Synchronous */
+
+var attributes = { "number": "1", "string": "one", "even": "false" };
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals("111", password);
+
+var deleted = Secret.password_remove_sync (STORE_SCHEMA, attributes, null);
+assertEquals(true, deleted);
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals(null, password);
+
+var deleted = Secret.password_remove_sync (STORE_SCHEMA, attributes, null);
+assertEquals(false, deleted);
+
+/* Asynchronous */
+
+var attributes = { "number": "2", "string": "two", "even": "true" };
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals("222", password);
+
+var loop = new GLib.MainLoop.new(null, false);
+
+Secret.password_remove (STORE_SCHEMA, attributes,
+ null, function(source, result) {
+ loop.quit();
+ var deleted = Secret.password_remove_finish(result);
+ assertEquals(true, deleted);
+});
+
+loop.run();
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals(null, password);
+
+Secret.password_remove (STORE_SCHEMA, attributes,
+ null, function(source, result) {
+ loop.quit();
+ var deleted = Secret.password_remove_finish(result);
+ assertEquals(false, deleted);
+});
+
+loop.run();
+
+Mock.stop();
diff --git a/library/tests/test-store-password.js b/library/tests/test-store-password.js
new file mode 100644
index 0000000..254c162
--- /dev/null
+++ b/library/tests/test-store-password.js
@@ -0,0 +1,58 @@
+
+const Mock = imports.gi.MockService;
+const Secret = imports.gi.Secret;
+const GLib = imports.gi.GLib;
+
+const JsUnit = imports.jsUnit;
+const assertEquals = JsUnit.assertEquals;
+const assertRaises = JsUnit.assertRaises;
+const assertTrue = JsUnit.assertTrue;
+
+Mock.start("mock-service-normal.py");
+
+const STORE_SCHEMA = new Secret.Schema.new("org.mock.type.Store",
+ Secret.SchemaFlags.NONE,
+ {
+ "number": Secret.SchemaAttributeType.INTEGER,
+ "string": Secret.SchemaAttributeType.STRING,
+ "even": Secret.SchemaAttributeType.BOOLEAN,
+ }
+);
+
+/* Synchronous */
+
+var attributes = { "number": "9", "string": "nine", "even": "false" };
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals(null, password);
+
+var stored = Secret.password_store_sync (STORE_SCHEMA, attributes, Secret.COLLECTION_DEFAULT,
+ "The number nine", "999", null);
+assertEquals(true, stored);
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals("999", password);
+
+
+/* Asynchronous */
+
+var attributes = { "number": "888", "string": "eight", "even": "true" };
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals(null, password);
+
+var loop = new GLib.MainLoop.new(null, false);
+
+Secret.password_store (STORE_SCHEMA, attributes, null, "The number eight", "888",
+ null, function(source, result) {
+ loop.quit();
+ var stored = Secret.password_store_finish(result);
+ assertEquals(true, stored);
+});
+
+loop.run();
+
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals("888", password);
+
+Mock.stop();