summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Sun <tony.sun427@gmail.com>2018-06-05 22:57:03 -0700
committerTony Sun <tony.sun427@gmail.com>2018-06-19 00:08:34 -0700
commit18fb58b453dfe909fe0dde81c251377394b72bd4 (patch)
treec207d85d9537069d6091fddda7c0f3ee0ffa24c6
parent3c9838528972ec55165fdd98bc70cec0bff4db3d (diff)
downloadcouchdb-retain_user_ctx_after_auth.tar.gz
refactor process_request to not drop reqretain_user_ctx_after_auth
Previously, when we fail authorization but pass authentication, we use the old HttpReq which drops user_ctx. This change leaves user_ctx.
-rw-r--r--src/chttpd/src/chttpd.erl51
1 files changed, 46 insertions, 5 deletions
diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index 6be0d1848..ae94ae6fc 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -288,11 +288,7 @@ process_request(#httpd{mochi_req = MochiReq} = HttpReq) ->
not_preflight ->
case chttpd_auth:authenticate(HttpReq, fun authenticate_request/1) of
#httpd{} = Req ->
- HandlerFun = chttpd_handlers:url_handler(
- HandlerKey, fun chttpd_db:handle_request/1),
- AuthorizedReq = chttpd_auth:authorize(possibly_hack(Req),
- fun chttpd_auth_request:authorize_request/1),
- {AuthorizedReq, HandlerFun(AuthorizedReq)};
+ handle_req_after_auth(HandlerKey, Req);
Response ->
{HttpReq, Response}
end;
@@ -303,6 +299,17 @@ process_request(#httpd{mochi_req = MochiReq} = HttpReq) ->
{HttpReq, catch_error(HttpReq, Tag, Error)}
end.
+handle_req_after_auth(HandlerKey, HttpReq) ->
+ try
+ HandlerFun = chttpd_handlers:url_handler(HandlerKey,
+ fun chttpd_db:handle_request/1),
+ AuthorizedReq = chttpd_auth:authorize(possibly_hack(HttpReq),
+ fun chttpd_auth_request:authorize_request/1),
+ {AuthorizedReq, HandlerFun(AuthorizedReq)}
+ catch Tag:Error ->
+ {HttpReq, catch_error(HttpReq, Tag, Error)}
+ end.
+
catch_error(_HttpReq, throw, {http_head_abort, Resp}) ->
{ok, Resp};
catch_error(_HttpReq, throw, {http_abort, Resp, Reason}) ->
@@ -1238,4 +1245,38 @@ test_log_request(RawPath, UserCtx) ->
ok = meck:unload(couch_log),
Message.
+handle_req_after_auth_test() ->
+ Headers = mochiweb_headers:make([{"HOST", "127.0.0.1:15984"}]),
+ MochiReq = mochiweb_request:new(socket, [], 'PUT', "/newdb", version,
+ Headers),
+ UserCtx = #user_ctx{name = <<"retain_user">>},
+ Roles = [<<"_reader">>],
+ AuthorizedCtx = #user_ctx{name = <<"retain_user">>, roles = Roles},
+ Req = #httpd{
+ mochi_req = MochiReq,
+ begin_ts = {1458,588713,124003},
+ original_method = 'PUT',
+ peer = "127.0.0.1",
+ nonce = "nonce",
+ user_ctx = UserCtx
+ },
+ AuthorizedReq = Req#httpd{user_ctx = AuthorizedCtx},
+ ok = meck:new(chttpd_handlers, [passthrough]),
+ ok = meck:new(chttpd_auth, [passthrough]),
+ ok = meck:expect(chttpd_handlers, url_handler, fun(_Key, _Fun) ->
+ fun(_Req) -> handled_authorized_req end
+ end),
+ ok = meck:expect(chttpd_auth, authorize, fun(_Req, _Fun) ->
+ AuthorizedReq
+ end),
+ ?assertEqual({AuthorizedReq, handled_authorized_req},
+ handle_req_after_auth(foo_key, Req)),
+ ok = meck:expect(chttpd_auth, authorize, fun(_Req, _Fun) ->
+ meck:exception(throw, {http_abort, resp, some_reason})
+ end),
+ ?assertEqual({Req, {aborted, resp, some_reason}},
+ handle_req_after_auth(foo_key, Req)),
+ ok = meck:unload(chttpd_handlers),
+ ok = meck:unload(chttpd_auth).
+
-endif.