[gcr] gck: Allow enumerating objects on a session



commit 83c859210e66ffa5e0d7814cb822066c23c1e7bb
Author: Stef Walter <stefw collabora co uk>
Date:   Wed Nov 2 14:07:41 2011 +0100

    gck: Allow enumerating objects on a session
    
     * Add gck_session_enumerate_objects()
     * This has several advantages such as retrieving attributes during
       the enumeration, etc.

 docs/reference/gck/gck-sections.txt |    1 +
 gck/gck-enumerator.c                |  100 ++++++++++++++++++++++++++--------
 gck/gck-modules.c                   |    4 +-
 gck/gck-private.h                   |    9 +++-
 gck/gck-session.c                   |   27 +++++++++-
 gck/gck-slot.c                      |    2 +-
 gck/gck.h                           |    3 +
 gck/gck.symbols                     |    1 +
 gck/tests/test-gck-enumerator.c     |   57 ++++++++++++++++----
 9 files changed, 163 insertions(+), 41 deletions(-)
---
diff --git a/docs/reference/gck/gck-sections.txt b/docs/reference/gck/gck-sections.txt
index eacf4ba..5a36a28 100644
--- a/docs/reference/gck/gck-sections.txt
+++ b/docs/reference/gck/gck-sections.txt
@@ -190,6 +190,7 @@ gck_session_logout_finish
 gck_session_create_object
 gck_session_create_object_async
 gck_session_create_object_finish
+gck_session_enumerate_objects
 gck_session_find_handles
 gck_session_find_handles_async
 gck_session_find_handles_finish
diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c
index 1ac52dc..060b355 100644
--- a/gck/gck-enumerator.c
+++ b/gck/gck-enumerator.c
@@ -677,14 +677,24 @@ gck_enumerator_class_init (GckEnumeratorClass *klass)
 		                    GCK_TYPE_OBJECT, G_PARAM_READWRITE));
 }
 
-/* ----------------------------------------------------------------------------
- * PUBLIC
- */
+static void
+created_enumerator (GckUriData *uri_data,
+                    const gchar *type)
+{
+	if (_gck_debugging) {
+		gchar *attrs, *uri;
+		attrs = uri_data->attributes ? _gck_attributes_format (uri_data->attributes) : NULL;
+		uri = uri_data ? gck_uri_build (uri_data, GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE) : NULL;
+		_gck_debug ("for = %s, tokens = %s, objects = %s", type, uri, attrs);
+		g_free (attrs);
+		g_free (uri);
+	}
+}
 
-GckEnumerator*
-_gck_enumerator_new (GList *modules_or_slots,
-                     GckSessionOptions session_options,
-                     GckUriData *uri_data)
+GckEnumerator *
+_gck_enumerator_new_for_modules (GList *modules,
+                                 GckSessionOptions session_options,
+                                 GckUriData *uri_data)
 {
 	GckEnumerator *self;
 	GckEnumeratorState *state;
@@ -694,29 +704,71 @@ _gck_enumerator_new (GList *modules_or_slots,
 
 	state->session_options = session_options;
 
-	if (modules_or_slots && GCK_IS_SLOT (modules_or_slots->data)) {
-		state->slots = gck_list_ref_copy (modules_or_slots);
-		state->modules = NULL;
-		state->handler = state_slots;
-	} else {
-		state->modules = gck_list_ref_copy (modules_or_slots);
-		state->slots = NULL;
-		state->handler = state_modules;
-	}
+	state->modules = gck_list_ref_copy (modules);
+	state->slots = NULL;
+	state->handler = state_modules;
+	state->match = uri_data;
 
+	if (uri_data->attributes)
+		_gck_attributes_lock (uri_data->attributes);
+
+	created_enumerator (uri_data, "modules");
+	return self;
+}
+
+GckEnumerator *
+_gck_enumerator_new_for_slots (GList *slots,
+                               GckSessionOptions session_options,
+                               GckUriData *uri_data)
+{
+	GckEnumerator *self;
+	GckEnumeratorState *state;
+
+	self = g_object_new (GCK_TYPE_ENUMERATOR, NULL);
+	state = self->pv->the_state;
+
+	state->session_options = session_options;
+
+	state->slots = gck_list_ref_copy (slots);
+	state->modules = NULL;
+	state->handler = state_slots;
 	state->match = uri_data;
+
 	if (uri_data->attributes)
 		_gck_attributes_lock (uri_data->attributes);
 
-	if (_gck_debugging) {
-		gchar *attrs, *uri;
-		attrs = uri_data->attributes ? _gck_attributes_format (uri_data->attributes) : NULL;
-		uri = uri_data ? gck_uri_build (uri_data, GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE) : NULL;
-		_gck_debug ("new enumerator: tokens = %s, objects = %s", uri, attrs);
-		g_free (attrs);
-		g_free (uri);
-	}
+	created_enumerator (uri_data, "slots");
+	return self;
+}
+
+GckEnumerator *
+_gck_enumerator_new_for_session (GckSession *session,
+                                 GckUriData *uri_data)
+{
+	GckEnumerator *self;
+	GckEnumeratorState *state;
+	GckModule *module;
+
+	self = g_object_new (GCK_TYPE_ENUMERATOR, NULL);
+	state = self->pv->the_state;
+
+	state->session = g_object_ref (session);
+	state->modules = NULL;
+	state->slots = NULL;
+	state->handler = state_session;
+	state->match = uri_data;
+
+	state->slot = gck_session_get_slot (session);
+	state->token_info = gck_slot_get_token_info (state->slot);
+
+	module = gck_session_get_module (session);
+	state->funcs = gck_module_get_functions (module);
+	g_object_unref (module);
+
+	if (uri_data->attributes)
+		_gck_attributes_lock (uri_data->attributes);
 
+	created_enumerator (uri_data, "session");
 	return self;
 }
 
diff --git a/gck/gck-modules.c b/gck/gck-modules.c
index 0ebd0a6..37518ac 100644
--- a/gck/gck-modules.c
+++ b/gck/gck-modules.c
@@ -218,7 +218,7 @@ gck_modules_enumerate_objects (GList *modules,
 	uri_data = gck_uri_data_new ();
 	uri_data->attributes = gck_attributes_ref (attrs);
 
-	return _gck_enumerator_new (modules, session_options, uri_data);
+	return _gck_enumerator_new_for_modules (modules, session_options, uri_data);
 }
 
 static GList *
@@ -429,5 +429,5 @@ gck_modules_enumerate_uri (GList *modules,
 		return NULL;
 
 	/* Takes ownership of uri_info */
-	return _gck_enumerator_new (modules, session_options, uri_data);
+	return _gck_enumerator_new_for_modules (modules, session_options, uri_data);
 }
diff --git a/gck/gck-private.h b/gck/gck-private.h
index 4caf079..5e265fe 100644
--- a/gck/gck-private.h
+++ b/gck/gck-private.h
@@ -86,10 +86,17 @@ gboolean            _gck_module_info_match                  (GckModuleInfo *matc
  * ENUMERATOR
  */
 
-GckEnumerator*      _gck_enumerator_new                     (GList *modules,
+GckEnumerator *     _gck_enumerator_new_for_modules         (GList *modules,
                                                              GckSessionOptions session_options,
                                                              GckUriData *uri_data);
 
+GckEnumerator *     _gck_enumerator_new_for_slots           (GList *slots,
+                                                             GckSessionOptions session_options,
+                                                             GckUriData *uri_data);
+
+GckEnumerator *     _gck_enumerator_new_for_session         (GckSession *session,
+                                                             GckUriData *uri_data);
+
 /* ----------------------------------------------------------------------------
  * SLOT
  */
diff --git a/gck/gck-session.c b/gck/gck-session.c
index 4438021..a08be84 100644
--- a/gck/gck-session.c
+++ b/gck/gck-session.c
@@ -339,7 +339,7 @@ gck_session_class_init (GckSessionClass *klass)
 	/**
 	 * GckSession:app-data:
 	 *
-	 * Raw PKCS\#11 application data used to open the PKCS#11 session.
+	 * Raw PKCS\#11 application data used to open the PKCS\#11 session.
 	 */
 	g_object_class_install_property (gobject_class, PROP_APP_DATA,
 	           g_param_spec_pointer ("app-data", "App data", "PKCS#11 application data",
@@ -1764,6 +1764,31 @@ gck_session_find_objects_finish (GckSession *self,
 
 }
 
+/**
+ * gck_session_enumerate_objects:
+ * @self: session to enumerate objects on
+ * @match: attributes that the objects must match, or empty for all objects
+ *
+ * Setup an enumerator for listing matching objects available via this session.
+ *
+ * This call will not block but will return an enumerator immediately.
+ *
+ * Returns: (transfer full): a new enumerator
+ **/
+GckEnumerator *
+gck_session_enumerate_objects (GckSession *session,
+                               GckAttributes *match)
+{
+	GckUriData *uri_data;
+
+	g_return_val_if_fail (match != NULL, NULL);
+
+	uri_data = gck_uri_data_new ();
+	uri_data->attributes = gck_attributes_ref (match);
+
+	return _gck_enumerator_new_for_session (session, uri_data);
+}
+
 /* -----------------------------------------------------------------------------
  * KEY PAIR GENERATION
  */
diff --git a/gck/gck-slot.c b/gck/gck-slot.c
index b6cd1c8..49f0f3b 100644
--- a/gck/gck-slot.c
+++ b/gck/gck-slot.c
@@ -934,7 +934,7 @@ gck_slots_enumerate_objects (GList *slots,
 	uri_data = gck_uri_data_new ();
 	uri_data->attributes = gck_attributes_ref (match);
 
-	return _gck_enumerator_new (slots, options, uri_data);
+	return _gck_enumerator_new_for_slots (slots, options, uri_data);
 }
 
 
diff --git a/gck/gck.h b/gck/gck.h
index 79202fe..7acfaa9 100644
--- a/gck/gck.h
+++ b/gck/gck.h
@@ -875,6 +875,9 @@ gulong *            gck_session_find_handles_finish         (GckSession *self,
                                                              gulong *n_handles,
                                                              GError **error);
 
+GckEnumerator *     gck_session_enumerate_objects           (GckSession *self,
+                                                             GckAttributes *match);
+
 gboolean            gck_session_generate_key_pair           (GckSession *self,
                                                              gulong mech_type,
                                                              GckAttributes *public_attrs,
diff --git a/gck/gck.symbols b/gck/gck.symbols
index 237b88f..5070913 100644
--- a/gck/gck.symbols
+++ b/gck/gck.symbols
@@ -152,6 +152,7 @@ gck_session_encrypt
 gck_session_encrypt_async
 gck_session_encrypt_finish
 gck_session_encrypt_full
+gck_session_enumerate_objects
 gck_session_find_handles
 gck_session_find_handles_async
 gck_session_find_handles_finish
diff --git a/gck/tests/test-gck-enumerator.c b/gck/tests/test-gck-enumerator.c
index a70bfa4..d46d437 100644
--- a/gck/tests/test-gck-enumerator.c
+++ b/gck/tests/test-gck-enumerator.c
@@ -75,7 +75,7 @@ test_create (Test *test, gconstpointer unused)
 	GckEnumerator *en;
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	g_object_get (en, "object-type", &object_type, NULL);
@@ -93,7 +93,7 @@ test_create_slots (Test *test, gconstpointer unused)
 
 	uri_data = gck_uri_data_new ();
 	slots = gck_module_get_slots (test->module, FALSE);
-	en = _gck_enumerator_new (slots, 0, uri_data);
+	en = _gck_enumerator_new_for_slots (slots, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 	g_object_unref (en);
 	gck_list_unref_free (slots);
@@ -108,7 +108,7 @@ test_next (Test *test, gconstpointer unused)
 	GckObject *obj;
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	obj = gck_enumerator_next (en, NULL, &error);
@@ -129,7 +129,7 @@ test_next_slots (Test *test, gconstpointer unused)
 
 	uri_data = gck_uri_data_new ();
 	slots = gck_module_get_slots (test->module, FALSE);
-	en = _gck_enumerator_new (slots, 0, uri_data);
+	en = _gck_enumerator_new_for_slots (slots, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	obj = gck_enumerator_next (en, NULL, &error);
@@ -149,7 +149,7 @@ test_next_and_resume (Test *test, gconstpointer unused)
 	GckObject *obj, *obj2;
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	obj = gck_enumerator_next (en, NULL, &error);
@@ -176,7 +176,7 @@ test_next_n (Test *test, gconstpointer unused)
 	GList *objects, *l;
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	objects = gck_enumerator_next_n (en, -1, NULL, &error);
@@ -207,7 +207,7 @@ test_next_async (Test *test, gconstpointer unused)
 	GList *objects, *l;
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	gck_enumerator_next_async (en, -1, NULL, fetch_async_result, &result);
@@ -225,6 +225,38 @@ test_next_async (Test *test, gconstpointer unused)
 	g_object_unref (en);
 }
 
+
+static void
+test_enumerate_session (Test *test,
+                        gconstpointer unused)
+{
+	GckEnumerator *en;
+	GckAttributes *attrs;
+	GError *error = NULL;
+	GckSession *session;
+	GckObject *obj;
+	GList *slots;
+
+	slots = gck_module_get_slots (test->module, FALSE);
+	g_assert (slots != NULL && GCK_IS_SLOT (slots->data));
+
+	session = gck_session_open (slots->data, 0, NULL, NULL, &error);
+	g_assert_no_error (error);
+
+	attrs = gck_attributes_new ();
+	en = gck_session_enumerate_objects (session, attrs);
+	g_assert (GCK_IS_ENUMERATOR (en));
+	gck_attributes_unref (attrs);
+
+	obj = gck_enumerator_next (en, NULL, &error);
+	g_assert (GCK_IS_OBJECT (obj));
+
+	g_object_unref (obj);
+	g_object_unref (en);
+	g_object_unref (session);
+	gck_list_unref_free (slots);
+}
+
 static void
 test_attribute_match (Test *test, gconstpointer unused)
 {
@@ -236,7 +268,7 @@ test_attribute_match (Test *test, gconstpointer unused)
 	uri_data = gck_uri_data_new ();
 	uri_data->attributes = gck_attributes_new ();
 	gck_attributes_add_string (uri_data->attributes, CKA_LABEL, "Private Capitalize Key");
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	objects = gck_enumerator_next_n (en, -1, NULL, &error);
@@ -260,7 +292,7 @@ test_authenticate_interaction (Test *test,
 	GckObject *obj;
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, GCK_SESSION_LOGIN_USER, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, GCK_SESSION_LOGIN_USER, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	interaction = mock_interaction_new ("booo");
@@ -308,7 +340,7 @@ test_authenticate_compat (Test *test,
 	                  G_CALLBACK (on_authenticate_token), GUINT_TO_POINTER (35));
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, GCK_SESSION_LOGIN_USER, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, GCK_SESSION_LOGIN_USER, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	obj = gck_enumerator_next (en, NULL, &error);
@@ -329,7 +361,7 @@ test_token_match (Test *test, gconstpointer unused)
 	uri_data = gck_uri_data_new ();
 	uri_data->token_info = g_new0 (GckTokenInfo, 1);
 	uri_data->token_info->label = g_strdup ("Invalid token name");
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
 	objects = gck_enumerator_next_n (en, -1, NULL, &error);
@@ -450,7 +482,7 @@ test_attribute_get (Test *test,
 	MockObject *mock;
 
 	uri_data = gck_uri_data_new ();
-	en = _gck_enumerator_new (test->modules, 0, uri_data);
+	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_object_set (en, "object-type", mock_object_get_type (), NULL);
 
 	objects = gck_enumerator_next_n (en, -1, NULL, &error);
@@ -482,6 +514,7 @@ main (int argc, char **argv)
 	g_test_add ("/gck/enumerator/next_and_resume", Test, NULL, setup, test_next_and_resume, teardown);
 	g_test_add ("/gck/enumerator/next_n", Test, NULL, setup, test_next_n, teardown);
 	g_test_add ("/gck/enumerator/next_async", Test, NULL, setup, test_next_async, teardown);
+	g_test_add ("/gck/enumerator/session", Test, NULL, setup, test_enumerate_session, teardown);
 	g_test_add ("/gck/enumerator/authenticate-interaction", Test, NULL, setup, test_authenticate_interaction, teardown);
 	g_test_add ("/gck/enumerator/authenticate-compat", Test, NULL, setup, test_authenticate_compat, teardown);
 	g_test_add ("/gck/enumerator/attribute_match", Test, NULL, setup, test_attribute_match, teardown);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]