summaryrefslogtreecommitdiff
path: root/src/rabbit_access_control.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rabbit_access_control.erl')
-rw-r--r--src/rabbit_access_control.erl87
1 files changed, 48 insertions, 39 deletions
diff --git a/src/rabbit_access_control.erl b/src/rabbit_access_control.erl
index a6d3cd6c..0ebd2fcf 100644
--- a/src/rabbit_access_control.erl
+++ b/src/rabbit_access_control.erl
@@ -55,55 +55,64 @@ check_user_pass_login(Username, Password) ->
check_user_login(Username, AuthProps) ->
{ok, Modules} = application:get_env(rabbit, auth_backends),
R = lists:foldl(
- fun ({ModN, ModZ}, {refused, _, _}) ->
+ fun ({ModN, ModZs0}, {refused, _, _}) ->
+ ModZs = case ModZs0 of
+ A when is_atom(A) -> [A];
+ L when is_list(L) -> L
+ end,
%% Different modules for authN vs authZ. So authenticate
%% with authN module, then if that succeeds do
%% passwordless (i.e pre-authenticated) login with authZ.
case try_authenticate(ModN, Username, AuthProps) of
- {ok, User, _AuthZ} -> try_authorize(ModZ, User, []);
- Else -> Else
+ {ok, ModNUser = #auth_user{username = Username2}} ->
+ user(ModNUser, try_authorize(ModZs, Username2));
+ Else ->
+ Else
end;
(Mod, {refused, _, _}) ->
%% Same module for authN and authZ. Just take the result
%% it gives us
- try_authenticate(Mod, Username, AuthProps);
- (_, {ok, User, AuthZ}) ->
+ case try_authenticate(Mod, Username, AuthProps) of
+ {ok, ModNUser} -> user(ModNUser, {ok, [{Mod, ModNUser}]});
+ Else -> Else
+ end;
+ (_, {ok, User}) ->
%% We've successfully authenticated. Skip to the end...
- {ok, User, AuthZ}
+ {ok, User}
end, {refused, "No modules checked '~s'", [Username]}, Modules),
- case R of
- {ok, RUser, RAuthZ} ->
- rabbit_event:notify(user_authentication_success, [{name,Username}]),
- %% Store the list of authorization backends
- {ok, RUser#user{authZ_backends=RAuthZ}};
- _ ->
- rabbit_event:notify(user_authentication_failure, [{name,Username}]),
- R
- end.
+ rabbit_event:notify(case R of
+ {ok, _User} -> user_authentication_success;
+ _ -> user_authentication_failure
+ end, [{name, Username}]),
+ R.
try_authenticate(Module, Username, AuthProps) ->
case Module:check_user_login(Username, AuthProps) of
- {ok, User, AuthZ} -> {ok, User, [{Module, AuthZ}]};
- {error, E} -> {refused, "~s failed authenticating ~s: ~p~n",
- [Module, Username, E]};
- {refused, F, A} -> {refused, F, A}
+ {ok, AuthUser} -> {ok, AuthUser};
+ {error, E} -> {refused, "~s failed authenticating ~s: ~p~n",
+ [Module, Username, E]};
+ {refused, F, A} -> {refused, F, A}
end.
-try_authorize(Modules, User, AuthZList) when is_list(Modules) ->
+try_authorize(Modules, Username) ->
lists:foldr(
- fun (Module, {ok, _User, AuthZList2}) ->
- try_authorize(Module, User, AuthZList2);
+ fun (Module, {ok, AUsers}) ->
+ case Module:check_user_login(Username, []) of
+ {ok, AUser} -> {ok, [{Module, AUser} | AUsers]};
+ {error, E} -> {refused, "~s failed authorizing ~s: ~p~n",
+ [Module, Username, E]};
+ {refused, F, A} -> {refused, F, A}
+ end;
(_, {refused, _, _} = Error) ->
Error
- end, {ok, User, AuthZList}, Modules);
-
-try_authorize(Module, User = #user{username = Username}, AuthZList) ->
- case Module:check_user_login(Username, []) of
- {ok, _User, AuthZ} -> {ok, User, [{Module, AuthZ}|AuthZList]};
- {error, E} -> {refused, "~s failed authorizing ~s: ~p~n",
- [Module, Username, E]};
- Else -> Else
- end.
+ end, {ok, []}, Modules).
+
+user(#auth_user{username = Username, tags = Tags}, {ok, ModZUsers}) ->
+ {ok, #user{username = Username,
+ tags = Tags,
+ authz_backends = ModZUsers}};
+user(_AuthUser, Error) ->
+ Error.
check_user_loopback(Username, SockOrAddr) ->
{ok, Users} = application:get_env(rabbit, loopback_users),
@@ -113,14 +122,14 @@ check_user_loopback(Username, SockOrAddr) ->
false -> not_allowed
end.
-check_vhost_access(User = #user{username = Username,
- authZ_backends = Modules}, VHostPath, Sock) ->
+check_vhost_access(#user{username = Username,
+ authz_backends = Modules}, VHostPath, Sock) ->
lists:foldl(
- fun({Mod, Impl}, ok) ->
+ fun({Mod, AUser}, ok) ->
check_access(
fun() ->
rabbit_vhost:exists(VHostPath) andalso
- Mod:check_vhost_access(User, Impl, VHostPath, Sock)
+ Mod:check_vhost_access(AUser, VHostPath, Sock)
end,
Mod, "access to vhost '~s' refused for user '~s'",
[VHostPath, Username]);
@@ -132,14 +141,14 @@ check_resource_access(User, R = #resource{kind = exchange, name = <<"">>},
Permission) ->
check_resource_access(User, R#resource{name = <<"amq.default">>},
Permission);
-check_resource_access(User = #user{username = Username,
- authZ_backends = Modules},
+check_resource_access(#user{username = Username,
+ authz_backends = Modules},
Resource, Permission) ->
lists:foldl(
- fun({Module, Impl}, ok) ->
+ fun({Module, AUser}, ok) ->
check_access(
fun() -> Module:check_resource_access(
- User, Impl, Resource, Permission) end,
+ AUser, Resource, Permission) end,
Module, "access to ~s refused for user '~s'",
[rabbit_misc:rs(Resource), Username]);
(_, Else) -> Else