Merge branch 'main' into test-sac-with-priorities

This commit is contained in:
Michael Klishin 2025-06-02 23:48:36 +04:00 committed by GitHub
commit 8b7067d999
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 91 additions and 35 deletions

View File

@ -72,7 +72,7 @@ jobs:
docker build -t mocha-test --target test .
- name: Run Suites
id: run-suites
id: tests
run: |
IMAGE_TAG=$(find PACKAGES/rabbitmq-server-generic-unix-*.tar.xz | awk -F 'PACKAGES/rabbitmq-server-generic-unix-|.tar.xz' '{print $2}')
CONF_DIR_PREFIX="$(mktemp -d)" RABBITMQ_DOCKER_IMAGE=pivotalrabbitmq/rabbitmq:$IMAGE_TAG \
@ -83,7 +83,7 @@ jobs:
if: always()
uses: actions/upload-artifact@v4.3.2
env:
SELENIUM_ARTIFACTS: ${{ steps.run-suites.outputs.SELENIUM_ARTIFACTS }}
SELENIUM_ARTIFACTS: ${{ steps.tests.outputs.SELENIUM_ARTIFACTS }}
with:
name: test-artifacts-${{ matrix.browser }}-${{ matrix.erlang_version }}
path: |

View File

@ -57,6 +57,7 @@ jobs:
docker build -t mocha-test --target test .
- name: Run short UI suites on a standalone rabbitmq server
id: tests
run: |
IMAGE_TAG=$(find PACKAGES/rabbitmq-server-generic-unix-*.tar.xz | awk -F 'PACKAGES/rabbitmq-server-generic-unix-|.tar.xz' '{print $2}')
CONF_DIR_PREFIX="$(mktemp -d)" RABBITMQ_DOCKER_IMAGE=pivotalrabbitmq/rabbitmq:$IMAGE_TAG \
@ -67,7 +68,7 @@ jobs:
if: ${{ failure() && steps.tests.outcome == 'failed' }}
uses: actions/upload-artifact@v4
env:
SELENIUM_ARTIFACTS: ${{ steps.run-suites.outputs.SELENIUM_ARTIFACTS }}
SELENIUM_ARTIFACTS: ${{ steps.tests.outputs.SELENIUM_ARTIFACTS }}
with:
name: test-artifacts-${{ matrix.browser }}-${{ matrix.erlang_version }}
path: |

View File

@ -6254,18 +6254,10 @@ tcp_back_pressure_rabbitmq_internal_flow(QType, Config) ->
?assert(MsgsReady > 0),
?assert(MsgsReady < Num),
%% Use large buffers. This will considerably speed up receiving all messages (on Linux).
ok = inet:setopts(Socket, [{recbuf, 65536},
{buffer, 65536}]),
%% When we resume the receiving client, we expect to receive all messages.
?assert(meck:validate(Mod)),
ok = meck:unload(Mod),
ok = Mod:setopts(Socket, [{active, once}]),
receive_messages(Receiver, Num),
ok = detach_link_sync(Receiver),
{ok, #{message_count := 0}} = rabbitmq_amqp_client:delete_queue(LinkPair, QName),
ok = close({Connection, Session, LinkPair}).
%% Rely on end_per_testcase/2 to delete the queue and to close the connection.
ok.
session_flow_control_default_max_frame_size(Config) ->
QName = atom_to_binary(?FUNCTION_NAME),

View File

@ -87,11 +87,8 @@ user_login_authorization(Username, AuthProps) ->
check_vhost_access(#auth_user{impl = DecodedTokenFun},
VHost, _AuthzData) ->
with_decoded_token(DecodedTokenFun(),
fun(_Token) ->
DecodedToken = DecodedTokenFun(),
Scopes = get_scope(DecodedToken),
ScopeString = rabbit_oauth2_scope:concat_scopes(Scopes, ","),
rabbit_log:debug("Matching virtual host '~ts' against the following scopes: ~ts", [VHost, ScopeString]),
fun(Token) ->
Scopes = get_expanded_scopes(Token, #resource{virtual_host = VHost}),
rabbit_oauth2_scope:vhost_access(VHost, Scopes)
end).
@ -99,7 +96,7 @@ check_resource_access(#auth_user{impl = DecodedTokenFun},
Resource, Permission, _AuthzContext) ->
with_decoded_token(DecodedTokenFun(),
fun(Token) ->
Scopes = get_scope(Token),
Scopes = get_expanded_scopes(Token, Resource),
rabbit_oauth2_scope:resource_access(Resource, Permission, Scopes)
end).

View File

@ -41,6 +41,7 @@ resource_access(#resource{virtual_host = VHost, name = Name},
end,
get_scope_permissions(Scopes)).
-spec topic_access(rabbit_types:r(atom()), permission(), map(), [binary()]) -> boolean().
topic_access(#resource{virtual_host = VHost, name = ExchangeName},
Permission,
#{routing_key := RoutingKey},

View File

@ -117,6 +117,8 @@ fixture_token() ->
token_with_sub(TokenFixture, Sub) ->
maps:put(<<"sub">>, Sub, TokenFixture).
token_with_claim(TokenFixture, Name, Value) ->
maps:put(Name, Value, TokenFixture).
token_with_scopes(TokenFixture, Scopes) ->
maps:put(<<"scope">>, Scopes, TokenFixture).

View File

@ -35,6 +35,7 @@ groups() ->
test_successful_connection_with_a_full_permission_token_and_all_defaults,
test_successful_connection_with_a_full_permission_token_and_explicitly_configured_vhost,
test_successful_connection_with_simple_strings_for_aud_and_scope,
test_successful_connection_with_variable_expansion_on_queue_access,
test_successful_token_refresh,
test_successful_connection_without_verify_aud,
mqtt
@ -42,6 +43,7 @@ groups() ->
{basic_unhappy_path, [], [
test_failed_connection_with_expired_token,
test_failed_connection_with_a_non_token,
test_failed_connection_with_a_token_with_variable_expansion,
test_failed_connection_with_a_token_with_insufficient_vhost_permission,
test_failed_connection_with_a_token_with_insufficient_resource_permission,
more_than_one_resource_server_id_not_allowed_in_one_token,
@ -134,7 +136,8 @@ end_per_group(_Group, Config) ->
%%
init_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_a_full_permission_token_and_explicitly_configured_vhost orelse
Testcase =:= test_successful_token_refresh ->
Testcase =:= test_successful_token_refresh orelse
Testcase =:= test_successful_connection_with_variable_expansion_on_queue_access ->
rabbit_ct_broker_helpers:add_vhost(Config, <<"vhost1">>),
rabbit_ct_helpers:testcase_started(Config, Testcase),
Config;
@ -420,6 +423,19 @@ test_successful_connection_with_simple_strings_for_aud_and_scope(Config) ->
amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
close_connection_and_channel(Conn, Ch).
test_successful_connection_with_variable_expansion_on_queue_access(Config) ->
{_Algo, Token} = generate_valid_token(
Config,
<<"rabbitmq.configure:*/{vhost}-{sub}-* rabbitmq.write:*/* rabbitmq.read:*/*">>,
[<<"hare">>, <<"rabbitmq">>],
<<"Bob">>
),
Conn = open_unmanaged_connection(Config, 0, <<"vhost1">>, <<"Bob">>, Token),
{ok, Ch} = amqp_connection:open_channel(Conn),
#'queue.declare_ok'{} =
amqp_channel:call(Ch, #'queue.declare'{queue = <<"vhost1-Bob-1">>, exclusive = true}),
close_connection_and_channel(Conn, Ch).
test_successful_connection_without_verify_aud(Config) ->
{_Algo, Token} = generate_valid_token(
Config,
@ -895,6 +911,18 @@ test_failed_connection_with_a_token_with_insufficient_vhost_permission(Config) -
?assertEqual({error, not_allowed},
open_unmanaged_connection(Config, 0, <<"off-limits-vhost">>, <<"username">>, Token)).
test_failed_connection_with_a_token_with_variable_expansion(Config) ->
{_Algo, Token} = generate_valid_token(
Config,
<<"rabbitmq.configure:*/{vhost}-{sub}-* rabbitmq.write:*/* rabbitmq.read:*/*">>,
[<<"hare">>, <<"rabbitmq">>]
),
Conn = open_unmanaged_connection(Config, 0, <<"vhost2">>, <<"username">>, Token),
{ok, Ch} = amqp_connection:open_channel(Conn),
?assertExit({{shutdown, {server_initiated_close, 403, _}}, _},
amqp_channel:call(Ch, #'queue.declare'{queue = <<"vhost1-username-3">>, exclusive = true})),
close_connection(Conn).
test_failed_connection_with_a_token_with_insufficient_resource_permission(Config) ->
{_Algo, Token} = generate_valid_token(Config, [<<"rabbitmq.configure:vhost2/jwt*">>,
<<"rabbitmq.write:vhost2/jwt*">>,

View File

@ -49,7 +49,8 @@ all() ->
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_scope_field,
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_extra_scope_source_field,
test_username_from,
{group, with_rabbitmq_node}
{group, with_rabbitmq_node},
{group, with_resource_server_id}
].
groups() ->
@ -62,11 +63,11 @@ groups() ->
},
{with_resource_server_id, [], [
test_successful_access_with_a_token,
test_validate_payload_resource_server_id_mismatch,
test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field,
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_field,
test_successful_authorization_without_scopes,
test_successful_authentication_without_scopes,
test_successful_access_with_a_token_that_uses_single_scope_alias_with_var_expansion,
test_successful_access_with_a_token_that_uses_single_scope_alias_in_extra_scope_source_field,
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_scope_source_field,
normalize_token_scope_with_additional_scopes_complex_claims,
@ -634,7 +635,7 @@ normalize_token_scope_with_additional_scopes_complex_claims(_) ->
<<"rabbitmq3">> =>
[<<"rabbitmq-resource.write:*/*">>,
<<"rabbitmq-resource-write">>]},
[<<"read:*/*">>, <<"rabbitmq.rabbitmq-resource-read">>]
[<<"read:*/*">>]
},
{
"claims are map with list content - empty result",
@ -647,7 +648,7 @@ normalize_token_scope_with_additional_scopes_complex_claims(_) ->
"claims are map with binary content",
#{ <<"rabbitmq">> => <<"rabbitmq-resource.read:*/* rabbitmq-resource-read">>,
<<"rabbitmq3">> => <<"rabbitmq-resource.write:*/* rabbitmq-resource-write">>},
[<<"rabbitmq.rabbitmq-resource.read:*/*">>, <<"rabbitmq.rabbitmq-resource-read">>]
[<<"read:*/*">>]
},
{
"claims are map with binary content - empty result",
@ -777,6 +778,45 @@ test_successful_access_with_a_token_that_has_tag_scopes(_) ->
{ok, #auth_user{username = Username, tags = [management, policymaker]}} =
user_login_authentication(Username, [{password, Token}]).
test_successful_access_with_a_token_that_uses_single_scope_alias_with_var_expansion(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(),
UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}],
set_env(key_config, UaaEnv),
Alias = <<"client-alias-1">>,
set_env(scope_aliases, #{
Alias => [
<<"rabbitmq.configure:{vhost}/q-{sub}/rk-{client_id}**">>
]
}),
VHost = <<"vhost">>,
Username = <<"bob">>,
ClientId = <<"rmq">>,
Token = ?UTIL_MOD:sign_token_hs(?UTIL_MOD:token_with_sub(
?UTIL_MOD:token_with_claim(
?UTIL_MOD:token_with_scope_alias_in_scope_field(Alias), <<"client_id">>, ClientId),
Username), Jwk),
{ok, #auth_user{username = Username} = AuthUser} =
user_login_authentication(Username, [{password, Token}]),
%% vhost access
assert_vhost_access_granted(AuthUser, ClientId),
%% resource access
assert_resource_access_denied(AuthUser, VHost, <<"none">>, read),
assert_resource_access_granted(AuthUser, VHost, <<"q-bob">>, configure),
%% topic access
assert_topic_access_refused(AuthUser, VHost, <<"q-bob">>, configure,
#{routing_key => <<"rk-r2mq/#">>}),
assert_topic_access_granted(AuthUser, VHost, <<"q-bob">>, configure,
#{routing_key => <<"rk-rmq/#">>}),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(),
UaaEnv = [{signing_keys, #{<<"token-key">> => {map, Jwk}}}],
@ -813,8 +853,7 @@ test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field(
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config),
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field_and_custom_scope_prefix(_) ->
@ -855,8 +894,7 @@ test_successful_access_with_a_token_that_uses_single_scope_alias_in_scope_field_
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_prefix),
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
application:unset_env(rabbitmq_auth_backend_oauth2, scope_prefix).
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(),
@ -901,8 +939,7 @@ test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_scope_fi
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config),
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_scope_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(),
@ -976,8 +1013,7 @@ test_successful_access_with_a_token_that_uses_single_scope_alias_in_extra_scope_
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config),
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_scope_source_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(),
@ -1021,8 +1057,7 @@ test_successful_access_with_a_token_that_uses_multiple_scope_aliases_in_extra_sc
assert_resource_access_denied(AuthUser, VHost, <<"three">>, write),
application:unset_env(rabbitmq_auth_backend_oauth2, scope_aliases),
application:unset_env(rabbitmq_auth_backend_oauth2, key_config),
application:unset_env(rabbitmq_auth_backend_oauth2, resource_server_id).
application:unset_env(rabbitmq_auth_backend_oauth2, key_config).
test_unsuccessful_access_with_a_token_that_uses_missing_scope_alias_in_extra_scope_source_field(_) ->
Jwk = ?UTIL_MOD:fixture_jwk(),

View File

@ -16,7 +16,6 @@
-export([init/1]).
start(_Type, _StartArgs) ->
?FEDERATION_ETS = ets:new(?FEDERATION_ETS, [set, public, named_table]),
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
stop(_State) ->

View File

@ -45,6 +45,7 @@ stop() ->
%%----------------------------------------------------------------------------
init([]) ->
?FEDERATION_ETS = ets:new(?FEDERATION_ETS, [set, public, named_table]),
Status = #{
id => status,
start => {rabbit_federation_status, start_link, []},