diff options
author | Tony Sun <tony.sun427@gmail.com> | 2018-06-05 22:57:03 -0700 |
---|---|---|
committer | Tony Sun <tony.sun427@gmail.com> | 2018-06-19 00:08:34 -0700 |
commit | 18fb58b453dfe909fe0dde81c251377394b72bd4 (patch) | |
tree | c207d85d9537069d6091fddda7c0f3ee0ffa24c6 | |
parent | 3c9838528972ec55165fdd98bc70cec0bff4db3d (diff) | |
download | couchdb-18fb58b453dfe909fe0dde81c251377394b72bd4.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.erl | 51 |
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. |