summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/Makefile.am1
-rw-r--r--share/www/script/couch_tests.js1
-rw-r--r--src/couchdb/couch_httpd_auth.erl57
3 files changed, 59 insertions, 0 deletions
diff --git a/share/Makefile.am b/share/Makefile.am
index 0288ada6..69f5baaf 100644
--- a/share/Makefile.am
+++ b/share/Makefile.am
@@ -134,6 +134,7 @@ nobase_dist_localdata_DATA = \
www/script/test/lots_of_docs.js \
www/script/test/multiple_rows.js \
www/script/test/oauth.js \
+ www/script/test/proxyauth.js \
www/script/test/purge.js \
www/script/test/reader_acl.js \
www/script/test/recreate_doc.js \
diff --git a/share/www/script/couch_tests.js b/share/www/script/couch_tests.js
index 04253c58..85d07065 100644
--- a/share/www/script/couch_tests.js
+++ b/share/www/script/couch_tests.js
@@ -62,6 +62,7 @@ loadTest("multiple_rows.js");
loadScript("script/oauth.js");
loadScript("script/sha1.js");
loadTest("oauth.js");
+loadTest("proxyauth.js");
loadTest("purge.js");
loadTest("reader_acl.js");
loadTest("recreate_doc.js");
diff --git a/src/couchdb/couch_httpd_auth.erl b/src/couchdb/couch_httpd_auth.erl
index 505194a9..3e2981ac 100644
--- a/src/couchdb/couch_httpd_auth.erl
+++ b/src/couchdb/couch_httpd_auth.erl
@@ -16,6 +16,7 @@
-export([default_authentication_handler/1,special_test_authentication_handler/1]).
-export([cookie_authentication_handler/1]).
-export([null_authentication_handler/1]).
+-export([proxy_authentification_handler/1]).
-export([cookie_auth_header/2]).
-export([handle_session_req/1]).
-export([ensure_users_db_exists/1, get_user/1]).
@@ -99,6 +100,62 @@ default_authentication_handler(Req) ->
null_authentication_handler(Req) ->
Req#httpd{user_ctx=#user_ctx{roles=[<<"_admin">>]}}.
+%% @doc proxy auth handler.
+%
+% This handler allows creation of a userCtx object from a user authenticated remotly.
+% The client just pass specific headers to CouchDB and the handler create the userCtx.
+% Headers name can be defined in local.ini. By thefault they are :
+%
+% * X-Auth-CouchDB-UserName : contain the username, (x_auth_username in
+% couch_httpd_auth section)
+% * X-Auth-CouchDB-Roles : contain the user roles, list of roles separated by a
+% comma (x_auth_roles in couch_httpd_auth section)
+% * X-Auth-CouchDB-Token : token to authenticate the authorization (x_auth_token
+% in couch_httpd_auth section). This token is an hmac-sha1 created from secret key
+% and username. The secret key should be the same in the client and couchdb node. s
+% ecret key is the secret key in couch_httpd_auth section of ini. This token is optional
+% if value of proxy_use_secret key in couch_httpd_auth section of ini isn't true.
+%
+proxy_authentification_handler(Req) ->
+ case proxy_auth_user(Req) of
+ nil -> Req;
+ Req2 -> Req2
+ end.
+
+proxy_auth_user(Req) ->
+ XHeaderUserName = couch_config:get("couch_httpd_auth", "x_auth_username",
+ "X-Auth-CouchDB-UserName"),
+ XHeaderRoles = couch_config:get("couch_httpd_auth", "x_auth_roles",
+ "X-Auth-CouchDB-Roles"),
+ XHeaderToken = couch_config:get("couch_httpd_auth", "x_auth_token",
+ "X-Auth-CouchDB-Token"),
+ case header_value(Req, XHeaderUserName) of
+ undefined -> nil;
+ UserName ->
+ Roles = case header_value(Req, XHeaderRoles) of
+ undefined -> [];
+ Else ->
+ [?l2b(R) || R <- string:tokens(Else, ",")]
+ end,
+ case couch_config:get("couch_httpd_auth", "proxy_use_secret", "false") of
+ "true" ->
+ case couch_config:get("couch_httpd_auth", "secret", nil) of
+ nil ->
+ Req#httpd{user_ctx=#user_ctx{name=?l2b(UserName), roles=Roles}};
+ Secret ->
+ ExpectedToken = couch_util:to_hex(crypto:sha_mac(Secret, UserName)),
+ case header_value(Req, XHeaderToken) of
+ Token when Token == ExpectedToken ->
+ Req#httpd{user_ctx=#user_ctx{name=?l2b(UserName),
+ roles=Roles}};
+ _ -> nil
+ end
+ end;
+ _ ->
+ Req#httpd{user_ctx=#user_ctx{name=?l2b(UserName), roles=Roles}}
+ end
+ end.
+
% maybe we can use hovercraft to simplify running this view query
% rename to get_user_from_users_db
get_user(UserName) ->