SoupAuthManager: implement subfeatures for adding/removing auth types
authorDan Winship <danw@gnome.org>
Mon, 7 Jun 2010 20:46:20 +0000 (16:46 -0400)
committerDan Winship <danw@gnome.org>
Thu, 9 Dec 2010 11:04:51 +0000 (12:04 +0100)
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
libsoup/soup-auth-digest.h
libsoup/soup-auth-manager.c
libsoup/soup-auth-manager.h
libsoup/soup-auth.h
tests/auth-test.c

index f6b7e2d..639bf03 100644 (file)
@@ -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*/
index 453c40c..0165f74 100644 (file)
@@ -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 {
index bb5ebb1..cc0f3c9 100644 (file)
@@ -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
index b6759ec..493960a 100644 (file)
@@ -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,
index 453f51d..61a8236 100644 (file)
@@ -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 */
index 4749b44..4724d60 100644 (file)
@@ -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);