More testing, and more bug fixes

This commit is contained in:
Stef Walter 2012-01-26 14:34:37 +01:00
parent c6c6afa2cc
commit 4c80765ef8
11 changed files with 1452 additions and 202 deletions

View File

@ -394,7 +394,6 @@ gsecret_collection_properties_changed (GDBusProxy *proxy,
g_variant_iter_init (&iter, changed_properties);
while (g_variant_iter_loop (&iter, "{sv}", &property_name, &value))
// TODO: zzzz;
handle_property_changed (self, property_name, value);
g_object_thaw_notify (G_OBJECT (self));
@ -678,8 +677,8 @@ gsecret_collection_delete (GSecretCollection *self,
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (self));
gsecret_service_delete_path (self->pv->service, object_path, cancellable,
callback, user_data);
_gsecret_service_delete_path (self->pv->service, object_path, FALSE,
cancellable, callback, user_data);
}
gboolean

View File

@ -476,8 +476,8 @@ gsecret_item_delete (GSecretItem *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gsecret_item_delete);
gsecret_service_delete_path (self->pv->service, object_path, cancellable,
on_item_deleted, g_object_ref (res));
_gsecret_service_delete_path (self->pv->service, object_path, TRUE,
cancellable, on_item_deleted, g_object_ref (res));
g_object_unref (res);
}

View File

@ -99,25 +99,18 @@ gboolean _gsecret_util_have_cached_properties (GDBusProxy *prox
void _gsecret_service_set_default_bus_name (const gchar *bus_name);
#if 0
GSecretService * _gsecret_service_bare_instance (GDBusConnection *connection,
const gchar *bus_name);
void _gsecret_service_bare_connect (const gchar *bus_name,
gboolean ensure_session,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSecretService * _gsecret_service_bare_connect_finish (GAsyncResult *result,
GError **error);
#endif
GSecretSession * _gsecret_service_get_session (GSecretService *self);
void _gsecret_service_take_session (GSecretService *self,
GSecretSession *session);
void _gsecret_service_delete_path (GSecretService *self,
const gchar *object_path,
gboolean is_an_item,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GSecretItem * _gsecret_service_find_item_instance (GSecretService *self,
const gchar *item_path);

View File

@ -395,6 +395,8 @@ on_init_base (GObject *source,
result, &error)) {
g_simple_async_result_take_error (res, error);
g_simple_async_result_complete (res);
} else {
}
service_ensure_for_flags_async (self, self->pv->init_flags, res);
@ -506,6 +508,7 @@ gsecret_service_get (GSecretServiceFlags flags,
service_ensure_for_flags_async (service, flags, res);
g_object_unref (service);
g_object_unref (res);
}
}
@ -530,6 +533,15 @@ gsecret_service_get_finish (GAsyncResult *result,
/* Creating a whole new service */
} else {
service = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), result, error);
if (service) {
G_LOCK (service_instance);
if (service_instance == NULL) {
service_instance = service;
g_object_weak_ref (G_OBJECT (service), on_service_instance_gone, NULL);
}
G_UNLOCK (service_instance);
}
}
if (source_object)
@ -563,15 +575,15 @@ gsecret_service_get_sync (GSecretServiceFlags flags,
"g-interface-name", GSECRET_SERVICE_INTERFACE,
"flags", flags,
NULL);
if (service == NULL)
return NULL;
if (service != NULL) {
G_LOCK (service_instance);
if (service_instance == NULL) {
service_instance = service;
g_object_weak_ref (G_OBJECT (service), on_service_instance_gone, NULL);
}
G_UNLOCK (service_instance);
}
} else {
if (!service_ensure_for_flags_sync (service, flags, cancellable, error)) {
@ -696,16 +708,18 @@ GSecretItem *
_gsecret_service_find_item_instance (GSecretService *self,
const gchar *item_path)
{
GSecretCollection *collection;
GSecretCollection *collection = NULL;
gchar *collection_path;
GSecretItem *item;
collection_path = _gsecret_util_parent_path (item_path);
g_mutex_lock (&self->pv->mutex);
if (self->pv->collections) {
collection = g_hash_table_lookup (self->pv->collections, collection_path);
if (collection != NULL)
g_object_ref (collection);
}
g_mutex_unlock (&self->pv->mutex);
g_free (collection_path);
@ -965,7 +979,7 @@ gsecret_service_ensure_collections (GSecretService *self,
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
g_return_if_fail (paths == NULL);
g_return_if_fail (paths != NULL);
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gsecret_service_ensure_collections);
@ -1030,7 +1044,7 @@ gsecret_service_ensure_collections_sync (GSecretService *self,
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
paths = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (self), "Collections");
g_return_val_if_fail (paths == NULL, FALSE);
g_return_val_if_fail (paths != NULL, FALSE);
collections = collections_table_new ();
@ -1193,7 +1207,7 @@ search_closure_free (gpointer data)
}
static void
search_closure_add_item (SearchClosure *closure,
search_closure_take_item (SearchClosure *closure,
GSecretItem *item)
{
const gchar *path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (item));
@ -1217,7 +1231,7 @@ on_search_loaded (GObject *source,
g_simple_async_result_take_error (res, error);
if (item != NULL)
search_closure_add_item (closure, item);
search_closure_take_item (closure, item);
if (closure->loading == 0)
g_simple_async_result_complete (res);
@ -1225,7 +1239,7 @@ on_search_loaded (GObject *source,
}
static void
search_load_item (GSecretService *self,
search_load_item_async (GSecretService *self,
GSimpleAsyncResult *res,
SearchClosure *closure,
const gchar *path)
@ -1234,12 +1248,11 @@ search_load_item (GSecretService *self,
item = _gsecret_service_find_item_instance (self, path);
if (item == NULL) {
// TODO: xxxxxxxxxx;
gsecret_item_new (self, path, closure->cancellable,
on_search_loaded, g_object_ref (res));
closure->loading++;
} else {
search_closure_add_item (closure, item);
search_closure_take_item (closure, item);
}
}
@ -1261,9 +1274,9 @@ on_search_paths (GObject *source,
}
for (i = 0; closure->unlocked[i] != NULL; i++)
search_load_item (self, res, closure, closure->unlocked[i]);
search_load_item_async (self, res, closure, closure->unlocked[i]);
for (i = 0; closure->locked[i] != NULL; i++)
search_load_item (self, res, closure, closure->locked[i]);
search_load_item_async (self, res, closure, closure->locked[i]);
if (closure->loading == 0)
g_simple_async_result_complete (res);
@ -1344,6 +1357,33 @@ gsecret_service_search_finish (GSecretService *self,
return TRUE;
}
static gboolean
service_load_items_sync (GSecretService *self,
GCancellable *cancellable,
gchar **paths,
GList **items,
GError **error)
{
GSecretItem *item;
GList *result = NULL;
guint i;
for (i = 0; paths[i] != NULL; i++) {
item = _gsecret_service_find_item_instance (self, paths[i]);
if (item == NULL)
item = gsecret_item_new_sync (self, paths[i], cancellable, error);
if (item == NULL) {
g_list_free_full (result, g_object_unref);
return FALSE;
} else {
result = g_list_prepend (result, item);
}
}
*items = g_list_reverse (result);
return TRUE;
}
gboolean
gsecret_service_search_sync (GSecretService *self,
GHashTable *attributes,
@ -1352,25 +1392,28 @@ gsecret_service_search_sync (GSecretService *self,
GList **locked,
GError **error)
{
GSecretSync *sync;
gchar **unlocked_paths = NULL;
gchar **locked_paths = NULL;
gboolean ret;
g_return_val_if_fail (GSECRET_IS_SERVICE (self), FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
sync = _gsecret_sync_new ();
g_main_context_push_thread_default (sync->context);
if (!gsecret_service_search_for_paths_sync (self, attributes, cancellable,
unlocked ? &unlocked_paths : NULL,
locked ? &locked_paths : NULL, error))
return FALSE;
gsecret_service_search (self, attributes, cancellable,
_gsecret_sync_on_result, sync);
ret = TRUE;
g_main_loop_run (sync->loop);
if (unlocked)
ret = service_load_items_sync (self, cancellable, unlocked_paths, unlocked, error);
if (ret && locked)
ret = service_load_items_sync (self, cancellable, locked_paths, locked, error);
ret = gsecret_service_search_finish (self, sync->result, unlocked, locked, error);
g_main_context_pop_thread_default (sync->context);
_gsecret_sync_free (sync);
g_strfreev (unlocked_paths);
g_strfreev (locked_paths);
return ret;
}
@ -1454,7 +1497,7 @@ gsecret_service_get_secret_for_path (GSecretService *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gsecret_service_get_secret_for_path);
closure = g_slice_new (GetClosure);
closure = g_slice_new0 (GetClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->in = g_variant_ref_sink (g_variant_new_objv (&object_path, 1));
g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free);
@ -1471,7 +1514,7 @@ service_decode_get_secrets_first (GSecretService *self,
GVariant *out)
{
GSecretSession *session;
GSecretValue *value;
GSecretValue *value = NULL;
GVariantIter *iter;
GVariant *variant;
const gchar *path;
@ -1579,7 +1622,7 @@ gsecret_service_get_secrets_for_paths (GSecretService *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gsecret_service_get_secret_for_path);
closure = g_slice_new (GetClosure);
closure = g_slice_new0 (GetClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->in = g_variant_ref_sink (g_variant_new_objv (object_paths, -1));
g_simple_async_result_set_op_res_gpointer (res, closure, get_closure_free);
@ -1659,7 +1702,7 @@ gsecret_service_get_secrets (GSecretService *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gsecret_service_get_secrets);
closure = g_slice_new (GetClosure);
closure = g_slice_new0 (GetClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->items = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
@ -1700,7 +1743,7 @@ gsecret_service_get_secrets_finish (GSecretService *self,
g_return_val_if_fail (GSECRET_IS_SERVICE (self), NULL);
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
gsecret_service_get_secret_for_path), NULL);
gsecret_service_get_secrets), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
res = G_SIMPLE_ASYNC_RESULT (result);
@ -1859,8 +1902,9 @@ service_xlock_paths_async (GSecretService *self,
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
service_xlock_paths_async);
closure = g_slice_new (XlockClosure);
closure = g_slice_new0 (XlockClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : cancellable;
closure->xlocked = g_ptr_array_new_with_free_func (g_free);
g_simple_async_result_set_op_res_gpointer (res, closure, xlock_closure_free);
g_dbus_proxy_call (G_DBUS_PROXY (self), method,
@ -2172,7 +2216,7 @@ gsecret_service_unlock_finish (GSecretService *self,
g_return_val_if_fail (GSECRET_IS_SERVICE (self), -1);
g_return_val_if_fail (error == NULL || *error == NULL, -1);
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
gsecret_service_unlock_paths), -1);
service_xlock_paths_async), -1);
return service_xlock_finish (self, result, unlocked, error);
}
@ -2529,6 +2573,7 @@ static void
lookup_closure_free (gpointer data)
{
LookupClosure *closure = data;
if (closure->value)
gsecret_value_unref (closure->value);
g_clear_object (&closure->cancellable);
g_slice_free (LookupClosure, closure);
@ -2827,8 +2872,9 @@ on_delete_complete (GObject *source,
}
void
gsecret_service_delete_path (GSecretService *self,
const gchar *item_path,
_gsecret_service_delete_path (GSecretService *self,
const gchar *object_path,
gboolean is_an_item,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@ -2837,18 +2883,18 @@ gsecret_service_delete_path (GSecretService *self,
DeleteClosure *closure;
g_return_if_fail (GSECRET_IS_SERVICE (self));
g_return_if_fail (item_path != NULL);
g_return_if_fail (object_path != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
res = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
gsecret_service_delete_path);
_gsecret_service_delete_path);
closure = g_slice_new0 (DeleteClosure);
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
g_simple_async_result_set_op_res_gpointer (res, closure, delete_closure_free);
g_dbus_connection_call (g_dbus_proxy_get_connection (G_DBUS_PROXY (self)),
g_dbus_proxy_get_name (G_DBUS_PROXY (self)),
item_path, GSECRET_ITEM_INTERFACE,
g_dbus_proxy_get_name (G_DBUS_PROXY (self)), object_path,
is_an_item ? GSECRET_ITEM_INTERFACE : GSECRET_COLLECTION_INTERFACE,
"Delete", g_variant_new ("()"), G_VARIANT_TYPE ("(o)"),
G_DBUS_CALL_FLAGS_NO_AUTO_START, -1,
cancellable, on_delete_complete, g_object_ref (res));
@ -2856,6 +2902,20 @@ gsecret_service_delete_path (GSecretService *self,
g_object_unref (res);
}
void
gsecret_service_delete_path (GSecretService *self,
const gchar *item_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
g_return_if_fail (GSECRET_IS_SERVICE (self));
g_return_if_fail (item_path != NULL);
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
_gsecret_service_delete_path (self, item_path, TRUE, cancellable, callback, user_data);
}
gboolean
gsecret_service_delete_path_finish (GSecretService *self,
GAsyncResult *result,
@ -2867,7 +2927,7 @@ gsecret_service_delete_path_finish (GSecretService *self,
g_return_val_if_fail (GSECRET_IS_SERVICE (self), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
gsecret_service_delete_path), FALSE);
_gsecret_service_delete_path), FALSE);
res = G_SIMPLE_ASYNC_RESULT (result);
if (g_simple_async_result_propagate_error (res, error))
@ -2879,7 +2939,7 @@ gsecret_service_delete_path_finish (GSecretService *self,
gboolean
gsecret_service_delete_path_sync (GSecretService *self,
const gchar *item_path,
const gchar *object_path,
GCancellable *cancellable,
GError **error)
{
@ -2887,14 +2947,15 @@ gsecret_service_delete_path_sync (GSecretService *self,
gboolean result;
g_return_val_if_fail (GSECRET_IS_SERVICE (self), FALSE);
g_return_val_if_fail (item_path != NULL, FALSE);
g_return_val_if_fail (object_path != NULL, FALSE);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
sync = _gsecret_sync_new ();
g_main_context_push_thread_default (sync->context);
gsecret_service_delete_path (self, item_path, cancellable, _gsecret_sync_on_result, sync);
gsecret_service_delete_path (self, object_path, cancellable,
_gsecret_sync_on_result, sync);
g_main_loop_run (sync->loop);
@ -2959,7 +3020,7 @@ on_search_delete_password (GObject *source,
/* Delete the first path */
} else {
closure->deleted = TRUE;
gsecret_service_delete_path (self, path,
_gsecret_service_delete_path (self, path, TRUE,
closure->cancellable,
on_delete_password_complete,
g_object_ref (res));

View File

@ -366,7 +366,7 @@ GSecretValue * gsecret_service_lookupv_sync (GSecretServi
GError **error);
void gsecret_service_delete_path (GSecretService *self,
const gchar *item_path,
const gchar *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@ -376,7 +376,7 @@ gboolean gsecret_service_delete_path_finish (GSecretServi
GError **error);
gboolean gsecret_service_delete_path_sync (GSecretService *self,
const gchar *item_path,
const gchar *object_path,
GCancellable *cancellable,
GError **error);

View File

@ -76,7 +76,6 @@ _gsecret_util_parent_path (const gchar *path)
g_return_val_if_fail (pos != NULL, NULL);
g_return_val_if_fail (pos != path, NULL);
pos--;
return g_strndup (path, pos - path);
}

View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
import dbus
import mock
import sys
service = mock.SecretService()
service.add_standard_objects()
collection = mock.SecretCollection(service, "lock_one", locked=False, confirm=False)
mock.SecretItem(collection, "item", attributes={ "number": "1", "string": "one", "even": "false" }, secret="uno")
mock.SecretItem(collection, "confirm", attributes={ "number": "2", "string": "two", "even": "true" }, secret="dos", confirm=True)
collection = mock.SecretCollection(service, "lock_prompt", locked=True, confirm=True)
mock.SecretItem(collection, "locked", attributes={ "number": "3", "string": "three", "even": "false" }, secret="tres")
service.listen()

View File

@ -181,6 +181,12 @@ class SecretItem(dbus.service.Object):
return False
return True
def get_locked(self):
return self.collection.locked
def perform_xlock(self, lock):
return self.collection.perform_xlock(lock)
def perform_delete(self):
del self.collection.items[self.identifier]
del objects[self.path]
@ -191,7 +197,7 @@ class SecretItem(dbus.service.Object):
session = objects.get(session_path, None)
if not session or session.sender != sender:
raise InvalidArgs("session invalid: %s" % session_path)
if self.collection.locked:
if self.get_locked():
raise IsLocked("secret is locked: %s" % self.path)
return session.encode_secret(self.secret, self.content_type)
@ -213,7 +219,7 @@ class SecretItem(dbus.service.Object):
def GetAll(self, interface_name):
if interface_name == 'org.freedesktop.Secret.Item':
return {
'Locked': self.collection.locked,
'Locked': self.get_locked(),
'Attributes': dbus.Dictionary(self.attributes, signature='ss'),
'Label': self.label,
'Created': dbus.UInt64(self.created),
@ -260,6 +266,15 @@ class SecretCollection(dbus.service.Object):
results.append(item)
return results
def get_locked(self):
return self.locked
def perform_xlock(self, lock):
self.locked = lock
for item in self.items.values():
self.PropertiesChanged('org.freedesktop.Secret.Item', { "Locked" : lock }, [])
self.PropertiesChanged('org.freedesktop.Secret.Collection', { "Locked" : lock }, [])
def perform_delete(self):
for item in self.items.values():
item.perform_delete()
@ -285,11 +300,11 @@ class SecretCollection(dbus.service.Object):
def GetAll(self, interface_name):
if interface_name == 'org.freedesktop.Secret.Collection':
return {
'Locked': self.locked,
'Locked': self.get_locked(),
'Label': self.label,
'Created': dbus.UInt64(self.created),
'Modified': dbus.UInt64(self.modified),
'Items': [dbus.ObjectPath(i.path) for i in self.items.values()]
'Items': dbus.Array([dbus.ObjectPath(i.path) for i in self.items.values()], signature='o')
}
else:
raise InvalidArgs('Unknown %s interface' % interface_name)
@ -301,7 +316,7 @@ class SecretCollection(dbus.service.Object):
if property_name == "Label":
self.label = str(new_value)
else:
raise InvalidArgs('Unknown %s interface' % property_name)
raise InvalidArgs('Not a writable property %s' % property_name)
self.PropertiesChanged(interface_name, { property_name: new_value }, [])
@dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as')
@ -336,15 +351,17 @@ class SecretService(dbus.service.Object):
'org.freedesktop.DBus')
def add_standard_objects(self):
collection = SecretCollection(self, "collection", label="Collection One", locked=False)
SecretItem(collection, "item_one", label="Item One", attributes={ "number": "1", "string": "one", "parity": "odd" }, secret="uno")
SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" }, secret="dos")
SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" }, secret="tres")
collection = SecretCollection(self, "english", label="Collection One", locked=False)
SecretItem(collection, "item_one", label="Item One", attributes={ "number": "1", "string": "one", "even": "false" }, secret="111")
SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "even": "true" }, secret="222")
SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "even": "false" }, secret="3333")
collection = SecretCollection(self, "second", locked=True)
SecretItem(collection, "item_one", attributes={ "number": "1", "string": "one", "parity": "odd" })
SecretItem(collection, "item_two", attributes={ "number": "2", "string": "two", "parity": "even" })
SecretItem(collection, "item_three", attributes={ "number": "3", "string": "three", "parity": "odd" })
collection = SecretCollection(self, "spanish", locked=True)
SecretItem(collection, "item_one", attributes={ "number": "1", "string": "uno", "even": "false" }, secret="111")
SecretItem(collection, "item_two", attributes={ "number": "2", "string": "dos", "even": "true" }, secret="222")
SecretItem(collection, "item_three", attributes={ "number": "3", "string": "tres", "even": "false" }, secret="3333")
collection = SecretCollection(self, "empty", locked=False)
def listen(self):
global ready_pipe
@ -378,6 +395,36 @@ class SecretService(dbus.service.Object):
return self.collections[parts[0]].get(parts[1], None)
return None
@dbus.service.method('org.freedesktop.Secret.Service', sender_keyword='sender')
def Lock(self, paths, lock=True, sender=None):
locked = []
prompts = []
for path in paths:
if path not in objects:
continue
object = objects[path]
if object.get_locked() == lock:
locked.append(path)
elif not object.confirm:
object.perform_xlock(lock)
locked.append(path)
else:
prompts.append(object)
def prompt_callback():
for object in prompts:
object.perform_xlock(lock)
locked = dbus.Array(locked, signature='o')
if prompts:
prompt = SecretPrompt(self, sender, dismiss=False, action=prompt_callback,
result=dbus.Array([o.path for o in prompts], signature='o'))
return (locked, dbus.ObjectPath(prompt.path))
else:
return (locked, dbus.ObjectPath("/"))
@dbus.service.method('org.freedesktop.Secret.Service', sender_keyword='sender')
def Unlock(self, paths, sender=None):
return self.Lock(paths, lock=False, sender=sender)
@dbus.service.method('org.freedesktop.Secret.Service', byte_arrays=True, sender_keyword='sender')
def OpenSession(self, algorithm, param, sender=None):
assert type(algorithm) == dbus.String
@ -394,7 +441,7 @@ class SecretService(dbus.service.Object):
items = [ ]
for collection in self.collections.values():
items = collection.search_items(attributes)
if collection.locked:
if collection.get_locked():
locked.extend(items)
else:
unlocked.extend(items)
@ -408,10 +455,29 @@ class SecretService(dbus.service.Object):
results = dbus.Dictionary(signature="o(oayays)")
for item_path in item_paths:
item = objects.get(item_path, None)
if item and not item.collection.locked:
if item and not item.get_locked():
results[item_path] = item.GetSecret(session_path, sender)
return results
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
def Get(self, interface_name, property_name):
return self.GetAll(interface_name)[property_name]
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
def GetAll(self, interface_name):
if interface_name == 'org.freedesktop.Secret.Service':
return {
'Collections': dbus.Array([dbus.ObjectPath(c.path) for c in self.collections.values()], signature='o')
}
else:
raise InvalidArgs('Unknown %s interface' % interface_name)
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ssv')
def Set(self, interface_name, property_name, new_value):
if interface_name != 'org.freedesktop.Secret.Collection':
raise InvalidArgs('Unknown %s interface' % interface_name)
raise InvalidArgs('Not a writable property %s' % property_name)
def parse_options(args):
global bus_name, ready_pipe

View File

@ -84,7 +84,7 @@ static void
test_new_sync (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/collection";
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GError *error = NULL;
GSecretCollection *collection;
@ -97,11 +97,24 @@ test_new_sync (Test *test,
egg_assert_not_object (collection);
}
static void
test_new_sync_noexist (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/nonexistant";
GError *error = NULL;
GSecretCollection *collection;
collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error);
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
g_assert (collection == NULL);
}
static void
test_new_async (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/collection";
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GError *error = NULL;
GSecretCollection *collection;
GAsyncResult *result = NULL;
@ -121,13 +134,34 @@ test_new_async (Test *test,
egg_assert_not_object (collection);
}
static void
test_new_async_noexist (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/nonexistant";
GError *error = NULL;
GSecretCollection *collection;
GAsyncResult *result = NULL;
gsecret_collection_new (test->service, collection_path, NULL, on_async_result, &result);
g_assert (result == NULL);
egg_test_wait ();
collection = gsecret_collection_new_finish (result, &error);
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
g_assert (collection == NULL);
g_object_unref (result);
}
static void
test_properties (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/collection";
GError *error = NULL;
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GSecretCollection *collection;
GSecretService *service;
GError *error = NULL;
guint64 created;
guint64 modified;
gboolean locked;
@ -149,6 +183,7 @@ test_properties (Test *test,
"created", &created,
"modified", &modified,
"label", &label,
"service", &service,
NULL);
g_assert (locked == FALSE);
@ -158,6 +193,122 @@ test_properties (Test *test,
g_assert_cmpstr (label, ==, "Collection One");
g_free (label);
g_assert (service == test->service);
g_object_unref (service);
g_object_unref (collection);
}
static void
check_items_equal (GList *items,
...)
{
GHashTable *paths;
gboolean have_item;
const gchar *path;
guint num_items;
va_list va;
GList *l;
va_start (va, items);
paths = g_hash_table_new (g_str_hash, g_str_equal);
while ((path = va_arg (va, gchar *)) != NULL)
g_hash_table_insert (paths, (gpointer)path, (gpointer)path);
va_end (va);
num_items = g_hash_table_size (paths);
g_assert_cmpuint (num_items, ==, g_list_length (items));
for (l = items; l != NULL; l = g_list_next (l)) {
path = g_dbus_proxy_get_object_path (l->data);
have_item = g_hash_table_remove (paths, path);
g_assert (have_item);
}
g_hash_table_destroy (paths);
}
static void
test_items (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GSecretCollection *collection;
GError *error = NULL;
GList *items;
collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error);
g_assert_no_error (error);
items = gsecret_collection_get_items (collection);
check_items_equal (items,
"/org/freedesktop/secrets/collection/english/item_one",
"/org/freedesktop/secrets/collection/english/item_two",
"/org/freedesktop/secrets/collection/english/item_three",
NULL);
g_list_free_full (items, g_object_unref);
g_object_get (collection, "items", &items, NULL);
check_items_equal (items,
"/org/freedesktop/secrets/collection/english/item_one",
"/org/freedesktop/secrets/collection/english/item_two",
"/org/freedesktop/secrets/collection/english/item_three",
NULL);
g_list_free_full (items, g_object_unref);
g_object_unref (collection);
}
static void
test_items_empty (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/empty";
GSecretCollection *collection;
GError *error = NULL;
GList *items;
collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error);
g_assert_no_error (error);
items = gsecret_collection_get_items (collection);
check_items_equal (items, NULL);
g_list_free_full (items, g_object_unref);
g_object_get (collection, "items", &items, NULL);
check_items_equal (items, NULL);
g_list_free_full (items, g_object_unref);
g_object_unref (collection);
}
static void
test_items_empty_async (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/empty";
GSecretCollection *collection;
GAsyncResult *result = NULL;
GError *error = NULL;
GList *items;
gsecret_collection_new (test->service, collection_path, NULL, on_async_result, &result);
g_assert (result == NULL);
egg_test_wait ();
collection = gsecret_collection_new_finish (result, &error);
g_assert_no_error (error);
g_object_unref (result);
items = gsecret_collection_get_items (collection);
check_items_equal (items, NULL);
g_list_free_full (items, g_object_unref);
g_object_get (collection, "items", &items, NULL);
check_items_equal (items, NULL);
g_list_free_full (items, g_object_unref);
g_object_unref (collection);
}
@ -165,7 +316,7 @@ static void
test_set_label_sync (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/collection";
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GError *error = NULL;
GSecretCollection *collection;
gboolean ret;
@ -193,7 +344,7 @@ static void
test_set_label_async (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/collection";
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GAsyncResult *result = NULL;
GError *error = NULL;
GSecretCollection *collection;
@ -228,7 +379,7 @@ static void
test_set_label_prop (Test *test,
gconstpointer unused)
{
const gchar *collection_path = "/org/freedesktop/secrets/collection/collection";
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GError *error = NULL;
GSecretCollection *collection;
guint sigs = 2;
@ -254,59 +405,58 @@ test_set_label_prop (Test *test,
g_object_unref (collection);
}
#if 0
static void
test_delete_sync (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GSecretCollection *collection;
GError *error = NULL;
GSecretItem *item;
gboolean ret;
item = gsecret_item_new_sync (test->service, item_path, NULL, &error);
collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error);
g_assert_no_error (error);
ret = gsecret_item_delete_sync (item, NULL, &error);
ret = gsecret_collection_delete_sync (collection, NULL, &error);
g_assert_no_error (error);
g_assert (ret == TRUE);
g_object_unref (item);
g_object_unref (collection);
item = gsecret_item_new_sync (test->service, item_path, NULL, &error);
collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error);
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
g_assert (item == NULL);
g_assert (collection == NULL);
}
static void
test_delete_async (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *collection_path = "/org/freedesktop/secrets/collection/english";
GSecretCollection *collection;
GAsyncResult *result = NULL;
GError *error = NULL;
GSecretItem *item;
gboolean ret;
item = gsecret_item_new_sync (test->service, item_path, NULL, &error);
collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error);
g_assert_no_error (error);
gsecret_item_delete (item, NULL, on_async_result, &result);
gsecret_collection_delete (collection, NULL, on_async_result, &result);
g_assert (result == NULL);
egg_test_wait ();
ret = gsecret_item_delete_finish (item, result, &error);
ret = gsecret_collection_delete_finish (collection, result, &error);
g_assert_no_error (error);
g_object_unref (result);
g_assert (ret == TRUE);
g_object_unref (item);
g_object_unref (collection);
item = gsecret_item_new_sync (test->service, item_path, NULL, &error);
collection = gsecret_collection_new_sync (test->service, collection_path, NULL, &error);
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
g_assert (item == NULL);
g_assert (collection == NULL);
}
#endif
int
main (int argc, char **argv)
@ -316,15 +466,18 @@ main (int argc, char **argv)
g_type_init ();
g_test_add ("/collection/new-sync", Test, "mock-service-normal.py", setup, test_new_sync, teardown);
g_test_add ("/collection/new-sync-noexist", Test, "mock-service-normal.py", setup, test_new_sync_noexist, teardown);
g_test_add ("/collection/new-async", Test, "mock-service-normal.py", setup, test_new_async, teardown);
g_test_add ("/collection/new-async-noexist", Test, "mock-service-normal.py", setup, test_new_async_noexist, teardown);
g_test_add ("/collection/properties", Test, "mock-service-normal.py", setup, test_properties, teardown);
g_test_add ("/collection/items", Test, "mock-service-normal.py", setup, test_items, teardown);
g_test_add ("/collection/items-empty", Test, "mock-service-normal.py", setup, test_items_empty, teardown);
g_test_add ("/collection/items-empty-async", Test, "mock-service-normal.py", setup, test_items_empty_async, teardown);
g_test_add ("/collection/set-label-sync", Test, "mock-service-normal.py", setup, test_set_label_sync, teardown);
g_test_add ("/collection/set-label-async", Test, "mock-service-normal.py", setup, test_set_label_async, teardown);
g_test_add ("/collection/set-label-prop", Test, "mock-service-normal.py", setup, test_set_label_prop, teardown);
#if 0
g_test_add ("/item/delete-sync", Test, "mock-service-normal.py", setup, test_delete_sync, teardown);
g_test_add ("/item/delete-async", Test, "mock-service-normal.py", setup, test_delete_async, teardown);
#endif
g_test_add ("/collection/delete-sync", Test, "mock-service-normal.py", setup, test_delete_sync, teardown);
g_test_add ("/collection/delete-async", Test, "mock-service-normal.py", setup, test_delete_async, teardown);
return egg_tests_run_with_loop ();
}

View File

@ -84,7 +84,7 @@ static void
test_new_sync (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GSecretItem *item;
@ -96,11 +96,24 @@ test_new_sync (Test *test,
g_object_unref (item);
}
static void
test_new_sync_noexist (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/english/nonexistant";
GError *error = NULL;
GSecretItem *item;
item = gsecret_item_new_sync (test->service, item_path, NULL, &error);
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
g_assert (item == NULL);
}
static void
test_new_async (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GAsyncResult *result = NULL;
GError *error = NULL;
GSecretItem *item;
@ -119,13 +132,34 @@ test_new_async (Test *test,
g_object_unref (item);
}
static void
test_new_async_noexist (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/english/nonexistant";
GAsyncResult *result = NULL;
GError *error = NULL;
GSecretItem *item;
gsecret_item_new (test->service, item_path, NULL, on_async_result, &result);
g_assert (result == NULL);
egg_test_wait ();
item = gsecret_item_new_finish (result, &error);
g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
g_assert (item == NULL);
g_object_unref (result);
}
static void
test_properties (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GHashTable *attributes;
GSecretService *service;
GSecretItem *item;
guint64 created;
guint64 modified;
@ -146,7 +180,7 @@ test_properties (Test *test,
attributes = gsecret_item_get_attributes (item);
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, "parity"), ==, "odd");
g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false");
g_assert_cmpuint (g_hash_table_size (attributes), ==, 3);
g_hash_table_unref (attributes);
@ -156,6 +190,7 @@ test_properties (Test *test,
"modified", &modified,
"label", &label,
"attributes", &attributes,
"service", &service,
NULL);
g_assert (locked == FALSE);
@ -167,10 +202,13 @@ 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, "parity"), ==, "odd");
g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false");
g_assert_cmpuint (g_hash_table_size (attributes), ==, 3);
g_hash_table_unref (attributes);
g_assert (service == test->service);
g_object_unref (service);
g_object_unref (item);
}
@ -178,7 +216,7 @@ static void
test_set_label_sync (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GSecretItem *item;
gboolean ret;
@ -206,7 +244,7 @@ static void
test_set_label_async (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GAsyncResult *result = NULL;
GError *error = NULL;
GSecretItem *item;
@ -241,7 +279,7 @@ static void
test_set_label_prop (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GSecretItem *item;
guint sigs = 2;
@ -271,7 +309,7 @@ static void
test_set_attributes_sync (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GSecretItem *item;
gboolean ret;
@ -283,7 +321,7 @@ test_set_attributes_sync (Test *test,
attributes = gsecret_item_get_attributes (item);
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, "parity"), ==, "odd");
g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false");
g_assert_cmpuint (g_hash_table_size (attributes), ==, 3);
g_hash_table_unref (attributes);
@ -308,7 +346,7 @@ static void
test_set_attributes_async (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GHashTable *attributes;
GError *error = NULL;
GAsyncResult *result = NULL;
@ -321,7 +359,7 @@ test_set_attributes_async (Test *test,
attributes = gsecret_item_get_attributes (item);
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, "parity"), ==, "odd");
g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false");
g_assert_cmpuint (g_hash_table_size (attributes), ==, 3);
g_hash_table_unref (attributes);
@ -351,7 +389,7 @@ static void
test_set_attributes_prop (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GSecretItem *item;
GHashTable *attributes;
@ -363,7 +401,7 @@ test_set_attributes_prop (Test *test,
attributes = gsecret_item_get_attributes (item);
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, "parity"), ==, "odd");
g_assert_cmpstr (g_hash_table_lookup (attributes, "even"), ==, "false");
g_assert_cmpuint (g_hash_table_size (attributes), ==, 3);
g_hash_table_unref (attributes);
@ -391,7 +429,7 @@ static void
test_get_secret_sync (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GSecretItem *item;
GSecretValue *value;
@ -406,7 +444,7 @@ test_get_secret_sync (Test *test,
g_assert (value != NULL);
data = gsecret_value_get (value, &length);
egg_assert_cmpmem (data, length, ==, "uno", 3);
egg_assert_cmpmem (data, length, ==, "111", 3);
gsecret_value_unref (value);
@ -417,7 +455,7 @@ static void
test_get_secret_async (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GAsyncResult *result = NULL;
GError *error = NULL;
GSecretItem *item;
@ -439,7 +477,7 @@ test_get_secret_async (Test *test,
g_object_unref (result);
data = gsecret_value_get (value, &length);
egg_assert_cmpmem (data, length, ==, "uno", 3);
egg_assert_cmpmem (data, length, ==, "111", 3);
gsecret_value_unref (value);
@ -450,7 +488,7 @@ static void
test_delete_sync (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GError *error = NULL;
GSecretItem *item;
gboolean ret;
@ -473,7 +511,7 @@ static void
test_delete_async (Test *test,
gconstpointer unused)
{
const gchar *item_path = "/org/freedesktop/secrets/collection/collection/item_one";
const gchar *item_path = "/org/freedesktop/secrets/collection/english/item_one";
GAsyncResult *result = NULL;
GError *error = NULL;
GSecretItem *item;
@ -506,7 +544,9 @@ main (int argc, char **argv)
g_type_init ();
g_test_add ("/item/new-sync", Test, "mock-service-normal.py", setup, test_new_sync, teardown);
g_test_add ("/item/new-sync-noexist", Test, "mock-service-normal.py", setup, test_new_sync_noexist, teardown);
g_test_add ("/item/new-async", Test, "mock-service-normal.py", setup, test_new_async, teardown);
g_test_add ("/item/new-async-noexist", Test, "mock-service-normal.py", setup, test_new_async_noexist, teardown);
g_test_add ("/item/properties", Test, "mock-service-normal.py", setup, test_properties, teardown);
g_test_add ("/item/set-label-sync", Test, "mock-service-normal.py", setup, test_set_label_sync, teardown);
g_test_add ("/item/set-label-async", Test, "mock-service-normal.py", setup, test_set_label_async, teardown);

File diff suppressed because it is too large Load Diff