[libsoup] SoupAuthManager: implement subfeatures for adding/removing auth types



commit f4fed344602d061fed46c64a037feb1403982f28
Author: Dan Winship <danw gnome org>
Date:   Mon Jun 7 16:46:20 2010 -0400

    SoupAuthManager: implement subfeatures for adding/removing auth types
    
    Allow using soup_session_add/remove_feature_by_type() to add/remove auth
    types from the session, and add a test for that

 libsoup/soup-auth-basic.h   |    3 --
 libsoup/soup-auth-digest.h  |    3 --
 libsoup/soup-auth-manager.c |   47 ++++++++++++++++++++++++++++++++++--------
 libsoup/soup-auth-manager.h |    5 ----
 libsoup/soup-auth.h         |    7 ++++++
 tests/auth-test.c           |   45 ++++++++++++++++++++++++++++++-----------
 6 files changed, 78 insertions(+), 32 deletions(-)
---
diff --git a/libsoup/soup-auth-basic.h b/libsoup/soup-auth-basic.h
index f6b7e2d..639bf03 100644
--- a/libsoup/soup-auth-basic.h
+++ b/libsoup/soup-auth-basic.h
@@ -8,7 +8,6 @@
 
 #include "soup-auth.h"
 
-#define SOUP_TYPE_AUTH_BASIC            (soup_auth_basic_get_type ())
 #define SOUP_AUTH_BASIC(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_AUTH_BASIC, SoupAuthBasic))
 #define SOUP_AUTH_BASIC_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_AUTH_BASIC, SoupAuthBasicClass))
 #define SOUP_IS_AUTH_BASIC(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_AUTH_BASIC))
@@ -25,6 +24,4 @@ typedef struct {
 
 } SoupAuthBasicClass;
 
-GType soup_auth_basic_get_type (void);
-
 #endif /*SOUP_AUTH_BASIC_H*/
diff --git a/libsoup/soup-auth-digest.h b/libsoup/soup-auth-digest.h
index 453c40c..0165f74 100644
--- a/libsoup/soup-auth-digest.h
+++ b/libsoup/soup-auth-digest.h
@@ -8,7 +8,6 @@
 
 #include "soup-auth.h"
 
-#define SOUP_TYPE_AUTH_DIGEST            (soup_auth_digest_get_type ())
 #define SOUP_AUTH_DIGEST(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_AUTH_DIGEST, SoupAuthDigest))
 #define SOUP_AUTH_DIGEST_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_AUTH_DIGEST, SoupAuthDigestClass))
 #define SOUP_IS_AUTH_DIGEST(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_AUTH_DIGEST))
@@ -25,8 +24,6 @@ typedef struct {
 
 } SoupAuthDigestClass;
 
-GType soup_auth_digest_get_type (void);
-
 /* Utility routines (also used by SoupAuthDomainDigest) */
 
 typedef enum {
diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
index bb5ebb1..cc0f3c9 100644
--- a/libsoup/soup-auth-manager.c
+++ b/libsoup/soup-auth-manager.c
@@ -33,6 +33,9 @@ static void request_started  (SoupSessionFeature *feature, SoupSession *session,
 			      SoupMessage *msg, SoupSocket *socket);
 static void request_unqueued  (SoupSessionFeature *feature,
 			       SoupSession *session, SoupMessage *msg);
+static gboolean add_feature (SoupSessionFeature *feature, GType type);
+static gboolean remove_feature (SoupSessionFeature *feature, GType type);
+static gboolean has_feature (SoupSessionFeature *feature, GType type);
 
 enum {
 	AUTHENTICATE,
@@ -139,6 +142,9 @@ soup_auth_manager_session_feature_init (SoupSessionFeatureInterface *feature_int
 	feature_interface->request_queued = request_queued;
 	feature_interface->request_started = request_started;
 	feature_interface->request_unqueued = request_unqueued;
+	feature_interface->add_feature = add_feature;
+	feature_interface->remove_feature = remove_feature;
+	feature_interface->has_feature = has_feature;
 }
 
 static int
@@ -150,36 +156,59 @@ auth_type_compare_func (gconstpointer a, gconstpointer b)
 	return (*auth1)->strength - (*auth2)->strength;
 }
 
-void
-soup_auth_manager_add_type (SoupAuthManager *manager, GType type)
+static gboolean
+add_feature (SoupSessionFeature *feature, GType type)
 {
-	SoupAuthManagerPrivate *priv = SOUP_AUTH_MANAGER_GET_PRIVATE (manager);
+	SoupAuthManagerPrivate *priv = SOUP_AUTH_MANAGER_GET_PRIVATE (feature);
 	SoupAuthClass *auth_class;
 
-	g_return_if_fail (g_type_is_a (type, SOUP_TYPE_AUTH));
+	if (!g_type_is_a (type, SOUP_TYPE_AUTH))
+		return FALSE;
 
 	auth_class = g_type_class_ref (type);
 	g_ptr_array_add (priv->auth_types, auth_class);
 	g_ptr_array_sort (priv->auth_types, auth_type_compare_func);
+	return TRUE;
 }
 
-void
-soup_auth_manager_remove_type (SoupAuthManager *manager, GType type)
+static gboolean
+remove_feature (SoupSessionFeature *feature, GType type)
 {
-	SoupAuthManagerPrivate *priv = SOUP_AUTH_MANAGER_GET_PRIVATE (manager);
+	SoupAuthManagerPrivate *priv = SOUP_AUTH_MANAGER_GET_PRIVATE (feature);
 	SoupAuthClass *auth_class;
 	int i;
 
-	g_return_if_fail (g_type_is_a (type, SOUP_TYPE_AUTH));
+	if (!g_type_is_a (type, SOUP_TYPE_AUTH))
+		return FALSE;
 
 	auth_class = g_type_class_peek (type);
 	for (i = 0; i < priv->auth_types->len; i++) {
 		if (priv->auth_types->pdata[i] == (gpointer)auth_class) {
 			g_ptr_array_remove_index (priv->auth_types, i);
 			g_type_class_unref (auth_class);
-			return;
+			return TRUE;
 		}
 	}
+
+	return FALSE;
+}
+
+static gboolean
+has_feature (SoupSessionFeature *feature, GType type)
+{
+	SoupAuthManagerPrivate *priv = SOUP_AUTH_MANAGER_GET_PRIVATE (feature);
+	SoupAuthClass *auth_class;
+	int i;
+
+	if (!g_type_is_a (type, SOUP_TYPE_AUTH))
+		return FALSE;
+
+	auth_class = g_type_class_peek (type);
+	for (i = 0; i < priv->auth_types->len; i++) {
+		if (priv->auth_types->pdata[i] == (gpointer)auth_class)
+			return TRUE;
+	}
+	return FALSE;
 }
 
 void
diff --git a/libsoup/soup-auth-manager.h b/libsoup/soup-auth-manager.h
index b6759ec..493960a 100644
--- a/libsoup/soup-auth-manager.h
+++ b/libsoup/soup-auth-manager.h
@@ -32,11 +32,6 @@ typedef struct {
 
 GType soup_auth_manager_get_type (void);
 
-void soup_auth_manager_add_type          (SoupAuthManager *manager,
-					  GType            type);
-void soup_auth_manager_remove_type       (SoupAuthManager *manager,
-					  GType            type);
-
 void soup_auth_manager_emit_authenticate (SoupAuthManager *manager,
 					  SoupMessage     *msg,
 					  SoupAuth        *auth,
diff --git a/libsoup/soup-auth.h b/libsoup/soup-auth.h
index 453f51d..61a8236 100644
--- a/libsoup/soup-auth.h
+++ b/libsoup/soup-auth.h
@@ -100,6 +100,13 @@ void        soup_auth_has_saved_password    (SoupAuth      *auth,
 					     const char    *password);
 #endif
 
+/* The actual auth types, which can be added/removed as features */
+
+#define SOUP_TYPE_AUTH_BASIC  (soup_auth_basic_get_type ())
+GType soup_auth_basic_get_type  (void);
+#define SOUP_TYPE_AUTH_DIGEST (soup_auth_digest_get_type ())
+GType soup_auth_digest_get_type (void);
+
 G_END_DECLS
 
 #endif /* SOUP_AUTH_H */
diff --git a/tests/auth-test.c b/tests/auth-test.c
index 4749b44..4724d60 100644
--- a/tests/auth-test.c
+++ b/tests/auth-test.c
@@ -653,7 +653,8 @@ select_auth_authenticate (SoupSession *session, SoupMessage *msg,
 }
 
 static void
-select_auth_test_one (SoupURI *uri, const char *password,
+select_auth_test_one (SoupURI *uri,
+		      gboolean disable_digest, const char *password,
 		      const char *first_headers, const char *first_response,
 		      const char *second_headers, const char *second_response,
 		      guint final_status)
@@ -663,6 +664,9 @@ select_auth_test_one (SoupURI *uri, const char *password,
 	SoupSession *session;
 
 	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+	if (disable_digest)
+		soup_session_remove_feature_by_type (session, SOUP_TYPE_AUTH_DIGEST);
+
 	g_signal_connect (session, "authenticate",
 			  G_CALLBACK (select_auth_authenticate), &sad);
 	memset (&sad, 0, sizeof (sad));
@@ -726,7 +730,9 @@ static gboolean
 server_basic_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
 			    const char *username, const char *password, gpointer data)
 {
-	return FALSE;
+	if (strcmp (username, "user") != 0)
+		return FALSE;
+	return strcmp (password, "good-basic") == 0;
 }
 
 static char *
@@ -776,28 +782,43 @@ do_select_auth_test (void)
 		NULL);
 	soup_server_add_auth_domain (server, digest_auth_domain);
 
-	/* FIXME: when we support disabling auth types in the session,
-	 * test that too.
-	 */
-
 	debug_printf (1, "  Testing with no auth\n");
-	select_auth_test_one (uri, NULL,
+	select_auth_test_one (uri, FALSE, NULL,
 			      "Basic, Digest", "Digest",
 			      NULL, NULL,
 			      SOUP_STATUS_UNAUTHORIZED);
 
 	debug_printf (1, "  Testing with bad password\n");
-	select_auth_test_one (uri, "bad",
+	select_auth_test_one (uri, FALSE, "bad",
 			      "Basic, Digest", "Digest",
 			      "Basic, Digest", "Digest",
 			      SOUP_STATUS_UNAUTHORIZED);
 
 	debug_printf (1, "  Testing with good password\n");
-	select_auth_test_one (uri, "good",
+	select_auth_test_one (uri, FALSE, "good",
 			      "Basic, Digest", "Digest",
 			      NULL, NULL,
 			      SOUP_STATUS_OK);
 
+	/* Test with Digest disabled in the client. */
+	debug_printf (1, "  Testing without Digest with no auth\n");
+	select_auth_test_one (uri, TRUE, NULL,
+			      "Basic, Digest", "Basic",
+			      NULL, NULL,
+			      SOUP_STATUS_UNAUTHORIZED);
+
+	debug_printf (1, "  Testing without Digest with bad password\n");
+	select_auth_test_one (uri, TRUE, "bad",
+			      "Basic, Digest", "Basic",
+			      "Basic, Digest", "Basic",
+			      SOUP_STATUS_UNAUTHORIZED);
+
+	debug_printf (1, "  Testing without Digest with good password\n");
+	select_auth_test_one (uri, TRUE, "good-basic",
+			      "Basic, Digest", "Basic",
+			      NULL, NULL,
+			      SOUP_STATUS_OK);
+
 	/* Now flip the order of the domains, verify that this flips
 	 * the order of the headers, and make sure that digest auth
 	 * *still* gets used.
@@ -809,19 +830,19 @@ do_select_auth_test (void)
 	soup_server_add_auth_domain (server, basic_auth_domain);
 
 	debug_printf (1, "  Testing flipped with no auth\n");
-	select_auth_test_one (uri, NULL,
+	select_auth_test_one (uri, FALSE, NULL,
 			      "Digest, Basic", "Digest",
 			      NULL, NULL,
 			      SOUP_STATUS_UNAUTHORIZED);
 
 	debug_printf (1, "  Testing flipped with bad password\n");
-	select_auth_test_one (uri, "bad",
+	select_auth_test_one (uri, FALSE, "bad",
 			      "Digest, Basic", "Digest",
 			      "Digest, Basic", "Digest",
 			      SOUP_STATUS_UNAUTHORIZED);
 
 	debug_printf (1, "  Testing flipped with good password\n");
-	select_auth_test_one (uri, "good",
+	select_auth_test_one (uri, FALSE, "good",
 			      "Digest, Basic", "Digest",
 			      NULL, NULL,
 			      SOUP_STATUS_OK);



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