Check for protected tag during user update and deletion via management API
This commit is contained in:
parent
aadc89b050
commit
ef7e772013
|
@ -53,6 +53,8 @@
|
||||||
|
|
||||||
-export([set_resp_not_found/2]).
|
-export([set_resp_not_found/2]).
|
||||||
|
|
||||||
|
-export([is_protected_user/1]).
|
||||||
|
|
||||||
-import(rabbit_misc, [pget/2]).
|
-import(rabbit_misc, [pget/2]).
|
||||||
|
|
||||||
-include("rabbit_mgmt.hrl").
|
-include("rabbit_mgmt.hrl").
|
||||||
|
@ -208,6 +210,14 @@ is_authorized_user(ReqData, Context, Username, Password, ReplyWhenFailed) ->
|
||||||
ReplyWhenFailed,
|
ReplyWhenFailed,
|
||||||
auth_config()).
|
auth_config()).
|
||||||
|
|
||||||
|
is_protected_user(Username) ->
|
||||||
|
case rabbit_auth_backend_internal:lookup_user(Username) of
|
||||||
|
{ok, User} ->
|
||||||
|
Tags = internal_user:get_tags(User),
|
||||||
|
rabbit_web_dispatch_access_control:is_protected_user(Tags);
|
||||||
|
{error, _} -> false
|
||||||
|
end.
|
||||||
|
|
||||||
vhost_from_headers(ReqData) ->
|
vhost_from_headers(ReqData) ->
|
||||||
rabbit_web_dispatch_access_control:vhost_from_headers(ReqData).
|
rabbit_web_dispatch_access_control:vhost_from_headers(ReqData).
|
||||||
|
|
||||||
|
|
|
@ -46,17 +46,31 @@ to_json(ReqData, Context) ->
|
||||||
|
|
||||||
accept_content(ReqData0, Context = #context{user = #user{username = ActingUser}}) ->
|
accept_content(ReqData0, Context = #context{user = #user{username = ActingUser}}) ->
|
||||||
Username = rabbit_mgmt_util:id(user, ReqData0),
|
Username = rabbit_mgmt_util:id(user, ReqData0),
|
||||||
|
case rabbit_mgmt_util:is_protected_user(Username) of
|
||||||
|
true ->
|
||||||
|
rabbit_mgmt_util:bad_request(
|
||||||
|
<<"User updates via API are disabled for this user">>,
|
||||||
|
ReqData0, Context);
|
||||||
|
false ->
|
||||||
rabbit_mgmt_util:with_decode(
|
rabbit_mgmt_util:with_decode(
|
||||||
[], ReqData0, Context,
|
[], ReqData0, Context,
|
||||||
fun(_, User, ReqData) ->
|
fun(_, User, ReqData) ->
|
||||||
_ = put_user(User#{name => Username}, ActingUser),
|
_ = put_user(User#{name => Username}, ActingUser),
|
||||||
{true, ReqData, Context}
|
{true, ReqData, Context}
|
||||||
end).
|
end)
|
||||||
|
end.
|
||||||
|
|
||||||
delete_resource(ReqData, Context = #context{user = #user{username = ActingUser}}) ->
|
delete_resource(ReqData, Context = #context{user = #user{username = ActingUser}}) ->
|
||||||
User = rabbit_mgmt_util:id(user, ReqData),
|
User = rabbit_mgmt_util:id(user, ReqData),
|
||||||
|
case rabbit_mgmt_util:is_protected_user(User) of
|
||||||
|
true ->
|
||||||
|
rabbit_mgmt_util:bad_request(
|
||||||
|
<<"User deletion via API is disabled for this user">>,
|
||||||
|
ReqData, Context);
|
||||||
|
false ->
|
||||||
rabbit_auth_backend_internal:delete_user(User, ActingUser),
|
rabbit_auth_backend_internal:delete_user(User, ActingUser),
|
||||||
{true, ReqData, Context}.
|
{true, ReqData, Context}
|
||||||
|
end.
|
||||||
|
|
||||||
is_authorized(ReqData, Context) ->
|
is_authorized(ReqData, Context) ->
|
||||||
rabbit_mgmt_util:is_authorized_admin(ReqData, Context).
|
rabbit_mgmt_util:is_authorized_admin(ReqData, Context).
|
||||||
|
|
|
@ -77,6 +77,7 @@ groups() ->
|
||||||
some_tests() ->
|
some_tests() ->
|
||||||
[
|
[
|
||||||
users_test,
|
users_test,
|
||||||
|
users_protected_test,
|
||||||
exchanges_test,
|
exchanges_test,
|
||||||
queues_test,
|
queues_test,
|
||||||
bindings_test,
|
bindings_test,
|
||||||
|
@ -657,6 +658,21 @@ users_test(Config) ->
|
||||||
http_get(Config, "/users/users_test", ?NOT_FOUND),
|
http_get(Config, "/users/users_test", ?NOT_FOUND),
|
||||||
passed.
|
passed.
|
||||||
|
|
||||||
|
users_protected_test(Config) ->
|
||||||
|
ProtectedUser = <<"protected_user">>,
|
||||||
|
rabbit_ct_broker_helpers:add_user(Config, ProtectedUser),
|
||||||
|
rabbit_ct_broker_helpers:set_user_tags(Config, 0, ProtectedUser, [management, protected]),
|
||||||
|
|
||||||
|
%% Verify protected user cannot be updated via API
|
||||||
|
http_put(Config, "/users/protected_user", [{password, <<"new_password">>},
|
||||||
|
{tags, <<"management,protected">>}], ?BAD_REQUEST),
|
||||||
|
|
||||||
|
%% Verify protected user cannot be deleted via API
|
||||||
|
http_delete(Config, "/users/protected_user", ?BAD_REQUEST),
|
||||||
|
|
||||||
|
rabbit_ct_broker_helpers:delete_user(Config, ProtectedUser),
|
||||||
|
passed.
|
||||||
|
|
||||||
without_permissions_users_test(Config) ->
|
without_permissions_users_test(Config) ->
|
||||||
assert_item(#{name => <<"guest">>, tags => [<<"administrator">>]},
|
assert_item(#{name => <<"guest">>, tags => [<<"administrator">>]},
|
||||||
http_get(Config, "/whoami")),
|
http_get(Config, "/whoami")),
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
-export([id/2]).
|
-export([id/2]).
|
||||||
-export([not_authorised/3, halt_response/5]).
|
-export([not_authorised/3, halt_response/5]).
|
||||||
|
|
||||||
-export([is_admin/1, is_policymaker/1, is_monitor/1, is_mgmt_user/1]).
|
-export([is_admin/1, is_policymaker/1, is_monitor/1, is_mgmt_user/1, is_protected_user/1]).
|
||||||
|
|
||||||
-import(rabbit_misc, [pget/2]).
|
-import(rabbit_misc, [pget/2]).
|
||||||
|
|
||||||
|
@ -243,6 +243,7 @@ is_policymaker(T) -> intersects(T, [administrator, policymaker]).
|
||||||
is_monitor(T) -> intersects(T, [administrator, monitoring]).
|
is_monitor(T) -> intersects(T, [administrator, monitoring]).
|
||||||
is_mgmt_user(T) -> intersects(T, [administrator, monitoring, policymaker,
|
is_mgmt_user(T) -> intersects(T, [administrator, monitoring, policymaker,
|
||||||
management]).
|
management]).
|
||||||
|
is_protected_user(T) -> intersects(T, [protected]).
|
||||||
|
|
||||||
intersects(A, B) -> lists:any(fun(I) -> lists:member(I, B) end, A).
|
intersects(A, B) -> lists:any(fun(I) -> lists:member(I, B) end, A).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue