-module(lightspeed@transport@contract).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/lightspeed/transport/contract.gleam").
-export([authenticate/2, allow_all/1, deny_all/1, protect/2, allow_protection/0, deny_protection/1, require_csrf/1, limit_rate/2, allow_rate_limit/0, deny_rate_limit/2, error_to_string/1]).
-export_type([auth_context/0, auth_result/0, adapter_error/0, auth_hook/0, protection_context/0, protection_result/0, protection_hook/0, rate_limit_context/0, rate_limit_result/0, rate_limit_hook/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.
?MODULEDOC(" Transport adapter contract primitives.\n").
-type auth_context() :: {auth_context, binary(), binary(), binary(), binary()}.
-type auth_result() :: {authorized, binary()} | {denied, binary()}.
-type adapter_error() :: {authentication_failed, binary()} |
{protection_rejected, binary()} |
{rate_limited, binary(), integer()} |
{protocol_decode_failed, lightspeed@protocol:decode_error()} |
{unsupported_client_frame, binary()} |
{unsupported_client_event, binary()} |
{invalid_adapter_state, binary()}.
-type auth_hook() :: {auth_hook, fun((auth_context()) -> auth_result())}.
-type protection_context() :: {protection_context,
binary(),
binary(),
binary(),
binary(),
binary()}.
-type protection_result() :: protected | {rejected, binary()}.
-type protection_hook() :: {protection_hook,
fun((protection_context()) -> protection_result())}.
-type rate_limit_context() :: {rate_limit_context,
binary(),
binary(),
binary(),
integer()}.
-type rate_limit_result() :: rate_allowed | {limited, binary(), integer()}.
-type rate_limit_hook() :: {rate_limit_hook,
fun((rate_limit_context()) -> rate_limit_result())}.
-file("src/lightspeed/transport/contract.gleam", 82).
?DOC(" Execute an auth hook.\n").
-spec authenticate(auth_hook(), auth_context()) -> auth_result().
authenticate(Hook, Context) ->
(erlang:element(2, Hook))(Context).
-file("src/lightspeed/transport/contract.gleam", 87).
?DOC(" Accept every connection with the given owner id.\n").
-spec allow_all(binary()) -> auth_hook().
allow_all(Owner) ->
{auth_hook, fun(_) -> {authorized, Owner} end}.
-file("src/lightspeed/transport/contract.gleam", 92).
?DOC(" Reject every connection with a fixed reason.\n").
-spec deny_all(binary()) -> auth_hook().
deny_all(Reason) ->
{auth_hook, fun(_) -> {denied, Reason} end}.
-file("src/lightspeed/transport/contract.gleam", 97).
?DOC(" Execute a protection hook.\n").
-spec protect(protection_hook(), protection_context()) -> protection_result().
protect(Hook, Context) ->
(erlang:element(2, Hook))(Context).
-file("src/lightspeed/transport/contract.gleam", 105).
?DOC(" Allow every connection through protection checks.\n").
-spec allow_protection() -> protection_hook().
allow_protection() ->
{protection_hook, fun(_) -> protected end}.
-file("src/lightspeed/transport/contract.gleam", 110).
?DOC(" Deny every connection through protection checks.\n").
-spec deny_protection(binary()) -> protection_hook().
deny_protection(Reason) ->
{protection_hook, fun(_) -> {rejected, Reason} end}.
-file("src/lightspeed/transport/contract.gleam", 115).
?DOC(" Require an exact CSRF token match.\n").
-spec require_csrf(binary()) -> protection_hook().
require_csrf(Expected_token) ->
{protection_hook,
fun(Context) -> case erlang:element(5, Context) =:= Expected_token of
true ->
protected;
false ->
{rejected, <<"csrf_token_mismatch"/utf8>>}
end end}.
-file("src/lightspeed/transport/contract.gleam", 125).
?DOC(" Execute a rate-limit hook.\n").
-spec limit_rate(rate_limit_hook(), rate_limit_context()) -> rate_limit_result().
limit_rate(Hook, Context) ->
(erlang:element(2, Hook))(Context).
-file("src/lightspeed/transport/contract.gleam", 133).
?DOC(" Allow every event by rate-limit policy.\n").
-spec allow_rate_limit() -> rate_limit_hook().
allow_rate_limit() ->
{rate_limit_hook, fun(_) -> rate_allowed end}.
-file("src/lightspeed/transport/contract.gleam", 138).
?DOC(" Deny every event by rate-limit policy.\n").
-spec deny_rate_limit(binary(), integer()) -> rate_limit_hook().
deny_rate_limit(Reason, Retry_after_ms) ->
{rate_limit_hook, fun(_) -> {limited, Reason, Retry_after_ms} end}.
-file("src/lightspeed/transport/contract.gleam", 145).
?DOC(" Stable adapter error string for logs and tests.\n").
-spec error_to_string(adapter_error()) -> binary().
error_to_string(Error) ->
case Error of
{authentication_failed, Reason} ->
<<"authentication_failed:"/utf8, Reason/binary>>;
{protection_rejected, Reason@1} ->
<<"protection_rejected:"/utf8, Reason@1/binary>>;
{rate_limited, Reason@2, Retry_after_ms} ->
<<<<<<"rate_limited:"/utf8, Reason@2/binary>>/binary, ":"/utf8>>/binary,
(erlang:integer_to_binary(Retry_after_ms))/binary>>;
{protocol_decode_failed, Decode_error} ->
<<"protocol_decode_failed:"/utf8,
(lightspeed@protocol:decode_error_to_string(Decode_error))/binary>>;
{unsupported_client_frame, Frame} ->
<<"unsupported_client_frame:"/utf8, Frame/binary>>;
{unsupported_client_event, Event} ->
<<"unsupported_client_event:"/utf8, Event/binary>>;
{invalid_adapter_state, Reason@3} ->
<<"invalid_adapter_state:"/utf8, Reason@3/binary>>
end.