Skip to content

Commit ecac15f

Browse files
Modify management schema
to be able to set extra parameters for authorize and token endpoints
1 parent 19f3b03 commit ecac15f

File tree

12 files changed

+259
-109
lines changed

12 files changed

+259
-109
lines changed

deps/oauth2_client/include/types.hrl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
-record(access_token_request, {
3838
client_id :: string() | binary(),
3939
client_secret :: string() | binary(),
40-
scope :: string() | binary() | undefined,
40+
scope :: option(string() | binary()),
41+
extra_parameters :: option(query_list()),
4142
timeout :: option(integer())
4243
}).
4344

deps/oauth2_client/src/oauth2_client.erl

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -470,33 +470,50 @@ ensure_oauth_provider_has_id_property(OAuth2ProviderId, OAuth2Provider) ->
470470
end.
471471

472472
build_access_token_request_body(Request) ->
473-
uri_string:compose_query([
474-
grant_type_request_parameter(?CLIENT_CREDENTIALS_GRANT_TYPE),
475-
client_id_request_parameter(Request#access_token_request.client_id),
476-
client_secret_request_parameter(Request#access_token_request.client_secret)]
477-
++ scope_request_parameter_or_default(Request#access_token_request.scope, [])).
473+
uri_string:compose_query(
474+
append_extra_parameters(Request,
475+
append_scope_request_parameter(Request#access_token_request.scope, [
476+
grant_type_request_parameter(?CLIENT_CREDENTIALS_GRANT_TYPE),
477+
client_id_request_parameter(
478+
Request#access_token_request.client_id),
479+
client_secret_request_parameter(
480+
Request#access_token_request.client_secret)]))).
478481

479482
build_refresh_token_request_body(Request) ->
480-
uri_string:compose_query([
481-
grant_type_request_parameter(?REFRESH_TOKEN_GRANT_TYPE),
482-
refresh_token_request_parameter(Request#refresh_token_request.refresh_token),
483-
client_id_request_parameter(Request#refresh_token_request.client_id),
484-
client_secret_request_parameter(Request#refresh_token_request.client_secret)]
485-
++ scope_request_parameter_or_default(Request#refresh_token_request.scope, [])).
483+
uri_string:compose_query(
484+
append_scope_request_parameter(Request#refresh_token_request.scope, [
485+
grant_type_request_parameter(?REFRESH_TOKEN_GRANT_TYPE),
486+
refresh_token_request_parameter(Request),
487+
client_id_request_parameter(Request#refresh_token_request.client_id),
488+
client_secret_request_parameter(
489+
Request#refresh_token_request.client_secret)])).
486490

487491
grant_type_request_parameter(Type) ->
488492
{?REQUEST_GRANT_TYPE, Type}.
489-
client_id_request_parameter(Client_id) ->
490-
{?REQUEST_CLIENT_ID, binary_to_list(Client_id)}.
491-
client_secret_request_parameter(Client_secret) ->
492-
{?REQUEST_CLIENT_SECRET, binary_to_list(Client_secret)}.
493-
refresh_token_request_parameter(RefreshToken) ->
494-
{?REQUEST_REFRESH_TOKEN, RefreshToken}.
495-
scope_request_parameter_or_default(Scope, Default) ->
493+
494+
client_id_request_parameter(ClientId) ->
495+
{?REQUEST_CLIENT_ID,
496+
binary_to_list(ClientId)}.
497+
498+
client_secret_request_parameter(ClientSecret) ->
499+
{?REQUEST_CLIENT_SECRET,
500+
binary_to_list(ClientSecret)}.
501+
502+
refresh_token_request_parameter(Request) ->
503+
{?REQUEST_REFRESH_TOKEN, Request#refresh_token_request.refresh_token}.
504+
505+
append_scope_request_parameter(Scope, QueryList) ->
496506
case Scope of
497-
undefined -> Default;
498-
<<>> -> Default;
499-
Scope -> [{?REQUEST_SCOPE, Scope}]
507+
undefined -> QueryList;
508+
<<>> -> QueryList;
509+
Scope -> [{?REQUEST_SCOPE, Scope} | QueryList]
510+
end.
511+
512+
append_extra_parameters(Request, QueryList) ->
513+
case Request#access_token_request.extra_parameters of
514+
undefined -> QueryList;
515+
[] -> QueryList;
516+
Params -> Params ++ QueryList
500517
end.
501518

502519
get_ssl_options_if_any(OAuthProvider) ->

deps/oauth2_client/test/system_SUITE.erl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ all() ->
3333

3434
groups() ->
3535
[
36+
3637
{with_all_oauth_provider_settings, [], [
3738
{group, verify_get_oauth_provider}
3839
]},
@@ -402,6 +403,23 @@ grants_access_token(Config) ->
402403
?assertEqual(proplists:get_value(token_type, JsonPayload), TokenType),
403404
?assertEqual(proplists:get_value(access_token, JsonPayload), AccessToken).
404405

406+
grants_access_token_optional_parameters(Config) ->
407+
#{request := #{parameters := Parameters},
408+
response := [ {code, 200}, {content_type, _CT}, {payload, JsonPayload}] }
409+
= lookup_expectation(token_endpoint, Config),
410+
411+
AccessTokenRequest0 = build_access_token_request(Parameters),
412+
AccessTokenRequest = AccessTokenRequest0#access_token_request{
413+
scope = "some-scope",
414+
extra_parameters = [{"param1", "value1"}]
415+
},
416+
{ok, #successful_access_token_response{access_token = AccessToken,
417+
token_type = TokenType} } =
418+
oauth2_client:get_access_token(?config(oauth_provider, Config),
419+
AccessTokenRequest),
420+
?assertEqual(proplists:get_value(token_type, JsonPayload), TokenType),
421+
?assertEqual(proplists:get_value(access_token, JsonPayload), AccessToken).
422+
405423
grants_refresh_token(Config) ->
406424
#{request := #{parameters := Parameters},
407425
response := [ {code, 200}, {content_type, _CT}, {payload, JsonPayload}] }

deps/rabbitmq_auth_backend_oauth2/priv/schema/rabbitmq_auth_backend_oauth2.schema

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,6 @@
158158
"rabbitmq_auth_backend_oauth2.authorization_endpoint",
159159
[{datatype, string}, {validators, ["uri", "https_uri"]}]}.
160160

161-
{mapping,
162-
"auth_oauth2.authorization_endpoint_params.$param",
163-
"rabbitmq_auth_backend_oauth2.authorization_endpoint_params",
164-
[{datatype, string}]}.
165-
166-
{translation, "rabbitmq_auth_backend_oauth2.authorization_endpoint_params",
167-
fun(Conf) ->
168-
oauth2_schema:translate_endpoint_params("authorization_endpoint_params", Conf)
169-
end}.
170-
171161
{mapping,
172162
"auth_oauth2.discovery_endpoint_path",
173163
"rabbitmq_auth_backend_oauth2.discovery_endpoint_path",
@@ -189,22 +179,7 @@
189179
[{datatype, string}]}.
190180

191181
{mapping,
192-
"auth_oauth2.token_endpoint_params.$param",
193-
"rabbitmq_auth_backend_oauth2.token_endpoint_params",
194-
[{datatype, string}]}.
195-
196-
{translation, "rabbitmq_auth_backend_oauth2.token_endpoint_params",
197-
fun(Conf) ->
198-
oauth2_schema:translate_endpoint_params("token_endpoint_params", Conf)
199-
end}.
200-
201-
{mapping,
202-
"auth_oauth2.oauth_providers.$name.authorization_endpoint_params.$param",
203-
"rabbitmq_auth_backend_oauth2.oauth_providers",
204-
[{datatype, string}]}.
205-
206-
{mapping,
207-
"auth_oauth2.oauth_providers.$name.token_endpoint_params.$param",
182+
"auth_oauth2.oauth_providers.$name.discovery_endpoint_path",
208183
"rabbitmq_auth_backend_oauth2.oauth_providers",
209184
[{datatype, string}]}.
210185

deps/rabbitmq_auth_backend_oauth2/src/oauth2_schema.erl

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ translate_oauth_providers(Conf) ->
4141
merge_list_of_maps([
4242
extract_oauth_providers_properties(Settings),
4343
extract_oauth_providers_endpoint_params(discovery_endpoint_params, Settings),
44-
extract_oauth_providers_endpoint_params(authorization_endpoint_params, Settings),
45-
extract_oauth_providers_endpoint_params(token_endpoint_params, Settings),
4644
extract_oauth_providers_algorithm(Settings),
4745
extract_oauth_providers_https(Settings),
4846
extract_oauth_providers_signing_keys(Settings)
@@ -122,13 +120,7 @@ mapOauthProviderProperty({Key, Value}) ->
122120
token_endpoint -> validator_https_uri(Key, Value);
123121
jwks_uri -> validator_https_uri(Key, Value);
124122
end_session_endpoint -> validator_https_uri(Key, Value);
125-
authorization_endpoint -> validator_https_uri(Key, Value);
126-
token_endpoint_params ->
127-
cuttlefish:invalid(io_lib:format(
128-
"Invalid attribute (~p) value: should be a map of Key,Value pairs", [Key]));
129-
authorization_endpoint_params ->
130-
cuttlefish:invalid(io_lib:format(
131-
"Invalid attribute (~p) value: should be a map of Key,Value pairs", [Key]));
123+
authorization_endpoint -> validator_https_uri(Key, Value);
132124
discovery_endpoint_params ->
133125
cuttlefish:invalid(io_lib:format(
134126
"Invalid attribute (~p) value: should be a map of Key,Value pairs", [Key]));
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
-module(uaa_jwks).
22
-export([get/2]).
33

4-
-spec get(string() | binary(), term()) -> {ok, term()} | {error, term()}.
4+
-spec get(uri_string:uri_string(), list()) -> {ok, term()} | {error, term()}.
55
get(JwksUrl, SslOptions) ->
66
Options = [{timeout, 60000}] ++ [{ssl, SslOptions}],
77
httpc:request(get, {JwksUrl, []}, Options, []).

deps/rabbitmq_auth_backend_oauth2/test/oauth2_schema_SUITE.erl

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ test_without_resource_servers(_) ->
4545
#{} = oauth2_schema:translate_resource_servers([]).
4646

4747
test_without_endpoint_params(_) ->
48-
#{} = translate_endpoint_params("discovery_endpoint_params", []),
49-
#{} = translate_endpoint_params("token_endpoint_params", []),
50-
#{} = translate_endpoint_params("authorization_endpoint_params", []).
48+
#{} = translate_endpoint_params("oauth_discovery_endpoint_params", []).
5149

5250
test_with_invalid_endpoint_params(_) ->
5351
try translate_endpoint_params("discovery_endpoint_params", [
@@ -60,16 +58,10 @@ test_with_invalid_endpoint_params(_) ->
6058
test_with_endpoint_params(_) ->
6159
Conf = [
6260
{["auth_oauth2","discovery_endpoint_params","param1"], "some-value1"},
63-
{["auth_oauth2","discovery_endpoint_params","param2"], "some-value2"},
64-
{["auth_oauth2","token_endpoint_params","audience"], "some-audience"},
65-
{["auth_oauth2","authorization_endpoint_params","resource"], "some-resource"}
61+
{["auth_oauth2","discovery_endpoint_params","param2"], "some-value2"}
6662
],
6763
#{ <<"param1">> := <<"some-value1">>, <<"param2">> := <<"some-value2">> } =
68-
translate_endpoint_params("discovery_endpoint_params", Conf),
69-
#{ <<"audience">> := <<"some-audience">>} =
70-
translate_endpoint_params("token_endpoint_params", Conf),
71-
#{ <<"resource">> := <<"some-resource">>} =
72-
translate_endpoint_params("authorization_endpoint_params", Conf).
64+
translate_endpoint_params("discovery_endpoint_params", Conf).
7365

7466
test_invalid_oauth_providers_endpoint_params(_) ->
7567
try oauth2_schema:translate_oauth_providers([
@@ -83,17 +75,15 @@ test_without_oauth_providers_with_endpoint_params(_) ->
8375
Conf = [
8476
{["auth_oauth2","oauth_providers", "A", "discovery_endpoint_params","param1"], "some-value1"},
8577
{["auth_oauth2","oauth_providers", "A", "discovery_endpoint_params","param2"], "some-value2"},
86-
{["auth_oauth2","oauth_providers", "B", "token_endpoint_params","audience"], "some-audience"},
87-
{["auth_oauth2","oauth_providers", "C", "authorization_endpoint_params","resource"], "some-resource"}
78+
{["auth_oauth2","oauth_providers", "B", "discovery_endpoint_params","param3"], "some-value3"}
8879
],
8980

9081
#{
9182
<<"A">> := [{discovery_endpoint_params,
9283
#{ <<"param1">> := <<"some-value1">>, <<"param2">> := <<"some-value2">> }}],
93-
<<"B">> := [{token_endpoint_params,
94-
#{ <<"audience">> := <<"some-audience">>}}],
95-
<<"C">> := [{authorization_endpoint_params,
96-
#{ <<"resource">> := <<"some-resource">>}}]
84+
<<"B">> := [{discovery_endpoint_params,
85+
#{ <<"param3">> := <<"some-value3">>}}
86+
]
9787
} = translate_oauth_providers(Conf).
9888

9989
test_with_one_oauth_provider(_) ->
@@ -110,11 +100,13 @@ test_with_one_resource_server(_) ->
110100

111101
test_with_many_oauth_providers(_) ->
112102
Conf = [{["auth_oauth2","oauth_providers","keycloak","issuer"],"https://keycloak"},
113-
{["auth_oauth2","oauth_providers","uaa","issuer"],"https://uaa"}
103+
{["auth_oauth2","oauth_providers","uaa","issuer"],"https://uaa"},
104+
{["auth_oauth2","oauth_providers","uaa","discovery_endpoint_path"],"/some-path"}
114105
],
115-
#{<<"keycloak">> := [{issuer, <<"https://keycloak">>}
106+
#{<<"keycloak">> := [{issuer, <<"https://keycloak">>}
116107
],
117-
<<"uaa">> := [{issuer, <<"https://uaa">>}
108+
<<"uaa">> := [{issuer, <<"https://uaa">>},
109+
{discovery_endpoint_path, <<"/some-path">>}
118110
]
119111
} = oauth2_schema:translate_oauth_providers(Conf).
120112

deps/rabbitmq_management/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ rabbitmq_suite(
130130
],
131131
)
132132

133+
rabbitmq_suite(
134+
name = "rabbit_mgmt_schema_SUITE",
135+
size = "small"
136+
)
137+
133138
rabbitmq_integration_suite(
134139
name = "clustering_prop_SUITE",
135140
size = "large",

deps/rabbitmq_management/app.bzl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def all_beam_files(name = "all_beam_files"):
3030
"src/rabbit_mgmt_load_definitions.erl",
3131
"src/rabbit_mgmt_login.erl",
3232
"src/rabbit_mgmt_nodes.erl",
33+
"src/rabbit_mgmt_schema.erl",
3334
"src/rabbit_mgmt_oauth_bootstrap.erl",
3435
"src/rabbit_mgmt_reset_handler.erl",
3536
"src/rabbit_mgmt_stats.erl",
@@ -163,6 +164,7 @@ def all_test_beam_files(name = "all_test_beam_files"):
163164
"src/rabbit_mgmt_load_definitions.erl",
164165
"src/rabbit_mgmt_login.erl",
165166
"src/rabbit_mgmt_nodes.erl",
167+
"src/rabbit_mgmt_schema.erl",
166168
"src/rabbit_mgmt_oauth_bootstrap.erl",
167169
"src/rabbit_mgmt_reset_handler.erl",
168170
"src/rabbit_mgmt_stats.erl",
@@ -387,6 +389,7 @@ def all_srcs(name = "all_srcs"):
387389
"src/rabbit_mgmt_load_definitions.erl",
388390
"src/rabbit_mgmt_login.erl",
389391
"src/rabbit_mgmt_nodes.erl",
392+
"src/rabbit_mgmt_schema.erl",
390393
"src/rabbit_mgmt_oauth_bootstrap.erl",
391394
"src/rabbit_mgmt_reset_handler.erl",
392395
"src/rabbit_mgmt_stats.erl",
@@ -495,6 +498,15 @@ def all_srcs(name = "all_srcs"):
495498
)
496499

497500
def test_suite_beam_files(name = "test_suite_beam_files"):
501+
erlang_bytecode(
502+
name = "rabbit_mgmt_schema_SUITE_beam_files",
503+
testonly = True,
504+
srcs = ["test/rabbit_mgmt_schema_SUITE.erl"],
505+
outs = ["test/rabbit_mgmt_schema_SUITE.beam"],
506+
app_name = "rabbitmq_management",
507+
erlc_opts = "//:test_erlc_opts",
508+
deps = ["@proper//:erlang_app"],
509+
)
498510
erlang_bytecode(
499511
name = "cache_SUITE_beam_files",
500512
testonly = True,

deps/rabbitmq_management/priv/schema/rabbitmq_management.schema

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,26 @@ end}.
472472
{mapping, "management.oauth_response_type", "rabbitmq_management.oauth_response_type",
473473
[{datatype, string}]}.
474474

475+
%% Configure OAuth2 authorization_endpoint additional request parameters
476+
{mapping, "management.oauth_authorization_endpoint_params.$name",
477+
"rabbitmq_management.oauth_authorization_endpoint_params",
478+
[{datatype, string}]}.
479+
480+
{translation, "rabbitmq_management.oauth_authorization_endpoint_params",
481+
fun(Conf) ->
482+
rabbit_mgmt_schema:translate_endpoint_params("oauth_authorization_endpoint_params", Conf)
483+
end}.
484+
485+
%% Configure OAuth2 token_endpoint additional request parameters
486+
{mapping, "management.oauth_token_endpoint_params.$name",
487+
"rabbitmq_management.oauth_token_endpoint_params",
488+
[{datatype, string}]}.
489+
490+
{translation, "rabbitmq_management.oauth_token_endpoint_params",
491+
fun(Conf) ->
492+
rabbit_mgmt_schema:translate_endpoint_params("oauth_token_endpoint_params", Conf)
493+
end}.
494+
475495
%% The scopes RabbitMq should claim during the authorization flow. Defaults to "openid profile"
476496
{mapping, "management.oauth_scopes", "rabbitmq_management.oauth_scopes",
477497
[{datatype, string}]}.
@@ -513,8 +533,6 @@ end}.
513533
[{datatype, string}]
514534
}.
515535

516-
517-
518536
{mapping,
519537
"management.oauth_resource_servers.$name.oauth_client_id",
520538
"rabbitmq_management.oauth_resource_servers",
@@ -533,7 +551,6 @@ end}.
533551
[{datatype, string}]
534552
}.
535553

536-
537554
{mapping,
538555
"management.oauth_resource_servers.$name.oauth_scopes",
539556
"rabbitmq_management.oauth_resource_servers",
@@ -551,36 +568,17 @@ end}.
551568
"rabbitmq_management.oauth_resource_servers",
552569
[{datatype, {enum, [sp_initiated, idp_initiated]}}]}.
553570

571+
{mapping, "management.oauth_resource_servers.$name.authorization_endpoint_params.$name",
572+
""rabbitmq_management.oauth_resource_servers",
573+
[{datatype, string}]}.
574+
575+
{mapping, "management.oauth_resource_servers.$name.token_endpoint_params.$name",
576+
""rabbitmq_management.oauth_resource_servers",
577+
[{datatype, string}]}.
578+
554579
{translation, "rabbitmq_management.oauth_resource_servers",
555580
fun(Conf) ->
556-
Settings = cuttlefish_variable:filter_by_prefix("management.oauth_resource_servers", Conf),
557-
ResourceServers = [{Name, {list_to_atom(Key), V}} || {["management","oauth_resource_servers", Name, Key], V} <- Settings ],
558-
KeyFun = fun({Name,_}) -> list_to_binary(Name) end,
559-
ValueFun = fun({_,V}) -> V end,
560-
NewGroup = maps:groups_from_list(KeyFun, ValueFun, ResourceServers),
561-
ListOrSingleFun = fun(K, List) ->
562-
case K of
563-
key_config -> proplists:get_all_values(K, List);
564-
_ ->
565-
case proplists:lookup_all(K, List) of
566-
[One] -> proplists:get_value(K, List);
567-
[One|_] = V -> V
568-
end
569-
end
570-
end,
571-
GroupKeyConfigFun = fun(K, List) ->
572-
ListKeys = proplists:get_keys(List),
573-
[ {K,ListOrSingleFun(K,List)} || K <- ListKeys ]
574-
end,
575-
NewGroupTwo = maps:map(GroupKeyConfigFun, NewGroup),
576-
IndexByIdOrElseNameFun = fun(K, V, NewMap) ->
577-
case proplists:get_value(id, V) of
578-
undefined -> maps:put(K, V, NewMap);
579-
ID when is_binary(ID) -> maps:put(ID, V, NewMap);
580-
ID -> maps:put(list_to_binary(ID), V, NewMap)
581-
end
582-
end,
583-
maps:fold(IndexByIdOrElseNameFun,#{}, NewGroupTwo)
581+
rabbit_mgmt_schema:translate_resource_servers(Conf)
584582
end}.
585583

586584
%% ===========================================================================

0 commit comments

Comments
 (0)