rabbitmq-server/deps/rabbit/test/topic_permission_SUITE.erl

231 lines
9.8 KiB
Erlang

%% This Source Code Form is subject to the terms of the Mozilla Public
%% License, v. 2.0. If a copy of the MPL was not distributed with this
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
%%
%% Copyright (c) 2007-2024 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%%
-module(topic_permission_SUITE).
-include_lib("rabbit_common/include/rabbit.hrl").
-compile(export_all).
all() ->
[
{group, sequential_tests}
].
groups() -> [
{sequential_tests, [], [
topic_permission_database_access,
topic_permission_checks
]}
].
init_per_suite(Config) ->
rabbit_ct_helpers:log_environment(),
Config1 = rabbit_ct_helpers:set_config(Config, [
{rmq_nodename_suffix, ?MODULE}
]),
rabbit_ct_helpers:run_setup_steps(Config1,
rabbit_ct_broker_helpers:setup_steps() ++
rabbit_ct_client_helpers:setup_steps()).
end_per_suite(Config) ->
rabbit_ct_helpers:run_teardown_steps(Config,
rabbit_ct_client_helpers:teardown_steps() ++
rabbit_ct_broker_helpers:teardown_steps()).
init_per_group(_, Config) -> Config.
end_per_group(_, Config) -> Config.
init_per_testcase(Testcase, Config) ->
ok = rabbit_ct_broker_helpers:rpc(Config, 0,
?MODULE, clear_tables, []),
rabbit_ct_helpers:testcase_started(Config, Testcase).
clear_tables() ->
ok = rabbit_db_vhost:clear(),
ok = rabbit_db_user:clear().
end_per_testcase(Testcase, Config) ->
rabbit_ct_helpers:testcase_finished(Config, Testcase).
topic_permission_database_access(Config) ->
ok = rabbit_ct_broker_helpers:rpc(Config, 0,
?MODULE, topic_permission_database_access1, [Config]).
topic_permission_database_access1(_Config) ->
rabbit_vhost:add(<<"/">>, <<"acting-user">>),
rabbit_vhost:add(<<"other-vhost">>, <<"acting-user">>),
rabbit_auth_backend_internal:add_user(<<"guest">>, <<"guest">>, <<"acting-user">>),
rabbit_auth_backend_internal:add_user(<<"dummy">>, <<"dummy">>, <<"acting-user">>),
ok = rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"/">>, <<"amq.topic">>, "^a", "^a", <<"acting-user">>
),
1 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
0 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"dummy">>)),
1 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"/">>)),
0 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"other-vhost">>)),
1 = length(rabbit_auth_backend_internal:list_user_vhost_topic_permissions(<<"guest">>,<<"/">>)),
0 = length(rabbit_auth_backend_internal:list_user_vhost_topic_permissions(<<"guest">>,<<"other-vhost">>)),
1 = length(rabbit_auth_backend_internal:list_topic_permissions()),
rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"other-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
),
2 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
0 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"dummy">>)),
1 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"/">>)),
1 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"other-vhost">>)),
1 = length(rabbit_auth_backend_internal:list_user_vhost_topic_permissions(<<"guest">>,<<"/">>)),
1 = length(rabbit_auth_backend_internal:list_user_vhost_topic_permissions(<<"guest">>,<<"other-vhost">>)),
2 = length(rabbit_auth_backend_internal:list_topic_permissions()),
rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"/">>, <<"topic1">>, "^a", "^a", <<"acting-user">>
),
rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"/">>, <<"topic2">>, "^a", "^a", <<"acting-user">>
),
4 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
3 = length(rabbit_auth_backend_internal:list_user_vhost_topic_permissions(<<"guest">>,<<"/">>)),
1 = length(rabbit_auth_backend_internal:list_user_vhost_topic_permissions(<<"guest">>,<<"other-vhost">>)),
4 = length(rabbit_auth_backend_internal:list_topic_permissions()),
rabbit_auth_backend_internal:clear_topic_permissions(<<"guest">>, <<"other-vhost">>,
<<"acting-user">>),
0 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"other-vhost">>)),
3 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
rabbit_auth_backend_internal:clear_topic_permissions(<<"guest">>, <<"/">>, <<"topic1">>,
<<"acting-user">>),
2 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
rabbit_auth_backend_internal:clear_topic_permissions(<<"guest">>, <<"/">>,
<<"acting-user">>),
0 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
{error, {no_such_user, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
<<"non-existing-user">>, <<"other-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
)),
{error, {no_such_vhost, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"non-existing-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
)),
{error, {no_such_user, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
<<"non-existing-user">>, <<"non-existing-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
)),
{error, {no_such_user, _}} = (catch rabbit_auth_backend_internal:list_user_topic_permissions(
<<"non-existing-user">>
)),
{error, {no_such_vhost, _}} = (catch rabbit_auth_backend_internal:list_vhost_topic_permissions(
<<"non-existing-vhost">>
)),
{error, {invalid_regexp, _, _}} = (catch rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"/">>, <<"amq.topic">>, "[", "^a", <<"acting-user">>
)),
ok.
topic_permission_checks(Config) ->
ok = rabbit_ct_broker_helpers:rpc(Config, 0,
?MODULE, topic_permission_checks1, [Config]).
topic_permission_checks1(_Config) ->
rabbit_vhost:add(<<"/">>, <<"">>),
rabbit_vhost:add(<<"other-vhost">>, <<"">>),
rabbit_auth_backend_internal:add_user(<<"guest">>, <<"guest">>, <<"acting-user">>),
rabbit_auth_backend_internal:add_user(<<"dummy">>, <<"dummy">>, <<"acting-user">>),
rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"/">>, <<"amq.topic">>, "^a", "^a", <<"acting-user">>
),
1 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
0 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"dummy">>)),
1 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"/">>)),
0 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"other-vhost">>)),
rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"other-vhost">>, <<"amq.topic">>, ".*", ".*", <<"acting-user">>
),
2 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"guest">>)),
0 = length(rabbit_auth_backend_internal:list_user_topic_permissions(<<"dummy">>)),
1 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"/">>)),
1 = length(rabbit_auth_backend_internal:list_vhost_topic_permissions(<<"other-vhost">>)),
User = #auth_user{username = <<"guest">>},
Topic = #resource{name = <<"amq.topic">>, virtual_host = <<"/">>,
kind = topic},
Context = #{routing_key => <<"a.b.c">>},
Permissions = [write, read],
%% user has access to exchange, routing key matches
[true = rabbit_auth_backend_internal:check_topic_access(
User,
Topic,
Perm,
Context
) || Perm <- Permissions],
%% user has access to exchange, routing key does not match
[false = rabbit_auth_backend_internal:check_topic_access(
User,
Topic,
Perm,
#{routing_key => <<"x.y.z">>}
) || Perm <- Permissions],
%% user has access to exchange but not on this vhost
%% let pass when there's no match
[true = rabbit_auth_backend_internal:check_topic_access(
User,
Topic#resource{virtual_host = <<"fancyvhost">>},
Perm,
Context
) || Perm <- Permissions],
%% user does not have access to exchange
%% let pass when there's no match
[true = rabbit_auth_backend_internal:check_topic_access(
#auth_user{username = <<"dummy">>},
Topic,
Perm,
Context
) || Perm <- Permissions],
%% expand variables
rabbit_auth_backend_internal:set_topic_permissions(
<<"guest">>, <<"other-vhost">>, <<"amq.topic">>,
"services.{vhost}.accounts.{username}.notifications",
"services.{vhost}.accounts.{username}.notifications", <<"acting-user">>
),
%% routing key OK
[true = rabbit_auth_backend_internal:check_topic_access(
User,
Topic#resource{virtual_host = <<"other-vhost">>},
Perm,
#{routing_key => <<"services.other-vhost.accounts.guest.notifications">>,
variable_map => #{
<<"username">> => <<"guest">>,
<<"vhost">> => <<"other-vhost">>
}
}
) || Perm <- Permissions],
%% routing key KO
[false = rabbit_auth_backend_internal:check_topic_access(
User,
Topic#resource{virtual_host = <<"other-vhost">>},
Perm,
#{routing_key => <<"services.default.accounts.dummy.notifications">>,
variable_map => #{
<<"username">> => <<"guest">>,
<<"vhost">> => <<"other-vhost">>
}
}
) || Perm <- Permissions],
ok.