From 50decd4044bb8fcfd22c485e064a11d63fa15a2d Mon Sep 17 00:00:00 2001 From: "Damien F. Katz" Date: Wed, 22 Oct 2008 03:08:53 +0000 Subject: First check-in of admin http authentication and authorization. git-svn-id: https://svn.apache.org/repos/asf/incubator/couchdb/trunk@706848 13f79535-47bb-0310-9956-ffa450edef68 --- src/couchdb/couch_httpd.erl | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src/couchdb/couch_httpd.erl') diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl index 7cc5546f..2be90893 100644 --- a/src/couchdb/couch_httpd.erl +++ b/src/couchdb/couch_httpd.erl @@ -15,7 +15,8 @@ -export([start_link/0, stop/0, handle_request/3]). --export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,path/1,unquote/1]). +-export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,path/1]). +-export([check_is_admin/1,unquote/1]). -export([parse_form/1,json_body/1,body/1,doc_etag/1]). -export([primary_header_value/2,partition/1,serve_file/3]). -export([start_chunked_response/3,send_chunk/2]). @@ -85,6 +86,7 @@ start_link() -> stop() -> mochiweb_http:stop(?MODULE). + handle_request(MochiReq, UrlHandlers, DbUrlHandlers) -> @@ -195,6 +197,30 @@ json_body(#httpd{mochi_req=MochiReq}) -> doc_etag(#doc{revs=[DiskRev|_]}) -> "\"" ++ binary_to_list(DiskRev) ++ "\"". +check_is_admin(Req) -> + IsNamedAdmin = + case header_value(Req, "Authorization") of + "Basic " ++ Base64Value -> + [User, Pass] = + string:tokens(?b2l(couch_util:decodeBase64(Base64Value)),":"), + couch_server:is_admin(User, Pass); + _ -> + false + end, + + case IsNamedAdmin of + true -> + ok; + false -> + case couch_server:has_admins() of + true -> + throw(admin_auth_error); + false -> + % if no admins, then everyone is admin! Yay, admin party! + ok + end + end. + start_chunked_response(#httpd{mochi_req=MochiReq}, Code, Headers) -> {ok, MochiReq:respond({Code, Headers ++ server_header(), chunked})}. @@ -250,6 +276,11 @@ send_error(Req, {not_found, Reason}) -> send_error(Req, 404, <<"not_found">>, Reason); send_error(Req, conflict) -> send_error(Req, 412, <<"conflict">>, <<"Document update conflict.">>); +send_error(Req, admin_auth_error) -> + send_json(Req, 401, + [{"WWW-Authenticate", "Basic realm=\"admin\""}], + {[{<<"error">>, <<"auth_error">>}, + {<<"reason">>, <<"Admin user name and password required">>}]}); send_error(Req, {doc_validation, Msg}) -> send_error(Req, 406, <<"doc_validation">>, Msg); send_error(Req, file_exists) -> -- cgit v1.2.3