Skip to content

Commit 30c5c79

Browse files
Merge pull request #16241 from rabbitmq/mergify/bp/v4.2.x/pr-16237
HTTP API: revisit authN attempt stats (backport #16235) (backport #16237)
2 parents 2d4e98e + dcadd95 commit 30c5c79

2 files changed

Lines changed: 102 additions & 1 deletion

File tree

deps/rabbitmq_management/src/rabbit_mgmt_wm_auth_attempts.erl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ to_json(ReqData, {Mode, Context}) ->
3333
rabbit_mgmt_util:reply(augment(Mode, ReqData), ReqData, Context).
3434

3535
is_authorized(ReqData, {Mode, Context}) ->
36-
{Res, Req2, Context2} = rabbit_mgmt_util:is_authorized_monitor(ReqData, Context),
36+
AuthFun = case cowboy_req:method(ReqData) of
37+
<<"DELETE">> -> fun rabbit_mgmt_util:is_authorized_admin/2;
38+
_ -> fun rabbit_mgmt_util:is_authorized_monitor/2
39+
end,
40+
{Res, Req2, Context2} = AuthFun(ReqData, Context),
3741
{Res, Req2, {Mode, Context2}}.
3842

3943
delete_resource(ReqData, Context) ->
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
%% This Source Code Form is subject to the terms of the Mozilla Public
2+
%% License, v. 2.0. If a copy of the MPL was not distributed with this
3+
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
%%
5+
%% Copyright (c) 2007-2026 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
6+
%%
7+
8+
-module(auth_attempts_http_SUITE).
9+
10+
-include_lib("common_test/include/ct.hrl").
11+
-include_lib("eunit/include/eunit.hrl").
12+
-include_lib("rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl").
13+
14+
-import(rabbit_mgmt_test_util, [http_get/2, http_get/3, http_get/5,
15+
http_put/4,
16+
http_delete/3, http_delete/5]).
17+
18+
-compile(nowarn_export_all).
19+
-compile(export_all).
20+
21+
all() ->
22+
[{group, authorization}].
23+
24+
groups() ->
25+
[{authorization, [], [
26+
monitoring_user_can_read_auth_attempts,
27+
monitoring_user_cannot_delete_auth_attempts,
28+
admin_can_delete_auth_attempts
29+
]}].
30+
31+
init_per_group(_Group, Config) ->
32+
rabbit_ct_helpers:log_environment(),
33+
inets:start(),
34+
Config1 = rabbit_ct_helpers:set_config(Config, [{rmq_nodename_suffix, ?MODULE}]),
35+
rabbit_ct_helpers:run_setup_steps(
36+
Config1,
37+
rabbit_ct_broker_helpers:setup_steps() ++
38+
rabbit_ct_client_helpers:setup_steps()).
39+
40+
end_per_group(_Group, Config) ->
41+
inets:stop(),
42+
rabbit_ct_helpers:run_teardown_steps(
43+
Config,
44+
rabbit_ct_client_helpers:teardown_steps() ++
45+
rabbit_ct_broker_helpers:teardown_steps()).
46+
47+
init_per_testcase(Testcase, Config) ->
48+
rabbit_ct_helpers:testcase_started(Config, Testcase).
49+
50+
end_per_testcase(Testcase, Config) ->
51+
rabbit_ct_helpers:testcase_finished(Config, Testcase).
52+
53+
%% -------------------------------------------------------------------
54+
%% Test cases
55+
%% -------------------------------------------------------------------
56+
57+
monitoring_user_can_read_auth_attempts(Config) ->
58+
try
59+
http_put(Config, "/users/mon",
60+
#{password => <<"mon">>, tags => <<"monitoring">>},
61+
{group, '2xx'}),
62+
Node = node_name(Config),
63+
http_get(Config, "/auth/attempts/" ++ Node, "mon", "mon", ?OK),
64+
http_get(Config, "/auth/attempts/" ++ Node ++ "/source", "mon", "mon", ?OK)
65+
after
66+
catch http_delete(Config, "/users/mon", ?NO_CONTENT)
67+
end.
68+
69+
monitoring_user_cannot_delete_auth_attempts(Config) ->
70+
try
71+
http_put(Config, "/users/mon",
72+
#{password => <<"mon">>, tags => <<"monitoring">>},
73+
{group, '2xx'}),
74+
Node = node_name(Config),
75+
http_delete(Config, "/auth/attempts/" ++ Node, "mon", "mon", ?NOT_AUTHORISED),
76+
http_delete(Config, "/auth/attempts/" ++ Node ++ "/source", "mon", "mon", ?NOT_AUTHORISED)
77+
after
78+
catch http_delete(Config, "/users/mon", ?NO_CONTENT)
79+
end.
80+
81+
admin_can_delete_auth_attempts(Config) ->
82+
try
83+
http_put(Config, "/users/admin",
84+
#{password => <<"admin">>, tags => <<"administrator">>},
85+
{group, '2xx'}),
86+
Node = node_name(Config),
87+
http_delete(Config, "/auth/attempts/" ++ Node, "admin", "admin", ?NO_CONTENT),
88+
http_delete(Config, "/auth/attempts/" ++ Node ++ "/source", "admin", "admin", ?NO_CONTENT)
89+
after
90+
catch http_delete(Config, "/users/admin", ?NO_CONTENT)
91+
end.
92+
93+
%% -------------------------------------------------------------------
94+
95+
node_name(Config) ->
96+
[NodeData] = http_get(Config, "/nodes"),
97+
binary_to_list(maps:get(name, NodeData)).

0 commit comments

Comments
 (0)