Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ansd committed Oct 29, 2024
1 parent dcb6f98 commit 88fad63
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 21 deletions.
21 changes: 20 additions & 1 deletion deps/rabbitmq_amqp_client/src/rabbitmq_amqp_client.erl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
declare_exchange/3,
bind_exchange/5,
unbind_exchange/5,
delete_exchange/2
delete_exchange/2,

set_token/2
].

-define(TIMEOUT, 20_000).
Expand Down Expand Up @@ -381,6 +383,23 @@ delete_exchange(LinkPair, ExchangeName) ->
Err
end.

%% Renew OAuth 2.0 token.
-spec set_token(link_pair(), binary()) ->
ok | {error, term()}.
set_token(LinkPair, Token) ->
Props = #{subject => <<"PUT">>,
to => <<"/auth/tokens">>},
Body = {binary, Token},
case request(LinkPair, Props, Body) of
{ok, Resp} ->
case is_success(Resp) of
true -> ok;
false -> {error, Resp}
end;
Err ->
Err
end.

-spec request(link_pair(), amqp10_msg:amqp10_properties(), amqp10_prim()) ->
{ok, Response :: amqp10_msg:amqp10_msg()} | {error, term()}.
request(#link_pair{session = Session,
Expand Down
100 changes: 80 additions & 20 deletions deps/rabbitmq_auth_backend_oauth2/test/system_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ groups() ->
more_than_one_resource_server_id_not_allowed_in_one_token,
mqtt_expired_token,
mqtt_expirable_token,
web_mqtt_expirable_token,
amqp_expirable_token
web_mqtt_expirable_token
]},

{token_refresh, [], [
Expand All @@ -73,7 +72,18 @@ groups() ->
]},
{rich_authorization_requests, [], [
test_successful_connection_with_rich_authorization_request_token
]}
]},
{amqp, [shuffle],
[
amqp_token_expire,
amqp_token_refresh,
amqp_token_refresh_vhost_permission,
amqp_token_refresh_exchange_write_permission,
amqp_token_refresh_queue_read_permission,
amqp_token_refresh_anon_term_exchange_write_permission,
amqp_token_refresh_topic_write_permission,
amqp_token_refresh_expire
]}
].

%%
Expand All @@ -100,7 +110,9 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
rabbit_ct_helpers:run_teardown_steps(Config, rabbit_ct_broker_helpers:teardown_steps()).


init_per_group(amqp, Config) ->
{ok, _} = application:ensure_all_started(rabbitmq_amqp_client),
Config;
init_per_group(_Group, Config) ->
%% The broker is managed by {init,end}_per_testcase().
lists:foreach(fun(Value) ->
Expand All @@ -109,6 +121,8 @@ init_per_group(_Group, Config) ->
[<<"vhost1">>, <<"vhost2">>, <<"vhost3">>, <<"vhost4">>]),
Config.

end_per_group(amqp, Config) ->
Config;
end_per_group(_Group, Config) ->
%% The broker is managed by {init,end}_per_testcase().
lists:foreach(fun(Value) ->
Expand Down Expand Up @@ -500,29 +514,20 @@ mqtt_expirable_token0(Port, AdditionalOpts, Connect, Config) ->
after Millis * 2 -> ct:fail("missing DISCONNECT packet from server")
end.

amqp_expirable_token(Config) ->
{ok, _} = application:ensure_all_started(rabbitmq_amqp_client),

%% Test that RabbitMQ closes the AMQP 1.0 connection when the token expires.
amqp_token_expire(Config) ->
Seconds = 4,
Millis = Seconds * 1000,
{_Algo, Token} = generate_expirable_token(Config,
[<<"rabbitmq.configure:*/*">>,
<<"rabbitmq.write:*/*">>,
<<"rabbitmq.read:*/*">>],
[<<"rabbitmq.configure:%2F/*">>,
<<"rabbitmq.write:%2F/*">>,
<<"rabbitmq.read:%2F/*">>],
Seconds),

%% Send and receive a message via AMQP 1.0.
%% Send and receive a message.
{Connection, Session, LinkPair} = amqp_init(Token, Config),
QName = atom_to_binary(?FUNCTION_NAME),
Address = rabbitmq_amqp_address:queue(QName),
Host = ?config(rmq_hostname, Config),
Port = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp),
OpnConf = #{address => Host,
port => Port,
container_id => <<"my container">>,
sasl => {plain, <<"">>, Token}},
{ok, Connection} = amqp10_client:open_connection(OpnConf),
{ok, Session} = amqp10_client:begin_session_sync(Connection),
{ok, LinkPair} = rabbitmq_amqp_client:attach_management_link_pair_sync(Session, <<"my link pair">>),
{ok, _} = rabbitmq_amqp_client:declare_queue(LinkPair, QName, #{}),
{ok, Sender} = amqp10_client:attach_sender_link(Session, <<"my sender">>, Address),
receive {amqp10_event, {link, Sender, credited}} -> ok
Expand All @@ -544,6 +549,43 @@ amqp_expirable_token(Config) ->
ct:fail("server did not close our connection")
end.

amqp_token_refresh(Config) ->
ok.

%% Test that RabbitMQ closes the AMQP 1.0 connection if the client
%% submits a new token without any permission to the vhost.
amqp_token_refresh_vhost_permission(Config) ->
{_Algo, Token1} = generate_valid_token(Config),
{Connection, Session, LinkPair} = amqp_init(Token1, Config),

{_Algo, Token2} = generate_valid_token(Config,
[<<"rabbitmq.configure:wrongvhost/*">>,
<<"rabbitmq.write:wrongvhost/*">>,
<<"rabbitmq.read:wrongvhost/*">>]),
ok = rabbitmq_amqp_client:set_token(LinkPair, Token2),
receive {amqp10_event,
{connection, Connection,
{closed, {unauthorized_access, Reason}}}} ->
?assertMatch(<<"access to vhost / failed for new credential:", _/binary>>,
Reason)
after 5000 -> ct:fail({missing_event, ?LINE})
end.

amqp_token_refresh_exchange_write_permission(Config) ->
ok.

amqp_token_refresh_queue_read_permission(Config) ->
ok.

amqp_token_refresh_anon_term_exchange_write_permission(Config) ->
ok.

amqp_token_refresh_topic_write_permission(Config) ->
ok.

amqp_token_refresh_expire(Config) ->
ok.

test_successful_connection_with_complex_claim_as_a_map(Config) ->
{_Algo, Token} = generate_valid_token_with_extra_fields(
Config,
Expand Down Expand Up @@ -765,3 +807,21 @@ test_failed_connection_with_non_existent_scope_alias_in_scope_field(Config) ->
more_than_one_resource_server_id_not_allowed_in_one_token(Config) ->
{_Algo, Token} = generate_valid_token(Config, <<"rmq.configure:*/*">>, [<<"prod">>, <<"dev">>]),
{error, _} = open_unmanaged_connection(Config, 0, <<"username">>, Token).

amqp_init(Token, Config) ->
OpnConf = amqp_connection_config(Token, Config),
{ok, Connection} = amqp10_client:open_connection(OpnConf),
receive {amqp10_event, {connection, Connection, opened}} -> ok
after 5000 -> ct:fail({missing_event, ?LINE})
end,
{ok, Session} = amqp10_client:begin_session_sync(Connection),
{ok, LinkPair} = rabbitmq_amqp_client:attach_management_link_pair_sync(Session, <<"my link pair">>),
{Connection, Session, LinkPair}.

amqp_connection_config(Token, Config) ->
Host = proplists:get_value(rmq_hostname, Config),
Port = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_port_amqp),
#{address => Host,
port => Port,
container_id => <<"my container">>,
sasl => {plain, <<>>, Token}}.

0 comments on commit 88fad63

Please sign in to comment.