This is an automated email from the ASF dual-hosted git repository. tonysun83 pushed a commit to branch retain_user_ctx_after_auth_2 in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 18fb58b453dfe909fe0dde81c251377394b72bd4 Author: Tony Sun <[email protected]> AuthorDate: Tue Jun 5 22:57:03 2018 -0700 refactor process_request to not drop req Previously, when we fail authorization but pass authentication, we use the old HttpReq which drops user_ctx. This change leaves user_ctx. --- src/chttpd/src/chttpd.erl | 51 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl index 6be0d18..ae94ae6 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.
