[couchdb-glib] Add basic HTTP authentication to CouchdbCredentials



commit 92219af5645b8a8b8e72f079ba213de2f8a7318d
Author: Adi Roiban <adiroiban ubuntu com>
Date:   Mon Jan 18 15:52:28 2010 +0100

    Add basic HTTP authentication to CouchdbCredentials

 couchdb-glib/couchdb-credentials.c |   31 ++++++++++++++++++
 couchdb-glib/couchdb-credentials.h |    8 ++++-
 couchdb-glib/couchdb-session.c     |   62 +++++++++++++++++++++++++++++++++++-
 couchdb-glib/couchdb-session.h     |    2 +
 4 files changed, 101 insertions(+), 2 deletions(-)
---
diff --git a/couchdb-glib/couchdb-credentials.c b/couchdb-glib/couchdb-credentials.c
index 04a882f..8757e18 100644
--- a/couchdb-glib/couchdb-credentials.c
+++ b/couchdb-glib/couchdb-credentials.c
@@ -95,6 +95,37 @@ couchdb_credentials_new_with_oauth (const gchar *consumer_key,
 }
 
 /**
+ * couchdb_credentials_new_with_username_and_password:
+ * @username: HTTP Authentication username
+ * @password: HTTP Authentication password
+ *
+ * Create a new #CouchdbCredentials object to be used for username
+ * and password based HTTP authentication scheme such as Basic or
+ * Digest.
+ *
+ * Authentication is delegated to LibSoup.
+ *
+ * Return value: A #CouchdbCredentials object.
+ */
+CouchdbCredentials *
+couchdb_credentials_new_with_username_and_password (const gchar *username,
+						    const gchar *password)
+{
+	CouchdbCredentials *credentials;
+
+	credentials = COUCHDB_CREDENTIALS (g_object_new (COUCHDB_TYPE_CREDENTIALS, NULL));
+	credentials->priv->type = COUCHDB_CREDENTIALS_TYPE_USERNAME_AND_PASSWORD;
+	couchdb_credentials_set_item (credentials,
+				      COUCHDB_CREDENTIALS_ITEM_USERNAME,
+				      username);
+	couchdb_credentials_set_item (credentials,
+				      COUCHDB_CREDENTIALS_ITEM_PASSWORD,
+				      password);
+
+	return credentials;
+}
+
+/**
  * couchdb_credentials_get_auth_type:
  * @credentials: A #CouchdbCredentials object
  *
diff --git a/couchdb-glib/couchdb-credentials.h b/couchdb-glib/couchdb-credentials.h
index a891869..abe814c 100644
--- a/couchdb-glib/couchdb-credentials.h
+++ b/couchdb-glib/couchdb-credentials.h
@@ -46,7 +46,8 @@ typedef struct {
 
 typedef enum {
 	COUCHDB_CREDENTIALS_TYPE_UNKNOWN = -1,
-	COUCHDB_CREDENTIALS_TYPE_OAUTH
+	COUCHDB_CREDENTIALS_TYPE_OAUTH,
+	COUCHDB_CREDENTIALS_TYPE_USERNAME_AND_PASSWORD
 } CouchdbCredentialsType;
 
 GType                  couchdb_credentials_get_type (void);
@@ -54,12 +55,17 @@ CouchdbCredentials    *couchdb_credentials_new_with_oauth (const gchar *consumer
 							   const gchar *consumer_secret,
 							   const gchar *token_key,
 							   const gchar *token_secret);
+CouchdbCredentials    *couchdb_credentials_new_with_username_and_password (const gchar *username,
+									   const gchar *password);
+
 CouchdbCredentialsType couchdb_credentials_get_auth_type (CouchdbCredentials *credentials);
 
 #define COUCHDB_CREDENTIALS_ITEM_OAUTH_CONSUMER_KEY    "oauth_consumer_key"
 #define COUCHDB_CREDENTIALS_ITEM_OAUTH_CONSUMER_SECRET "oauth_consumer_secret"
 #define COUCHDB_CREDENTIALS_ITEM_OAUTH_TOKEN_KEY       "oauth_token_key"
 #define COUCHDB_CREDENTIALS_ITEM_OAUTH_TOKEN_SECRET    "oauth_token_secret"
+#define COUCHDB_CREDENTIALS_ITEM_USERNAME	       "username"
+#define COUCHDB_CREDENTIALS_ITEM_PASSWORD	       "password"
 
 const gchar           *couchdb_credentials_get_item (CouchdbCredentials *credentials, const gchar *item);
 void                   couchdb_credentials_set_item (CouchdbCredentials *credentials,
diff --git a/couchdb-glib/couchdb-session.c b/couchdb-glib/couchdb-session.c
index 1216c09..48aebeb 100644
--- a/couchdb-glib/couchdb-session.c
+++ b/couchdb-glib/couchdb-session.c
@@ -35,6 +35,8 @@
 #include "oauth.h"
 #endif
 
+#define COUCHDB_SIGNAL_AUTHENTICATION_FAILED "authentication-failed"
+
 struct _CouchdbSessionPrivate {
 	char *uri;
 	SoupSession *http_session;
@@ -45,6 +47,7 @@ struct _CouchdbSessionPrivate {
 G_DEFINE_TYPE(CouchdbSession, couchdb_session, G_TYPE_OBJECT)
 
 enum {
+	AUTHENTICATION_FAILED,
 	DATABASE_CREATED,
 	DATABASE_DELETED,
 	DOCUMENT_CREATED,
@@ -69,6 +72,13 @@ static void debug_message (const gchar *log_domain,
 			   const gchar *message, gpointer user_data);
 #endif
 
+static gboolean _session_authenticate(SoupSession *session,
+				      SoupMessage *msg,
+				      SoupAuth *auth,
+				      gboolean retrying,
+				      gpointer couchdb);
+
+
 static void
 couchdb_session_finalize (GObject *object)
 {
@@ -143,6 +153,15 @@ couchdb_session_class_init (CouchdbSessionClass *klass)
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 	/* Signals */
+	couchdb_session_signals[AUTHENTICATION_FAILED] =
+		g_signal_new (COUCHDB_SIGNAL_AUTHENTICATION_FAILED,
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (CouchdbSessionClass, authentication_failed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0,
+			      NULL);
 	couchdb_session_signals[DATABASE_CREATED] =
 		g_signal_new ("database_created",
 			      G_OBJECT_CLASS_TYPE (object_class),
@@ -482,10 +501,16 @@ couchdb_session_enable_authentication (CouchdbSession *couchdb,
 		g_object_unref (G_OBJECT (couchdb->priv->credentials));
 
 	couchdb->priv->credentials = COUCHDB_CREDENTIALS (g_object_ref (G_OBJECT (credentials)));
+	if (couchdb_credentials_get_auth_type (couchdb->priv->credentials) == COUCHDB_CREDENTIALS_TYPE_USERNAME_AND_PASSWORD) {
+		g_signal_connect (couchdb->priv->http_session,
+				  "authenticate",
+				  G_CALLBACK (_session_authenticate),
+				  couchdb);
+	}
 }
 
 /**
- * couchdb_session_enable_authentication:
+ * couchdb_session_disable_authentication:
  * @couchdb: A #CouchdbSession object
  *
  * Disables authentication for the given #CouchdbSession object.
@@ -495,6 +520,12 @@ couchdb_session_disable_authentication (CouchdbSession *couchdb)
 {
 	g_return_if_fail (COUCHDB_IS_SESSION (couchdb));
 
+	if (couchdb_credentials_get_auth_type (couchdb->priv->credentials) == COUCHDB_CREDENTIALS_TYPE_USERNAME_AND_PASSWORD) {
+		g_signal_handlers_disconnect_by_func (couchdb->priv->http_session,
+						      G_CALLBACK (_session_authenticate),
+						      couchdb);
+	}
+
 	if (couchdb->priv->credentials) {
 		g_object_unref (G_OBJECT (couchdb->priv->credentials));
 		couchdb->priv->credentials = NULL;
@@ -517,6 +548,35 @@ couchdb_session_is_authentication_enabled (CouchdbSession *couchdb)
 	return couchdb->priv->credentials != NULL;
 }
 
+static gboolean
+_session_authenticate(SoupSession *session, SoupMessage *msg,
+		      SoupAuth *auth, gboolean retrying,
+		      gpointer callback_data)
+{
+	CouchdbSession *couchdb;
+
+	g_return_val_if_fail (COUCHDB_IS_SESSION (callback_data), FALSE);
+
+	couchdb = COUCHDB_SESSION (callback_data);
+
+	if (retrying) {
+		g_signal_emit_by_name (couchdb, COUCHDB_SIGNAL_AUTHENTICATION_FAILED, NULL);
+		g_debug ("Authentication failed!");
+		return FALSE;
+	}
+
+	if (couchdb_credentials_get_auth_type (couchdb->priv->credentials) == COUCHDB_CREDENTIALS_TYPE_USERNAME_AND_PASSWORD) {
+		const char *username = couchdb_credentials_get_item (couchdb->priv->credentials,
+								     COUCHDB_CREDENTIALS_ITEM_USERNAME);
+		const char *password = couchdb_credentials_get_item (couchdb->priv->credentials,
+								     COUCHDB_CREDENTIALS_ITEM_PASSWORD);
+
+		soup_auth_authenticate (auth, username, password);
+	}
+
+	return TRUE;
+}
+
 static void
 add_oauth_signature (CouchdbSession *couchdb, SoupMessage *http_message, const char *method, const char *url)
 {
diff --git a/couchdb-glib/couchdb-session.h b/couchdb-glib/couchdb-session.h
index 97a1657..9035357 100644
--- a/couchdb-glib/couchdb-session.h
+++ b/couchdb-glib/couchdb-session.h
@@ -51,6 +51,8 @@ typedef struct {
 typedef struct {
 	GObjectClass parent_class;
 
+	void (* authentication_failed) (CouchdbSession *couchdb);
+
 	void (* database_created) (CouchdbSession *couchdb, const char *dbname);
 	void (* database_deleted) (CouchdbSession *couchdb, const char *dbname);
 



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