From 46a2a634df57067426da8ed53e815ddb60f1d67b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mu=CC=88nch?= Date: Sat, 15 Oct 2016 20:16:53 +0200 Subject: [PATCH 1/2] Make auth handlers configurable. --- src/chttpd.erl | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/chttpd.erl b/src/chttpd.erl index d55aa5e..dec1547 100644 --- a/src/chttpd.erl +++ b/src/chttpd.erl @@ -117,6 +117,8 @@ start_link(Name, Options) -> end, ok = couch_httpd:validate_bind_address(IP), + set_auth_handlers(), + Options1 = Options ++ [ {loop, fun ?MODULE:handle_request/1}, {name, Name}, @@ -464,12 +466,37 @@ extract_cookie(#httpd{mochi_req = MochiReq}) -> end. %%% end hack -authenticate_request(Req) -> - AuthenticationFuns = [ - {<<"cookie">>, fun chttpd_auth:cookie_authentication_handler/1}, - {<<"default">>, fun chttpd_auth:default_authentication_handler/1}, +set_auth_handlers() -> + AuthenticationDefault = "{chttpd_auth, cookie_authentication_handler}, + {chttpd_auth, default_authentication_handler}", + AuthenticationSrcs = couch_httpd:make_fun_spec_strs( + config:get("chttpd", "authentication_handlers", AuthenticationDefault)), + AuthHandlers = lists:map( + fun(A) -> {auth_handler_name(A), couch_httpd:make_arity_1_fun(A)} end, AuthenticationSrcs), + AuthenticationFuns = AuthHandlers ++ [ fun chttpd_auth:party_mode_handler/1 %% must be last ], + ok = application:set_env(chttpd, auth_handlers, AuthenticationFuns). + +% SpecStr is a string like "{my_module, my_fun}" +% Takes the first token of the function name in front '_' as auth handler name +% e.g. +% chttpd_auth:default_authentication_handler: default +% chttpd_auth_cookie_authentication_handler: cookie +% couch_http_auth:proxy_authentication_handler: proxy +% +% couch_http:auth_handler_name can't be used here, since it assumes the name +% of the auth handler to be the 6th token split by [\\W_] +% - this only works for modules with exactly two underscores in their name +% - is not very robust (a space after the ',' is assumed) +auth_handler_name(SpecStr) -> + case couch_util:parse_term(SpecStr) of + {ok, {_, Fun}} -> + hd(string:tokens(atom_to_list(Fun), "_")) + end. + +authenticate_request(Req) -> + {ok, AuthenticationFuns} = application:get_env(chttpd, auth_handlers), authenticate_request(Req, chttpd_auth_cache, AuthenticationFuns). authenticate_request(#httpd{} = Req0, AuthModule, AuthFuns) -> From f28d30fe5014627199176b18d1ce28125dab8e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mu=CC=88nch?= Date: Mon, 17 Oct 2016 15:26:10 +0200 Subject: [PATCH 2/2] Use pattern matching instead of case statement with single cause --- src/chttpd.erl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/chttpd.erl b/src/chttpd.erl index dec1547..b3e74d2 100644 --- a/src/chttpd.erl +++ b/src/chttpd.erl @@ -490,10 +490,8 @@ set_auth_handlers() -> % - this only works for modules with exactly two underscores in their name % - is not very robust (a space after the ',' is assumed) auth_handler_name(SpecStr) -> - case couch_util:parse_term(SpecStr) of - {ok, {_, Fun}} -> - hd(string:tokens(atom_to_list(Fun), "_")) - end. + {ok, {_, Fun}} = couch_util:parse_term(SpecStr), + hd(string:tokens(atom_to_list(Fun), "_")). authenticate_request(Req) -> {ok, AuthenticationFuns} = application:get_env(chttpd, auth_handlers),