Nelson Vides 596d446f54
Erlang server overhaul (#19465)
* Upgrade erlang-server code generation and fix is_authorized crashes

* Introduce structured logging

* Improve general formatting

* Update generated files

* Enable erlang server on CI

* Add echo-server testing to CI

* Require OTP27 explicitly in the generated rebar.config file

* Rework handler and API

With this work, json validation becomes optional, fully implemented in
the `_api` module as it was before, but without being forcibly called by
the `_handler`. It is instead left as optional for the user to take
advantage of the exposed callbacks. Jesse also chooses draft-06 as a
default, but these can be chosen manually by the user too, as long as
jesse implements them.

`_handler` also becomes lighter, it now handles all mime types
transparently by forwarding to a user-given module that must implement
`accept_callback/4` and `provide_callback/4` as described in the
`_logic_handler` callbacks. These will simply be the return values of
cowboy_rest's `content_types_accepted` and `content_types_provided`
respectively, and should simply comply with their defined APIs. They
only get two parameters extending the behaviour, so that the user-given
callback can pattern-match on them: the path prefix of the logic
handler, and the operationID of the call.

* Fix return types for provide_callbacks

* Upgrade jesse to incur no dependencies

The less dependencies the built code requires the better.

* Fix dialyzer errors in the generated code

* Apply stronger dialyzer checks
2024-09-07 16:45:42 +08:00

46 lines
1.4 KiB
Erlang

-module(openapi_auth).
-export([authorize_api_key/5]).
-spec authorize_api_key(openapi_logic_handler:api_key_callback(),
openapi_api:operation_id(),
header | qs_val,
iodata() | atom(),
cowboy_req:req()) ->
{true, openapi_logic_handler:context(), cowboy_req:req()} |
{false, binary(), cowboy_req:req()}.
authorize_api_key(Handler, OperationID, From, KeyParam, Req0) ->
{ApiKey, Req} = get_api_key(From, KeyParam, Req0),
case ApiKey of
undefined ->
AuthHeader = <<>>,
{false, AuthHeader, Req};
_ ->
case Handler(OperationID, ApiKey) of
{true, Context} ->
{true, Context, Req};
{false, AuthHeader} ->
{false, AuthHeader, Req}
end
end.
get_api_key(header, KeyParam, Req) ->
Headers = cowboy_req:headers(Req),
{maps:get(KeyParam, Headers, undefined), Req};
get_api_key(qs_val, KeyParam, Req) ->
QS = cowboy_req:parse_qs(Req),
{get_opt(KeyParam, QS), Req}.
-spec get_opt(any(), []) -> any().
get_opt(Key, Opts) ->
get_opt(Key, Opts, undefined).
-spec get_opt(any(), [], any()) -> any().
get_opt(Key, Opts, Default) ->
case lists:keyfind(Key, 1, Opts) of
{_, Value} ->
Value;
false ->
Default
end.