Skip to content

Commit 860bfb4

Browse files
Add missing system test
Verify opaque tokens
1 parent d7ff7bf commit 860bfb4

File tree

2 files changed

+153
-46
lines changed

2 files changed

+153
-46
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
-module(introspect_http_handler).
2+
-behavior(cowboy_handler).
3+
4+
-export([init/2, terminate/3]).
5+
6+
init(Req, State) ->
7+
ct:log("introspect_http_handler init : ~p", [Req]),
8+
case cowboy_req:read_urlencoded_body(Req) of
9+
{ok, KeyValues, _Req} ->
10+
ct:log("introspect_http_handler responding with active token: ~p", [KeyValues]),
11+
case proplists:get_value(<<"token">>, KeyValues) of
12+
<<"401">> ->
13+
{ok, cowboy_req:reply(401, #{}, [], Req), State};
14+
<<"active">> ->
15+
Body = rabbit_json:encode([{"active", true}, {"scope", "rabbitmq.configure:*/* rabbitmq.write:*/* rabbitmq.read:*/*"}]),
16+
{ok, cowboy_req:reply(200, #{<<"content-type">> => <<"application/json">>},
17+
Body, Req), State};
18+
<<"inactive">> ->
19+
Body = rabbit_json:encode([{"active", false}, {"scope", "rabbitmq.configure:*/* rabbitmq.write:*/* rabbitmq.read:*/*"}]),
20+
{ok, cowboy_req:reply(200, #{<<"content-type">> => <<"application/json">>},
21+
Body, Req), State}
22+
end;
23+
Other ->
24+
ct:log("introspect_http_handler responding with 401 : ~p", [Other]),
25+
{ok, cowboy_req:reply(401, #{}, [], Req), State}
26+
end.
27+
28+
terminate(_Reason, _Req, _State) ->
29+
ok.

deps/rabbitmq_auth_backend_oauth2/test/system_SUITE.erl

Lines changed: 124 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ all() ->
2626
{group, token_refresh},
2727
{group, extra_scopes_source},
2828
{group, scope_aliases},
29-
{group, rich_authorization_requests}
29+
{group, rich_authorization_requests},
30+
{group, with_introspection_endpoint}
3031
].
3132

3233
groups() ->
@@ -83,6 +84,10 @@ groups() ->
8384
amqp_token_refresh_expire,
8485
amqp_token_refresh_vhost_permission,
8586
amqp_token_refresh_revoked_permissions
87+
]},
88+
{with_introspection_endpoint, [], [
89+
test_successful_connection_with_valid_opaque_token,
90+
test_unsuccessful_connection_with_invalid_opaque_token
8691
]}
8792
].
8893

@@ -113,6 +118,27 @@ end_per_suite(Config) ->
113118
init_per_group(amqp, Config) ->
114119
{ok, _} = application:ensure_all_started(rabbitmq_amqp_client),
115120
Config;
121+
init_per_group(with_introspection_endpoint, Config) ->
122+
{ok, _} = application:ensure_all_started(ssl),
123+
{ok, _} = application:ensure_all_started(cowboy),
124+
125+
PortBase = rabbit_ct_broker_helpers:get_node_config(Config, 0, tcp_ports_base),
126+
Port = PortBase + 100,
127+
AuthorizationServerURL = uri_string:normalize(#{
128+
scheme => "https",port => Port,path => "/introspect",host => "localhost"}),
129+
130+
CertsDir = ?config(rmq_certsdir, Config),
131+
Endpoints = [ {"/introspect", introspect_http_handler, []}],
132+
Dispatch = cowboy_router:compile([{'_', Endpoints}]),
133+
{ok, _} = cowboy:start_tls(introspection_http_listener,
134+
[{port, Port},
135+
{certfile, filename:join([CertsDir, "server", "cert.pem"])},
136+
{keyfile, filename:join([CertsDir, "server", "key.pem"])}],
137+
#{env => #{dispatch => Dispatch}}),
138+
139+
[ {authorization_server_url, AuthorizationServerURL},
140+
{authorization_server_ca_cert, filename:join([CertsDir, "testca", "cacert.pem"])} | Config];
141+
116142
init_per_group(_Group, Config) ->
117143
%% The broker is managed by {init,end}_per_testcase().
118144
lists:foreach(fun(Value) ->
@@ -123,6 +149,12 @@ init_per_group(_Group, Config) ->
123149

124150
end_per_group(amqp, Config) ->
125151
Config;
152+
153+
end_per_group(with_introspection_endpoint, Config) ->
154+
ok = cowboy:stop_listener(introspection_http_listener),
155+
inets:stop(),
156+
Config;
157+
126158
end_per_group(_Group, Config) ->
127159
%% The broker is managed by {init,end}_per_testcase().
128160
lists:foreach(fun(Value) ->
@@ -131,6 +163,33 @@ end_per_group(_Group, Config) ->
131163
[<<"vhost1">>, <<"vhost2">>, <<"vhost3">>, <<"vhost4">>]),
132164
Config.
133165

166+
setup_introspection_configuration(Config) ->
167+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
168+
[rabbitmq_auth_backend_oauth2, introspection_endpoint,
169+
?config(authorization_server_url, Config)]),
170+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
171+
[rabbitmq_auth_backend_oauth2, introspection_client_id, "some-id"]),
172+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
173+
[rabbitmq_auth_backend_oauth2, introspection_client_secret, "some-secret"]),
174+
CaCertFile = ?config(authorization_server_ca_cert, Config),
175+
176+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
177+
[rabbitmq_auth_backend_oauth2, key_config, [{cacertfile, CaCertFile}]]),
178+
179+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
180+
[rabbitmq_auth_backend_oauth2, opaque_token_signing_key,
181+
[{id, <<"rabbit_key">>}, {type, hs256}, {key, <<"some-key">>}]]),
182+
Config.
183+
184+
teardown_introspection_configuration(Config) ->
185+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
186+
[rabbitmq_auth_backend_oauth2, introspection_endpoint]),
187+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
188+
[rabbitmq_auth_backend_oauth2, introspection_client_id]),
189+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
190+
[rabbitmq_auth_backend_oauth2, introspection_client_secret]),
191+
Config.
192+
134193
%%
135194
%% Per-case setup
136195
%%
@@ -234,22 +293,25 @@ init_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection
234293
Config;
235294

236295
init_per_testcase(multiple_resource_server_ids, Config) ->
237-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
238-
[rabbitmq_auth_backend_oauth2, scope_prefix, <<"rmq.">> ]),
239-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
240-
[rabbitmq_auth_backend_oauth2, resource_servers, #{
241-
<<"prod">> => [ ],
242-
<<"dev">> => [ ]
243-
}]),
244-
rabbit_ct_helpers:testcase_started(Config, multiple_resource_server_ids),
245-
Config;
296+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
297+
[rabbitmq_auth_backend_oauth2, scope_prefix, <<"rmq.">> ]),
298+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, set_env,
299+
[rabbitmq_auth_backend_oauth2, resource_servers, #{
300+
<<"prod">> => [ ],
301+
<<"dev">> => [ ]
302+
}]),
303+
rabbit_ct_helpers:testcase_started(Config, multiple_resource_server_ids),
304+
Config;
305+
306+
init_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_valid_opaque_token ->
307+
rabbit_ct_helpers:testcase_started(
308+
setup_introspection_configuration(Config), Testcase);
246309

247310
init_per_testcase(Testcase, Config) ->
248311
rabbit_ct_helpers:testcase_started(Config, Testcase),
249312
Config.
250313

251314

252-
253315
%%
254316
%% Per-case Teardown
255317
%%
@@ -263,52 +325,55 @@ end_per_testcase(Testcase, Config) when Testcase =:= test_failed_token_refresh_c
263325
end_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_complex_claim_as_a_map orelse
264326
Testcase =:= test_successful_connection_with_complex_claim_as_a_list orelse
265327
Testcase =:= test_successful_connection_with_complex_claim_as_a_binary ->
266-
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost1">>),
267-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
268-
[rabbitmq_auth_backend_oauth2, extra_scopes_source]),
269-
rabbit_ct_helpers:testcase_finished(Config, Testcase),
270-
Config;
328+
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost1">>),
329+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
330+
[rabbitmq_auth_backend_oauth2, extra_scopes_source]),
331+
rabbit_ct_helpers:testcase_finished(Config, Testcase),
332+
Config;
271333

272334
end_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_with_single_scope_alias_in_extra_scopes_source ->
273-
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost1">>),
274-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
275-
[rabbitmq_auth_backend_oauth2, scope_aliases]),
276-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
277-
[rabbitmq_auth_backend_oauth2, extra_scopes_source]),
278-
rabbit_ct_helpers:testcase_finished(Config, Testcase),
279-
Config;
335+
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost1">>),
336+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
337+
[rabbitmq_auth_backend_oauth2, scope_aliases]),
338+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
339+
[rabbitmq_auth_backend_oauth2, extra_scopes_source]),
340+
rabbit_ct_helpers:testcase_finished(Config, Testcase),
341+
Config;
280342

281343
end_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_with_multiple_scope_aliases_in_extra_scopes_source ->
282-
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost4">>),
283-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
284-
[rabbitmq_auth_backend_oauth2, scope_aliases]),
285-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
286-
[rabbitmq_auth_backend_oauth2, extra_scopes_source]),
287-
rabbit_ct_helpers:testcase_finished(Config, Testcase),
288-
Config;
344+
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost4">>),
345+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
346+
[rabbitmq_auth_backend_oauth2, scope_aliases]),
347+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
348+
[rabbitmq_auth_backend_oauth2, extra_scopes_source]),
349+
rabbit_ct_helpers:testcase_finished(Config, Testcase),
350+
Config;
289351

290352
end_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_scope_alias_in_scope_field_case1 orelse
291353
Testcase =:= test_successful_connection_with_scope_alias_in_scope_field_case2 ->
292-
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost2">>),
293-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
294-
[rabbitmq_auth_backend_oauth2, scope_aliases]),
295-
rabbit_ct_helpers:testcase_finished(Config, Testcase),
296-
Config;
354+
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost2">>),
355+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
356+
[rabbitmq_auth_backend_oauth2, scope_aliases]),
357+
rabbit_ct_helpers:testcase_finished(Config, Testcase),
358+
Config;
297359

298360
end_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_scope_alias_in_scope_field_case3 ->
299-
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost3">>),
300-
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
301-
[rabbitmq_auth_backend_oauth2, scope_aliases]),
302-
rabbit_ct_helpers:testcase_finished(Config, Testcase),
303-
Config;
361+
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost3">>),
362+
ok = rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
363+
[rabbitmq_auth_backend_oauth2, scope_aliases]),
364+
rabbit_ct_helpers:testcase_finished(Config, Testcase),
365+
Config;
304366

305367
end_per_testcase(multiple_resource_server_ids, Config) ->
306-
rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
307-
[rabbitmq_auth_backend_oauth2, scope_prefix ]),
308-
rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
309-
[rabbitmq_auth_backend_oauth2, resource_servers ]),
310-
rabbit_ct_helpers:testcase_started(Config, multiple_resource_server_ids),
311-
Config;
368+
rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
369+
[rabbitmq_auth_backend_oauth2, scope_prefix ]),
370+
rabbit_ct_broker_helpers:rpc(Config, 0, application, unset_env,
371+
[rabbitmq_auth_backend_oauth2, resource_servers ]),
372+
rabbit_ct_helpers:testcase_started(Config, multiple_resource_server_ids),
373+
Config;
374+
375+
end_per_testcase(Testcase, Config) when Testcase =:= test_successful_connection_with_valid_opaque_token ->
376+
teardown_introspection_configuration(Config);
312377

313378
end_per_testcase(Testcase, Config) ->
314379
rabbit_ct_broker_helpers:delete_vhost(Config, <<"vhost1">>),
@@ -448,6 +513,18 @@ test_successful_connection_without_verify_aud(Config) ->
448513
amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
449514
close_connection_and_channel(Conn, Ch).
450515

516+
test_successful_connection_with_valid_opaque_token(Config) ->
517+
Conn = open_unmanaged_connection(Config, 0, <<"username">>, <<"active">>),
518+
{ok, Ch} = amqp_connection:open_channel(Conn),
519+
#'queue.declare_ok'{queue = _} =
520+
amqp_channel:call(Ch, #'queue.declare'{exclusive = true}),
521+
close_connection_and_channel(Conn, Ch).
522+
523+
test_unsuccessful_connection_with_invalid_opaque_token(Config) ->
524+
{error, Error} = open_unmanaged_connection(Config, 0, <<"username">>, <<"inactive">>),
525+
ct:log("Error : ~p", [Error]).
526+
527+
451528
mqtt(Config) ->
452529
Topic = <<"test/topic">>,
453530
Payload = <<"mqtt-test-message">>,
@@ -1062,3 +1139,4 @@ flush(Prefix) ->
10621139
after 1 ->
10631140
ok
10641141
end.
1142+

0 commit comments

Comments
 (0)