diff --git a/.gitignore b/.gitignore index f9dabdb..85927a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .eunit -deps +/deps/* *.o *.beam *.plt diff --git a/priv/local.d/ldap_auth.ini b/priv/local.d/ldap_auth.ini index 4aa2d6d..a8cccde 100644 --- a/priv/local.d/ldap_auth.ini +++ b/priv/local.d/ldap_auth.ini @@ -2,12 +2,16 @@ _session = {ldap_auth, handle_session_req} [httpd] - authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {ldap_auth, handle_basic_auth_req}, {ldap_auth, handle_admin_role} + authentication_handlers = {ldap_auth, handle_admin_role} [ldap_auth] ; NOTE: for all of the following configurations, if the key is suffixed in "DN", ldap_auth ; will expect you to provide a real LDAP Distinguished Name. + ; If you use handle_admin_role to assign your system admins, specify the authentication handlers it should + ; query here. See SystemAdminRoleName for more details. + AuthenticationHandlers = {couch_httpd_auth, cookie_authentication_handler}, {ldap_auth, handle_basic_auth_req} + ; Enable SSL to the LDAP server. UseSsl = false diff --git a/rebar.config b/rebar.config index 1a06fba..d258ca9 100644 --- a/rebar.config +++ b/rebar.config @@ -1,4 +1,4 @@ %%-*- mode: erlang -*- {deps, [ - {meck, "0.8.1", {git, "https://github.com/eproxus/meck.git", {tag, "0.8.1"}}} + {meck, "0.8.2", {git, "https://github.com/eproxus/meck.git", {tag, "0.8.2"}}} ]}. diff --git a/src/ldap_auth.erl b/src/ldap_auth.erl index d116fc9..4db1455 100644 --- a/src/ldap_auth.erl +++ b/src/ldap_auth.erl @@ -16,7 +16,7 @@ -export([handle_basic_auth_req/1, handle_admin_role/1]). -export([handle_session_req/1]). --import(couch_httpd, [header_value/2, send_json/2,send_json/4, send_method_not_allowed/2]). +-import(couch_httpd, [header_value/2, send_json/2, send_json/4, send_method_not_allowed/2]). -import(ldap_auth_config, [get_config/1]). -import(ldap_auth_gateway, [connect/0, authenticate/3, get_user_dn/2, get_group_memberships/2]). @@ -41,13 +41,26 @@ handle_basic_auth_req(Req) -> Req end. -handle_admin_role(#httpd{ user_ctx = #user_ctx{ roles = Roles } = UserCtx } = Req) when size(Roles) > 0 -> +handle_admin_role(Req) -> + % This is a workaround pending a resolution to https://issues.apache.org/jira/browse/COUCHDB-2034 + [AuthenticationHandlers] = get_config(["AuthenticationHandlers"]), + {ok, Tokens, _} = erl_scan:string("[" ++ AuthenticationHandlers ++ "]."), + {ok, Term} = erl_parse:parse_term(Tokens), + AuthedReq = run_auth_handlers(Req, Term), + prepend_admin_role(AuthedReq). + +prepend_admin_role(#httpd{ user_ctx = #user_ctx{ name = User, roles = Roles } = UserCtx } = Req) when length(Roles) > 0 -> [SystemAdminRoleName] = get_config(["SystemAdminRoleName"]), - case lists:member(SystemAdminRoleName, Roles) of + ?LOG_DEBUG("Checking for system admin role ~p for user ~p with roles: ~p", [ SystemAdminRoleName, User, Roles ]), + case lists:member(?l2b(SystemAdminRoleName), Roles) of true -> Req#httpd{ user_ctx = UserCtx#user_ctx{ roles = [<<"_admin">>|Roles] } }; _ -> Req end; -handle_admin_role(Req) -> Req. +prepend_admin_role(#httpd{} = Req) -> Req. + +run_auth_handlers(Req, []) -> Req; +run_auth_handlers(Req, [ {Mod, Fun} | Rem]) -> run_auth_handlers(Mod:Fun(Req), Rem); +run_auth_handlers(Req, [ {Mod, Fun, SpecArg} | Rem]) -> run_auth_handlers(Mod:Fun(Req, SpecArg), Rem). % session handlers % Login handler with user db