summaryrefslogtreecommitdiff
path: root/src/couchdb/couch_httpd.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couchdb/couch_httpd.erl')
-rw-r--r--src/couchdb/couch_httpd.erl53
1 files changed, 40 insertions, 13 deletions
diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index 2be90893..c58255e3 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -16,7 +16,7 @@
-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]).
--export([check_is_admin/1,unquote/1]).
+-export([check_is_admin/1,unquote/1,creds/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]).
@@ -197,14 +197,37 @@ json_body(#httpd{mochi_req=MochiReq}) ->
doc_etag(#doc{revs=[DiskRev|_]}) ->
"\"" ++ binary_to_list(DiskRev) ++ "\"".
-check_is_admin(Req) ->
- IsNamedAdmin =
+
+% user credentials
+creds(Req) ->
+ case username_pw(Req) of
+ {User, _Pw} ->
+ {[{<<"name">>, ?l2b(User)}]};
+ nil ->
+ {[]}
+ end.
+
+username_pw(Req) ->
case header_value(Req, "Authorization") of
"Basic " ++ Base64Value ->
- [User, Pass] =
- string:tokens(?b2l(couch_util:decodeBase64(Base64Value)),":"),
- couch_server:is_admin(User, Pass);
+ case string:tokens(?b2l(couch_util:decodeBase64(Base64Value)),":") of
+ [User, Pass] ->
+ {User, Pass};
+ [User] ->
+ {User, <<"">>};
+ _ ->
+ nil
+ end;
_ ->
+ nil
+ end.
+
+check_is_admin(Req) ->
+ IsNamedAdmin =
+ case username_pw(Req) of
+ {User, Pass} ->
+ couch_server:is_admin(User, Pass);
+ nil ->
false
end,
@@ -214,7 +237,7 @@ check_is_admin(Req) ->
false ->
case couch_server:has_admins() of
true ->
- throw(admin_auth_error);
+ throw(admin_authorization_error);
false ->
% if no admins, then everyone is admin! Yay, admin party!
ok
@@ -265,7 +288,6 @@ end_json_response(Resp) ->
send_chunk(Resp, []).
-
send_error(Req, bad_request) ->
send_error(Req, 400, <<"bad_request">>, <<>>);
send_error(Req, {bad_request, Reason}) ->
@@ -276,13 +298,18 @@ 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_error(Req, admin_authorization_error) ->
send_json(Req, 401,
- [{"WWW-Authenticate", "Basic realm=\"admin\""}],
- {[{<<"error">>, <<"auth_error">>},
+ [{"WWW-Authenticate", "Basic realm=\"administrator\""}],
+ {[{<<"error">>, <<"authorization">>},
{<<"reason">>, <<"Admin user name and password required">>}]});
-send_error(Req, {doc_validation, Msg}) ->
- send_error(Req, 406, <<"doc_validation">>, Msg);
+send_error(Req, {user_error, {Props}}) ->
+ {Headers} = proplists:get_value(<<"headers">>, Props, {[]}),
+ send_json(Req,
+ proplists:get_value(<<"http_status">>, Props, 500),
+ Headers,
+ {[{<<"error">>, proplists:get_value(<<"error">>, Props)},
+ {<<"reason">>, proplists:get_value(<<"reason">>, Props)}]});
send_error(Req, file_exists) ->
send_error(Req, 409, <<"file_exists">>, <<"The database could not be "
"created, the file already exists.">>);