Skip to content

Commit 794054e

Browse files
A follow-up to #9550
1 parent f852ddb commit 794054e

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed

deps/rabbitmq_management/src/rabbit_mgmt_util.erl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
is_authorized_monitor/2, is_authorized_policies/2,
1717
is_authorized_vhost_visible/2,
1818
is_authorized_vhost_visible_for_monitoring/2,
19-
is_authorized_global_parameters/2]).
19+
is_authorized_global_parameters/2,
20+
is_authorized_vhost_and_has_resource_permission/4
21+
]).
2022
-export([user/1]).
2123
-export([bad_request/3, service_unavailable/3, bad_request_exception/4, internal_server_error/4,
2224
id/2, parse_bool/1, parse_int/1, redirect_to_home/3]).
@@ -120,6 +122,10 @@ is_authorized_vhost_visible_for_monitoring(ReqData, Context) ->
120122
Context,
121123
auth_config()).
122124

125+
is_authorized_vhost_and_has_resource_permission(ReqData, Context, Resource, Permission) ->
126+
rabbit_web_dispatch_access_control:is_authorized_vhost_and_has_resource_permission(
127+
ReqData, Context, Resource, Permission, auth_config()).
128+
123129
auth_config() ->
124130
BasicAuthEnabled = not get_bool_env(rabbitmq_management, disable_basic_auth, false),
125131
OauthEnabled = get_bool_env(rabbitmq_management, oauth_enabled, false),

deps/rabbitmq_management/src/rabbit_mgmt_wm_queue.erl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ delete_resource(ReqData, Context = #context{user = #user{username = ActingUser}}
9696
end.
9797

9898
is_authorized(ReqData, Context) ->
99-
rabbit_mgmt_util:is_authorized_vhost(ReqData, Context).
99+
VHost = rabbit_mgmt_util:id(vhost, ReqData),
100+
QName = rabbit_mgmt_util:id(queue, ReqData),
101+
QRes = rabbit_misc:r(VHost, queue, QName),
102+
rabbit_mgmt_util:is_authorized_vhost_and_has_resource_permission(ReqData, Context, QRes, configure).
100103

101104
%%--------------------------------------------------------------------
102105

deps/rabbitmq_management/test/rabbit_mgmt_http_SUITE.erl

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ all_tests() -> [
9393
permissions_administrator_test,
9494
permissions_vhost_test,
9595
permissions_amqp_test,
96+
permissions_queue_delete_test,
9697
permissions_connection_channel_consumer_test,
9798
consumers_cq_test,
9899
consumers_qq_test,
@@ -148,7 +149,9 @@ all_tests() -> [
148149
rates_test,
149150
single_active_consumer_cq_test,
150151
single_active_consumer_qq_test,
151-
%% oauth_test, %% disabled until we are able to enable oauth2 plugin
152+
%% This needs OAuth 2 plugin to be enabled on the node. How to best do that with Bazel and CT
153+
%% remains an open question right now.
154+
%% oauth_test,
152155
disable_basic_auth_test,
153156
login_test,
154157
csp_headers_test,
@@ -1427,6 +1430,18 @@ permissions_amqp_test(Config) ->
14271430
http_delete(Config, "/users/myuser", {group, '2xx'}),
14281431
passed.
14291432

1433+
permissions_queue_delete_test(Config) ->
1434+
QArgs = #{},
1435+
PermArgs = [{configure, <<"foo.*">>}, {write, <<".*">>}, {read, <<".*">>}],
1436+
http_put(Config, "/users/myuser", [{password, <<"myuser">>},
1437+
{tags, <<"management">>}], {group, '2xx'}),
1438+
http_put(Config, "/permissions/%2F/myuser", PermArgs, {group, '2xx'}),
1439+
http_put(Config, "/queues/%2F/bar-queue", QArgs, {group, '2xx'}),
1440+
http_delete(Config, "/queues/%2F/bar-queue", "myuser", "myuser", ?NOT_AUTHORISED),
1441+
http_delete(Config, "/queues/%2F/bar-queue", {group, '2xx'}),
1442+
http_delete(Config, "/users/myuser", {group, '2xx'}),
1443+
passed.
1444+
14301445
%% Opens a new connection and a channel on it.
14311446
%% The channel is not managed by rabbit_ct_client_helpers and
14321447
%% should be explicitly closed by the caller.

deps/rabbitmq_web_dispatch/src/rabbit_web_dispatch_access_control.erl

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
is_authorized_monitor/3, is_authorized_policies/3,
1818
is_authorized_vhost_visible/3,
1919
is_authorized_vhost_visible_for_monitoring/3,
20-
is_authorized_global_parameters/3]).
20+
is_authorized_global_parameters/3,
21+
is_authorized_vhost_and_has_resource_permission/5
22+
]).
2123

2224
-export([list_visible_vhosts/1, list_visible_vhosts_names/1, list_login_vhosts/2]).
2325
-export([id/2]).
@@ -176,12 +178,12 @@ is_authorized(ReqData, Context, Username, Password, ErrorMsg, Fun, AuthConfig, R
176178
end.
177179

178180

179-
%% Used for connections / channels. A normal user can only see / delete
181+
%% Used for connections and channels. A normal user can only see / delete
180182
%% their own stuff. Monitors can see other users' and delete their
181183
%% own. Admins can do it all.
182184
is_authorized_user(ReqData, Context, Item, AuthConfig) ->
183185
is_authorized(ReqData, Context,
184-
<<"User not authorised to access object">>,
186+
<<"User not authorised to access the resource(s)">>,
185187
fun(#user{username = Username, tags = Tags}) ->
186188
case cowboy_req:method(ReqData) of
187189
<<"DELETE">> -> is_admin(Tags);
@@ -190,11 +192,11 @@ is_authorized_user(ReqData, Context, Item, AuthConfig) ->
190192
end,
191193
AuthConfig).
192194

193-
%% For policies / parameters. Like is_authorized_vhost but you have to
195+
%% For policies and parameters. Like is_authorized_vhost but you have to
194196
%% be a policymaker.
195197
is_authorized_policies(ReqData, Context, AuthConfig) ->
196198
is_authorized(ReqData, Context,
197-
<<"User not authorised to access object">>,
199+
<<"User not authorised to access the resource(s)">>,
198200
fun(User = #user{tags = Tags}) ->
199201
is_admin(Tags) orelse
200202
(is_policymaker(Tags) andalso
@@ -211,6 +213,23 @@ is_authorized_global_parameters(ReqData, Context, AuthConfig) ->
211213
end,
212214
AuthConfig).
213215

216+
is_authorized_vhost_and_has_resource_permission(ReqData, Context, Resource, Permission, AuthConfig) ->
217+
is_authorized(ReqData, Context,
218+
<<"User not authorised to access this resource">>,
219+
fun(User) ->
220+
try
221+
AuthzData = get_authz_data_as_map(ReqData),
222+
ok =:= rabbit_access_control:check_resource_access(User, Resource, Permission, AuthzData)
223+
catch
224+
exit:Err:_Stacktrace ->
225+
#amqp_error{explanation = Msg} = Err,
226+
_ = rabbit_log:error(Msg),
227+
false
228+
end
229+
end,
230+
AuthConfig).
231+
232+
214233
vhost_from_headers(ReqData) ->
215234
case cowboy_req:header(<<"x-vhost">>, ReqData) of
216235
undefined -> none;
@@ -263,6 +282,9 @@ get_authz_data(ReqData) ->
263282
{PeerAddress, _PeerPort} = cowboy_req:peer(ReqData),
264283
{ip, PeerAddress}.
265284

285+
get_authz_data_as_map(ReqData) ->
286+
{PeerAddress, _PeerPort} = cowboy_req:peer(ReqData),
287+
#{ip => PeerAddress}.
266288

267289
not_authorised(Reason, ReqData, Context) ->
268290
%% TODO: consider changing to 403 in 4.0

0 commit comments

Comments
 (0)