Skip to content

Commit fe04c36

Browse files
Fix first basic tests
1 parent a930fd1 commit fe04c36

File tree

4 files changed

+106
-38
lines changed

4 files changed

+106
-38
lines changed

deps/oauth2_client/include/types.hrl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,10 @@
8888
}).
8989

9090
-type introspect_token_request() :: #introspect_token_request{}.
91+
92+
-record(unsuccessful_introspect_token_response, {
93+
error :: integer(),
94+
error_description :: binary() | string() | undefined
95+
}).
96+
97+
-type unsuccessful_introspect_token_response() :: #unsuccessful_introspect_token_response{}.

deps/oauth2_client/src/oauth2_client.erl

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ introspect_token(Token) ->
6363
undefined -> [];
6464
SSL -> [{ssl, SSL}]
6565
end ++ get_default_timeout(),
66-
Options = [],
66+
Options = [],
6767
Response = httpc:request(post, {URL, Header, Type, Body}, HTTPOptions, Options),
68-
parse_access_token_response(Response);
68+
parse_introspect_token_response(Response);
6969
{error, _} = Error -> Error
7070
end.
7171

@@ -89,7 +89,7 @@ build_introspect_authorization_header_if_any(#introspect_token_request{
8989
client_secret = ClientSecret}) ->
9090
case Method of
9191
basic ->
92-
Credentials = binary_to_list(<<ClientId/binary,":",ClientSecret/binary>>),
92+
Credentials = erlang:iolist_to_binary([ClientId, <<":">>,ClientSecret ]),
9393
AuthStr = base64:encode_to_string(Credentials),
9494
[{"Authorization", "Basic " ++ AuthStr}];
9595
_ -> []
@@ -105,10 +105,10 @@ build_introspection_request() ->
105105
end;
106106
{error, _} = Error -> Error
107107
end,
108-
Providers = case Result of
108+
case Result of
109109
{ok, _} -> Result;
110110
{error, _} ->
111-
maps:filter(fun(K,_V) ->
111+
Providers = maps:filter(fun(K,_V) ->
112112
case get_oauth_provider(K, [introspection_endpoint]) of
113113
{error, _} -> false;
114114
{ok, P} ->
@@ -120,13 +120,13 @@ build_introspection_request() ->
120120
{_Id, _Secret, _Endpoint} -> true
121121
end
122122
end
123-
end, get_env(oauth_providers, #{}))
124-
end,
125-
case maps:size(Providers) of
126-
0 -> {error, not_found_introspection_endpoint};
127-
1 -> {ok, build_introspection_request(lists:last(maps:values(Providers))) };
128-
_ -> {error, too_many_introspection_endpoints}
129-
end.
123+
end, get_env(oauth_providers, #{})),
124+
case maps:size(Providers) of
125+
0 -> {error, not_found_introspection_endpoint};
126+
1 -> {ok, build_introspection_request(lists:last(maps:values(Providers))) };
127+
_ -> {error, too_many_introspection_endpoints}
128+
end
129+
end.
130130

131131
build_introspection_request(Provider) ->
132132
#introspect_token_request{
@@ -606,13 +606,17 @@ build_refresh_token_request_body(Request) ->
606606
grant_type_request_parameter(Type) ->
607607
{?REQUEST_GRANT_TYPE, Type}.
608608

609+
client_id_request_parameter(ClientId) when is_binary(ClientId) ->
610+
{?REQUEST_CLIENT_ID, binary_to_list(ClientId)};
611+
609612
client_id_request_parameter(ClientId) ->
610-
{?REQUEST_CLIENT_ID,
611-
binary_to_list(ClientId)}.
613+
{?REQUEST_CLIENT_ID, ClientId}.
614+
615+
client_secret_request_parameter(ClientSecret)when is_binary(ClientSecret) ->
616+
{?REQUEST_CLIENT_SECRET, binary_to_list(ClientSecret)};
612617

613-
client_secret_request_parameter(ClientSecret) ->
614-
{?REQUEST_CLIENT_SECRET,
615-
binary_to_list(ClientSecret)}.
618+
client_secret_request_parameter(ClientSecret) ->
619+
{?REQUEST_CLIENT_SECRET, ClientSecret}.
616620

617621
refresh_token_request_parameter(Request) ->
618622
{?REQUEST_REFRESH_TOKEN, Request#refresh_token_request.refresh_token}.
@@ -725,11 +729,39 @@ map_to_access_token_response(Code, Reason, Headers, Body) ->
725729
_ -> {error, Reason}
726730
end
727731
end.
732+
map_to_introspect_token_response(Code, Reason, Headers, Body) ->
733+
case decode_body(proplists:get_value("content-type", Headers, ?CONTENT_JSON), Body) of
734+
{error, {error, InternalError}} ->
735+
{error, InternalError};
736+
{error, _} = Error ->
737+
Error;
738+
Value ->
739+
case Code of
740+
200 -> {ok, Value};
741+
201 -> {ok, Value};
742+
204 -> {ok, []};
743+
400 -> {error, map_to_unsuccessful_introspect_token_response(Value)};
744+
401 -> {error, map_to_unsuccessful_introspect_token_response(Value)};
745+
_ -> {error, Reason}
746+
end
747+
end.
748+
map_to_unsuccessful_introspect_token_response(Map) ->
749+
#unsuccessful_introspect_token_response{
750+
error = maps:get(?RESPONSE_ERROR, Map),
751+
error_description = maps:get(?RESPONSE_ERROR_DESCRIPTION, Map, undefined)
752+
}.
728753
parse_access_token_response({error, Reason}) ->
729754
{error, Reason};
730755
parse_access_token_response({ok,{{_,Code,Reason}, Headers, Body}}) ->
731756
map_to_access_token_response(Code, Reason, Headers, Body).
732757

758+
parse_introspect_token_response({error, Reason}) ->
759+
ct:log("parse_introspect_token_response error ~p", [Reason]),
760+
{error, Reason};
761+
parse_introspect_token_response({ok,{{_,Code,Reason}, Headers, Body}}) ->
762+
ct:log("parse_introspect_token_response ok "),
763+
map_to_introspect_token_response(Code, Reason, Headers, Body).
764+
733765
-spec format_ssl_options([ssl:tls_client_option()]) -> string().
734766
format_ssl_options(TlsOptions) ->
735767
CaCertsCount = case proplists:get_value(cacerts, TlsOptions, []) of
@@ -753,14 +785,19 @@ format_oauth_provider(OAuthProvider) ->
753785
lists:flatten(io_lib:format("{id: ~p, issuer: ~p, discovery_endpoint: ~p, " ++
754786
" token_endpoint: ~p, " ++
755787
"authorization_endpoint: ~p, end_session_endpoint: ~p, " ++
756-
"introspection_endpoint: ~p, jwks_uri: ~p, ssl_options: ~p }", [
788+
"introspection{endpoint: ~p, client_id: ~p, has client_secret: ~p} jwks_uri: ~p, ssl_options: ~p }", [
757789
format_oauth_provider_id(OAuthProvider#oauth_provider.id),
758790
OAuthProvider#oauth_provider.issuer,
759791
OAuthProvider#oauth_provider.discovery_endpoint,
760792
OAuthProvider#oauth_provider.token_endpoint,
761793
OAuthProvider#oauth_provider.authorization_endpoint,
762794
OAuthProvider#oauth_provider.end_session_endpoint,
763795
OAuthProvider#oauth_provider.introspection_endpoint,
796+
OAuthProvider#oauth_provider.introspection_client_id,
797+
case OAuthProvider#oauth_provider.introspection_client_secret of
798+
undefined -> false;
799+
_ -> true
800+
end,
764801
OAuthProvider#oauth_provider.jwks_uri,
765802
format_ssl_options(OAuthProvider#oauth_provider.ssl_options)])).
766803

deps/oauth2_client/test/oauth_http_mock.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ match_request(Req, #{method := Method} = ExpectedRequest) ->
3535
end,
3636
case maps:is_key(headers, ExpectedRequest) of
3737
true -> maps:foreach(fun(K,V) ->
38-
?assertEqual(V, cowbow_req:header(K, Req)) end,
38+
?assertEqual(V, cowboy_req:header(K, Req)) end,
3939
maps:get(headers, ExpectedRequest));
4040
false -> ok
4141
end.

deps/oauth2_client/test/system_SUITE.erl

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
-compile(export_all).
1818

1919
-define(MOCK_OPAQUE_TOKEN, <<"some opaque token">>).
20-
-define(MOCK_INTROSPECTION_ENDPOINT, <<"/introspection">>).
20+
-define(MOCK_INTROSPECTION_ENDPOINT, <<"/introspect">>).
2121
-define(MOCK_TOKEN_ENDPOINT, <<"/token">>).
2222
-define(AUTH_PORT, 8000).
2323
-define(ISSUER_PATH, "/somepath").
@@ -47,12 +47,15 @@ groups() ->
4747
cannot_introspect_due_to_missing_configuration,
4848
{with_introspection_endpoint, [], [
4949
cannot_introspect_due_to_missing_configuration,
50-
{with_introspection_basic_client_credentials, [], [
51-
can_introspect_token
52-
]},
53-
{with_introspection_request_param_client_credentials, [], [
54-
can_introspect_token
50+
{https, [], [
51+
{with_introspection_basic_client_credentials, [], [
52+
can_introspect_token
53+
]},
54+
{with_introspection_request_param_client_credentials, [], [
55+
can_introspect_token
56+
]}
5557
]}
58+
5659
]}
5760
]}
5861
]},
@@ -170,31 +173,31 @@ init_per_group(with_default_oauth_provider, Config) ->
170173

171174
init_per_group(with_introspection_endpoint, Config) ->
172175
application:set_env(rabbitmq_auth_backend_oauth2, introspection_endpoint,
173-
"https://introspection"),
176+
build_token_introspection_endpoint("https")),
174177
Config;
175178

176179
init_per_group(with_introspection_basic_client_credentials, Config) ->
177-
application:set_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_id,
180+
application:set_env(rabbitmq_auth_backend_oauth2, introspection_client_id,
178181
"some-client-id"),
179-
application:set_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_secret,
182+
application:set_env(rabbitmq_auth_backend_oauth2, introspection_client_secret,
180183
"some-client-secret"),
181-
application:set_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_auth_method,
184+
application:set_env(rabbitmq_auth_backend_oauth2, introspection_client_auth_method,
182185
basic),
183-
[{with_introspection_basic_client_credentials, [
186+
[{can_introspect_token, [
184187
{introspection_endpoint, build_http_mock_behaviour(
185188
build_introspection_token_request(?MOCK_OPAQUE_TOKEN, basic, <<"some-client-id">>,
186189
<<"some-client-secret">>),
187190
build_http_200_introspection_token_response())}
188191
]} | Config];
189192

190193
init_per_group(with_introspection_request_param_client_credentials, Config) ->
191-
application:set_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_id,
194+
application:set_env(rabbitmq_auth_backend_oauth2, introspection_client_id,
192195
"some-client-id"),
193-
application:set_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_secret,
196+
application:set_env(rabbitmq_auth_backend_oauth2, introspection_client_secret,
194197
"some-client-secret"),
195-
application:set_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_auth_method,
198+
application:set_env(rabbitmq_auth_backend_oauth2, introspection_client_auth_method,
196199
request_param),
197-
[{with_introspection_request_param_client_credentials, [
200+
[{can_introspect_token, [
198201
{introspection_endpoint, build_http_mock_behaviour(
199202
build_introspection_token_request(?MOCK_OPAQUE_TOKEN, request_param, <<"some-client-id">>,
200203
<<"some-client-secret">>),
@@ -365,6 +368,18 @@ end_per_group(with_introspection_endpoint, Config) ->
365368
application:unset_env(rabbitmq_auth_backend_oauth2, introspection_endpoint),
366369
Config;
367370

371+
end_per_group(with_introspection_basic_client_credentials, Config) ->
372+
application:unset_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_id),
373+
application:unset_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_secret),
374+
application:unset_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_auth_method),
375+
Config;
376+
377+
end_per_group(with_introspection_request_param_client_credentials, Config) ->
378+
application:unset_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_id),
379+
application:unset_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_secret),
380+
application:unset_env(rabbitmq_auth_backend_oauth2, introspection_endpoint_client_auth_method),
381+
Config;
382+
368383
end_per_group(_, Config) ->
369384
Config.
370385

@@ -666,10 +681,10 @@ jwks_uri_takes_precedence_over_jwks_url(_Config) ->
666681

667682

668683
cannot_introspect_due_to_missing_configuration(_Config)->
669-
{error, not_found_introspection_endpoint} = oauth2_client:introspect_token(<<"some token">>).
684+
{error, not_found_introspection_endpoint} = oauth2_client:introspect_token(?MOCK_OPAQUE_TOKEN).
670685

671686
can_introspect_token(_Config) ->
672-
{ok, _} = oauth2_client:introspect_token(<<"some token">>).
687+
{ok, _} = oauth2_client:introspect_token(?MOCK_OPAQUE_TOKEN).
673688

674689
%%% HELPERS
675690

@@ -697,6 +712,12 @@ build_jwks_uri(Scheme, Path) ->
697712
port => rabbit_data_coercion:to_integer(?AUTH_PORT),
698713
path => Path}).
699714

715+
build_token_introspection_endpoint(Scheme) ->
716+
uri_string:recompose(#{scheme => Scheme,
717+
host => "localhost",
718+
port => rabbit_data_coercion:to_integer(?AUTH_PORT),
719+
path => "/introspect"}).
720+
700721
build_access_token_request(Request) ->
701722
#access_token_request {
702723
client_id = proplists:get_value(?REQUEST_CLIENT_ID, Request),
@@ -748,6 +769,7 @@ start_https_oauth_server(Port, CertsDir, Expectations) when is_list(Expectations
748769
{'_', [{Path, oauth_http_mock, Expected} || #{request := #{path := Path}}
749770
= Expected <- Expectations ]}
750771
]),
772+
ct:log("start_https_oauth_server with Expectations: ~p", [Expectations]),
751773
{ok, _} = cowboy:start_tls(
752774
mock_http_auth_listener,
753775
[{port, Port},
@@ -758,6 +780,7 @@ start_https_oauth_server(Port, CertsDir, Expectations) when is_list(Expectations
758780

759781
start_https_oauth_server(Port, CertsDir, #{request := #{path := Path}} = Expected) ->
760782
Dispatch = cowboy_router:compile([{'_', [{Path, oauth_http_mock, Expected}]}]),
783+
ct:log("start_https_oauth_server"),
761784
{ok, _} = cowboy:start_tls(
762785
mock_http_auth_listener,
763786
[{port, Port},
@@ -767,6 +790,7 @@ start_https_oauth_server(Port, CertsDir, #{request := #{path := Path}} = Expecte
767790
#{env => #{dispatch => Dispatch}}).
768791

769792
stop_https_auth_server() ->
793+
ct:log("stop_https_auth_server"),
770794
cowboy:stop_listener(mock_http_auth_listener).
771795

772796
-spec ssl_options(ssl:verify_type(), boolean(), file:filename()) -> list().
@@ -879,14 +903,14 @@ denies_access_token_expectation() ->
879903
build_introspection_token_request(Token, basic, ClientId, ClientSecret) ->
880904
Map = build_http_request(
881905
<<"POST">>,
882-
?MOCK_TOKEN_ENDPOINT,
906+
?MOCK_INTROSPECTION_ENDPOINT,
883907
[
884908
{?REQUEST_TOKEN, Token}
885909
]),
886910
Credentials = binary_to_list(<<ClientId/binary,":",ClientSecret/binary>>),
887911
AuthStr = base64:encode_to_string(Credentials),
888912
maps:put(headers, #{
889-
<<"authorization">> => "Basic " ++ AuthStr
913+
<<"authorization">> => list_to_binary("Basic " ++ AuthStr)
890914
}, Map);
891915
build_introspection_token_request(Token, request_param, ClientId, ClientSecret) ->
892916
build_http_request(

0 commit comments

Comments
 (0)