Current section
Files
Jump to
Current section
Files
src/flwr_oauth2@token_request.erl
-module(flwr_oauth2@token_request).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/flwr_oauth2/token_request.gleam").
-export([to_string/1, request_body_to_string/1, apply_modifiers/2, setup_request/2, authorization_setter/1, to_http_request_with_modifiers/2, to_http_request/1, to_http_request_with_custom_authentication/2, build_post_request/4]).
-export_type([token_request/0, request_error/0, authorization_setter/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type token_request() :: {authorization_code_grant_token_request,
gleam@uri:uri(),
flwr_oauth2@authentication:client_authentication(),
gleam@option:option(gleam@uri:uri()),
binary()} |
{resource_owner_credentials_grant_token_request,
gleam@uri:uri(),
flwr_oauth2@authentication:client_authentication(),
binary(),
binary(),
list(binary())} |
{refresh_token_grant_request,
gleam@uri:uri(),
flwr_oauth2@authentication:client_authentication(),
binary(),
list(binary())} |
{client_credentials_grant_token_request,
gleam@uri:uri(),
flwr_oauth2@authentication:client_authentication(),
list(binary())}.
-type request_error() :: secret_expired | invalid_uri.
-type authorization_setter() :: {authorization_setter,
fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()})}.
-file("src/flwr_oauth2/token_request.gleam", 77).
-spec to_string(token_request()) -> binary().
to_string(Req) ->
Auth = flwr_oauth2@authentication:to_string(erlang:element(3, Req)),
case Req of
{authorization_code_grant_token_request,
Token_endpoint,
_,
Redirect_uri,
Code} ->
<<<<<<<<<<<<<<<<<<<<<<<<"AuthorizationCodeGrantTokenRequest("/utf8,
"token_endpoint="/utf8>>/binary,
(gleam@uri:to_string(
Token_endpoint
))/binary>>/binary,
", "/utf8>>/binary,
"authentication="/utf8>>/binary,
Auth/binary>>/binary,
", "/utf8>>/binary,
"redirect_uri="/utf8>>/binary,
(begin
_pipe = gleam@option:map(
Redirect_uri,
fun gleam@uri:to_string/1
),
gleam@option:unwrap(_pipe, <<"None"/utf8>>)
end)/binary>>/binary,
", "/utf8>>/binary,
"code="/utf8>>/binary,
Code/binary>>/binary,
")"/utf8>>;
{resource_owner_credentials_grant_token_request,
Token_endpoint@1,
_,
Username,
Password,
Scope} ->
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"ResourceOwnerCredentialsGrantTokenRequest("/utf8,
"token_endpoint="/utf8>>/binary,
(gleam@uri:to_string(
Token_endpoint@1
))/binary>>/binary,
", "/utf8>>/binary,
"authentication="/utf8>>/binary,
Auth/binary>>/binary,
", "/utf8>>/binary,
"username="/utf8>>/binary,
Username/binary>>/binary,
", "/utf8>>/binary,
"password="/utf8>>/binary,
Password/binary>>/binary,
", "/utf8>>/binary,
"scope="/utf8>>/binary,
(gleam@string:join(Scope, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{refresh_token_grant_request,
Token_endpoint@2,
_,
Refresh_token,
Scope@1} ->
<<<<<<<<<<<<<<<<<<<<<<<<"RefreshTokenGrantRequest("/utf8,
"token_endpoint="/utf8>>/binary,
(gleam@uri:to_string(
Token_endpoint@2
))/binary>>/binary,
", "/utf8>>/binary,
"authentication="/utf8>>/binary,
Auth/binary>>/binary,
", "/utf8>>/binary,
"refresh_token="/utf8>>/binary,
Refresh_token/binary>>/binary,
", "/utf8>>/binary,
"scope="/utf8>>/binary,
(gleam@string:join(Scope@1, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>;
{client_credentials_grant_token_request, Token_endpoint@3, _, Scope@2} ->
<<<<<<<<<<<<<<<<<<"ClientCredentialsGrantTokenRequest("/utf8,
"token_endpoint="/utf8>>/binary,
(gleam@uri:to_string(
Token_endpoint@3
))/binary>>/binary,
", "/utf8>>/binary,
"authentication="/utf8>>/binary,
Auth/binary>>/binary,
", "/utf8>>/binary,
"scope="/utf8>>/binary,
(gleam@string:join(Scope@2, <<" "/utf8>>))/binary>>/binary,
")"/utf8>>
end.
-file("src/flwr_oauth2/token_request.gleam", 221).
-spec request_body_to_string(
gleam@http@request:request(list({binary(), binary()}))
) -> gleam@http@request:request(binary()).
request_body_to_string(Request) ->
_pipe = erlang:element(4, Request),
_pipe@1 = gleam@uri:query_to_string(_pipe),
gleam@http@request:set_body(Request, _pipe@1).
-file("src/flwr_oauth2/token_request.gleam", 214).
-spec apply_modifiers(
gleam@http@request:request(list({binary(), binary()})),
list(fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}))
) -> {ok, gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}.
apply_modifiers(Request, Modifiers) ->
gleam@list:fold(Modifiers, {ok, Request}, fun gleam@result:'try'/2).
-file("src/flwr_oauth2/token_request.gleam", 243).
?DOC(
" A helper function that maps a general request with credentials to a gleam http request.\n"
" The credentials are either attached to the request body URL encoded or added as basic `authorization` header.\n"
).
-spec setup_request(gleam@uri:uri(), list({binary(), binary()})) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}.
setup_request(Endpoint, Body) ->
Req = begin
_pipe = gleam@http@request:from_uri(Endpoint),
gleam@result:replace_error(_pipe, invalid_uri)
end,
gleam@result:'try'(Req, fun(Req@1) -> _pipe@1 = Req@1,
_pipe@2 = gleam@http@request:set_method(_pipe@1, post),
_pipe@3 = gleam@http@request:set_header(
_pipe@2,
<<"content-type"/utf8>>,
<<"application/x-www-form-urlencoded"/utf8>>
),
_pipe@4 = gleam@http@request:set_body(_pipe@3, Body),
{ok, _pipe@4} end).
-file("src/flwr_oauth2/token_request.gleam", 230).
?DOC(" Function that adds a scope to a list if the scope is not empty.\n").
-spec add_scope(list({binary(), binary()}), list(binary())) -> list({binary(),
binary()}).
add_scope(D, Scope) ->
_pipe@1 = case Scope of
[_ | _] = Scope@1 ->
{some,
{<<"scope"/utf8>>,
begin
_pipe = Scope@1,
gleam@string:join(_pipe, <<" "/utf8>>)
end}};
_ ->
none
end,
flwr_oauth2@helpers:add_if_present(D, _pipe@1).
-file("src/flwr_oauth2/token_request.gleam", 186).
-spec request_body(token_request()) -> list({binary(), binary()}).
request_body(Request) ->
case Request of
{authorization_code_grant_token_request, _, _, Redirect_uri, Code} ->
Redirect_uri@1 = flwr_oauth2@helpers:encode_redirect_uri(
Redirect_uri
),
_pipe = [{<<"grant_type"/utf8>>, <<"authorization_code"/utf8>>},
{<<"code"/utf8>>, Code}],
flwr_oauth2@helpers:add_if_present(_pipe, Redirect_uri@1);
{resource_owner_credentials_grant_token_request,
_,
_,
Username,
Password,
Scope} ->
_pipe@1 = [{<<"grant_type"/utf8>>, <<"password"/utf8>>},
{<<"username"/utf8>>, Username},
{<<"password"/utf8>>, Password}],
add_scope(_pipe@1, Scope);
{refresh_token_grant_request, _, _, Refresh_token, Scope@1} ->
_pipe@2 = [{<<"grant_type"/utf8>>, <<"refresh_token"/utf8>>},
{<<"refresh_token"/utf8>>, Refresh_token}],
add_scope(_pipe@2, Scope@1);
{client_credentials_grant_token_request, _, _, Scope@2} ->
_pipe@3 = [{<<"grant_type"/utf8>>, <<"client_credentials"/utf8>>}],
add_scope(_pipe@3, Scope@2)
end.
-file("src/flwr_oauth2/token_request.gleam", 181).
-spec base_http_request(token_request()) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}.
base_http_request(Req) ->
_pipe = request_body(Req),
setup_request(erlang:element(2, Req), _pipe).
-file("src/flwr_oauth2/token_request.gleam", 310).
-spec add_body(list({binary(), binary()})) -> fun((gleam@http@request:request(list({binary(),
binary()}))) -> {ok, gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}).
add_body(Fields) ->
fun(Req) -> _pipe = erlang:element(4, Req),
_pipe@1 = lists:append(Fields, _pipe),
_pipe@2 = gleam@http@request:set_body(Req, _pipe@1),
{ok, _pipe@2} end.
-file("src/flwr_oauth2/token_request.gleam", 300).
-spec guard_secret(flwr_oauth2@common:secret()) -> fun((gleam@http@request:request(list({binary(),
binary()}))) -> {ok, gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}).
guard_secret(Secret) ->
fun(Req) ->
gleam@bool:guard(
flwr_oauth2@common:is_secret_invalid(Secret),
{error, secret_expired},
fun() -> {ok, Req} end
)
end.
-file("src/flwr_oauth2/token_request.gleam", 292).
-spec compose(
fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}),
fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()})
) -> fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}).
compose(First, Second) ->
fun(Req) -> _pipe = Req,
_pipe@1 = First(_pipe),
gleam@result:'try'(_pipe@1, Second) end.
-file("src/flwr_oauth2/token_request.gleam", 319).
-spec set_basic_header(binary(), binary()) -> fun((gleam@http@request:request(list({binary(),
binary()}))) -> {ok, gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}).
set_basic_header(Client_id, Client_secret) ->
fun(Req) -> _pipe = Req,
_pipe@1 = flwr_oauth2@http_headers:set_basic(
_pipe,
Client_id,
Client_secret
),
{ok, _pipe@1} end.
-file("src/flwr_oauth2/token_request.gleam", 260).
?DOC(
" Encodes the ClientAuthentication that is to be sent to the OAuth 2.0 Server.\n"
" For Basic Authentication it will always encode it with base64.\n"
).
-spec authorization_setter(flwr_oauth2@authentication:client_authentication()) -> fun((gleam@http@request:request(list({binary(),
binary()}))) -> {ok, gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}).
authorization_setter(Auth) ->
case Auth of
{client_secret_basic, Client_id, Client_secret} ->
compose(
guard_secret(Client_secret),
set_basic_header(
erlang:element(2, Client_id),
erlang:element(2, Client_secret)
)
);
{client_secret_post, Client_id@1, Client_secret@1} ->
compose(
guard_secret(Client_secret@1),
add_body(
[{<<"client_id"/utf8>>, erlang:element(2, Client_id@1)},
{<<"client_secret"/utf8>>,
erlang:element(2, Client_secret@1)}]
)
);
{public_authentication, Client_id@2} ->
add_body([{<<"client_id"/utf8>>, erlang:element(2, Client_id@2)}]);
{client_assertion, Client_id@3, Client_assertion, Client_assertion_type} ->
add_body(
[{<<"client_id"/utf8>>, erlang:element(2, Client_id@3)},
{<<"client_assertion_type"/utf8>>, Client_assertion_type},
{<<"client_assertion"/utf8>>, Client_assertion}]
)
end.
-file("src/flwr_oauth2/token_request.gleam", 162).
?DOC(
" Creates a http request from the given TokenRequest applying the given modifiers, but does not send it.\n"
" Sending the request is done by the user of the function.\n"
).
-spec to_http_request_with_modifiers(
token_request(),
list(fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}))
) -> {ok, gleam@http@request:request(binary())} | {error, request_error()}.
to_http_request_with_modifiers(Request, Modifiers) ->
Modifiers@1 = [authorization_setter(erlang:element(3, Request)) | Modifiers],
_pipe = base_http_request(Request),
_pipe@1 = gleam@result:'try'(
_pipe,
fun(_capture) -> apply_modifiers(_capture, Modifiers@1) end
),
gleam@result:map(_pipe@1, fun request_body_to_string/1).
-file("src/flwr_oauth2/token_request.gleam", 156).
?DOC(
" Creates a http request from the given TokenRequest applying the given modifiers, but does not send it.\n"
" Sending the request is done by the user of the function.\n"
).
-spec to_http_request(token_request()) -> {ok,
gleam@http@request:request(binary())} |
{error, request_error()}.
to_http_request(Request) ->
_pipe = Request,
to_http_request_with_modifiers(_pipe, []).
-file("src/flwr_oauth2/token_request.gleam", 172).
-spec to_http_request_with_custom_authentication(
token_request(),
list(fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}))
) -> {ok, gleam@http@request:request(binary())} | {error, request_error()}.
to_http_request_with_custom_authentication(Request, Modifiers) ->
_pipe = base_http_request(Request),
_pipe@1 = gleam@result:'try'(
_pipe,
fun(_capture) -> apply_modifiers(_capture, Modifiers) end
),
gleam@result:map(_pipe@1, fun request_body_to_string/1).
-file("src/flwr_oauth2/token_request.gleam", 335).
?DOC(
" Build a POST request for an OAuth 2.0 endpoint with the given form-encoded body,\n"
" authentication, and optional modifiers.\n"
" This is a lower-level alternative to [`to_http_request_with_modifiers`] that\n"
" does not require a [`TokenRequest`] type — useful for modules that need to\n"
" construct requests with custom body content (e.g., revocation, assertion grants).\n"
).
-spec build_post_request(
gleam@uri:uri(),
list({binary(), binary()}),
flwr_oauth2@authentication:client_authentication(),
list(fun((gleam@http@request:request(list({binary(), binary()}))) -> {ok,
gleam@http@request:request(list({binary(), binary()}))} |
{error, request_error()}))
) -> {ok, gleam@http@request:request(binary())} | {error, request_error()}.
build_post_request(Endpoint, Body, Authentication, Modifiers) ->
Modifiers@1 = [authorization_setter(Authentication) | Modifiers],
_pipe = setup_request(Endpoint, Body),
_pipe@1 = gleam@result:'try'(
_pipe,
fun(_capture) -> apply_modifiers(_capture, Modifiers@1) end
),
gleam@result:map(_pipe@1, fun request_body_to_string/1).