mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-24 17:29:28 +01:00
Add support for XEP-0484: Fast Authentication Streamlining Tokens
This commit is contained in:
parent
da06a50072
commit
2caaa09c99
4
mix.exs
4
mix.exs
@ -135,7 +135,7 @@ defmodule Ejabberd.MixProject do
|
||||
{:eimp, "~> 1.0"},
|
||||
{:ex_doc, "~> 0.31", only: [:dev, :edoc], runtime: false},
|
||||
{:fast_tls, "~> 1.1.22"},
|
||||
{:fast_xml, "~> 1.1.53"},
|
||||
{:fast_xml, "~> 1.1.53", override: true},
|
||||
{:fast_yaml, "~> 1.0"},
|
||||
{:idna, "~> 6.0"},
|
||||
{:mqtree, "~> 1.0"},
|
||||
@ -144,7 +144,7 @@ defmodule Ejabberd.MixProject do
|
||||
{:p1_utils, "~> 1.0"},
|
||||
{:pkix, "~> 1.0"},
|
||||
{:stringprep, ">= 1.0.26"},
|
||||
{:xmpp, "~> 1.9"},
|
||||
{:xmpp, git: "https://github.com/processone/xmpp", ref: "333f688da2f52c73f374a46df139789a48c45395", override: true},
|
||||
{:yconf, git: "https://github.com/processone/yconf.git", ref: "9898754f16cbd4585a1c2061d72fa441ecb2e938", override: true}]
|
||||
++ cond_deps()
|
||||
end
|
||||
|
2
mix.lock
2
mix.lock
@ -34,6 +34,6 @@
|
||||
"stringprep": {:hex, :stringprep, "1.0.30", "46cf0ff631b3e7328f61f20b454d59428d87738f25d709798b5dcbb9b83c23f1", [:rebar3], [{:p1_utils, "1.0.26", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "f6fc9b3384a03877830f89b2f38580caf3f4a27448a4a333d6a8c3975c220b9a"},
|
||||
"stun": {:hex, :stun, "1.2.15", "eec510af6509201ff97f1f2c87b7977c833bf29c04e985383370ec21f04e4ccf", [:rebar3], [{:fast_tls, "1.1.22", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.26", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "f6d8a541a29fd13f2ce658b676c0cc661262b96e045b52def1644b75ebc0edef"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
"xmpp": {:hex, :xmpp, "1.9.0", "d92446bf51d36adda02db63b963fe6d4a1ede33e59b38a43d9b90afd20c25b74", [:rebar3], [{:ezlib, "~> 1.0.12", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "~> 1.1.19", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "~> 1.1.51", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:idna, "~> 6.0", [hex: :idna, repo: "hexpm", optional: false]}, {:p1_utils, "~> 1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "~> 1.0.29", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm", "c1b91be74a9a9503afa6766f756477516920ffbfeea0c260c2fa171355f53c27"},
|
||||
"xmpp": {:git, "https://github.com/processone/xmpp", "333f688da2f52c73f374a46df139789a48c45395", [ref: "333f688da2f52c73f374a46df139789a48c45395"]},
|
||||
"yconf": {:git, "https://github.com/processone/yconf.git", "9898754f16cbd4585a1c2061d72fa441ecb2e938", [ref: "9898754f16cbd4585a1c2061d72fa441ecb2e938"]},
|
||||
}
|
||||
|
@ -77,7 +77,7 @@
|
||||
{stringprep, "~> 1.0.29", {git, "https://github.com/processone/stringprep", {tag, "1.0.30"}}},
|
||||
{if_var_true, stun,
|
||||
{stun, "~> 1.2.12", {git, "https://github.com/processone/stun", {tag, "1.2.15"}}}},
|
||||
{xmpp, "~> 1.9.0", {git, "https://github.com/processone/xmpp", {tag, "1.9.0"}}},
|
||||
{xmpp, "~> 1.9.0", {git, "https://github.com/processone/xmpp", "333f688da2f52c73f374a46df139789a48c45395"}},
|
||||
{yconf, ".*", {git, "https://github.com/processone/yconf", "9898754f16cbd4585a1c2061d72fa441ecb2e938"}}
|
||||
]}.
|
||||
|
||||
|
13
rebar.lock
13
rebar.lock
@ -10,7 +10,7 @@
|
||||
{<<"fast_xml">>,{pkg,<<"fast_xml">>,<<"1.1.53">>},0},
|
||||
{<<"fast_yaml">>,{pkg,<<"fast_yaml">>,<<"1.0.37">>},0},
|
||||
{<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},0},
|
||||
{<<"jiffy">>,{pkg,<<"jiffy">>,<<"1.1.2">>},1},
|
||||
{<<"jiffy">>,{pkg,<<"jiffy">>,<<"1.1.2">>},0},
|
||||
{<<"jose">>,{pkg,<<"jose">>,<<"1.11.10">>},0},
|
||||
{<<"luerl">>,{pkg,<<"luerl">>,<<"1.2.0">>},0},
|
||||
{<<"mqtree">>,{pkg,<<"mqtree">>,<<"1.0.17">>},0},
|
||||
@ -24,7 +24,10 @@
|
||||
{<<"stringprep">>,{pkg,<<"stringprep">>,<<"1.0.30">>},0},
|
||||
{<<"stun">>,{pkg,<<"stun">>,<<"1.2.15">>},0},
|
||||
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},1},
|
||||
{<<"xmpp">>,{pkg,<<"xmpp">>,<<"1.9.0">>},0},
|
||||
{<<"xmpp">>,
|
||||
{git,"https://github.com/processone/xmpp",
|
||||
{ref,"333f688da2f52c73f374a46df139789a48c45395"}},
|
||||
0},
|
||||
{<<"yconf">>,
|
||||
{git,"https://github.com/processone/yconf",
|
||||
{ref,"9898754f16cbd4585a1c2061d72fa441ecb2e938"}},
|
||||
@ -55,8 +58,7 @@
|
||||
{<<"sqlite3">>, <<"E819DEFD280145C328457D7AF897D2E45E8E5270E18812EE30B607C99CDD21AF">>},
|
||||
{<<"stringprep">>, <<"46CF0FF631B3E7328F61F20B454D59428D87738F25D709798B5DCBB9B83C23F1">>},
|
||||
{<<"stun">>, <<"EEC510AF6509201FF97F1F2C87B7977C833BF29C04E985383370EC21F04E4CCF">>},
|
||||
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>},
|
||||
{<<"xmpp">>, <<"D92446BF51D36ADDA02DB63B963FE6D4A1EDE33E59B38A43D9B90AFD20C25B74">>}]},
|
||||
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]},
|
||||
{pkg_hash_ext,[
|
||||
{<<"base64url">>, <<"F9B3ADD4731A02A9B0410398B475B33E7566A695365237A6BDEE1BB447719F5C">>},
|
||||
{<<"cache_tab">>, <<"8582B60A4A09B247EF86355BA9E07FCE9E11EDC0345A775C9171F971C72B6351">>},
|
||||
@ -82,6 +84,5 @@
|
||||
{<<"sqlite3">>, <<"3C0BA4E13322C2AD49DE4E2DDD28311366ADDE54BEAE8DBA9D9E3888F69D2857">>},
|
||||
{<<"stringprep">>, <<"F6FC9B3384A03877830F89B2F38580CAF3F4A27448A4A333D6A8C3975C220B9A">>},
|
||||
{<<"stun">>, <<"F6D8A541A29FD13F2CE658B676C0CC661262B96E045B52DEF1644B75EBC0EDEF">>},
|
||||
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>},
|
||||
{<<"xmpp">>, <<"C1B91BE74A9A9503AFA6766F756477516920FFBFEEA0C260C2FA171355F53C27">>}]}
|
||||
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]}
|
||||
].
|
||||
|
@ -45,7 +45,8 @@
|
||||
handle_unbinded_packet/2, inline_stream_features/1,
|
||||
handle_sasl2_inline/2, handle_sasl2_inline_post/3,
|
||||
handle_bind2_inline/2, handle_bind2_inline_post/3, sasl_options/1,
|
||||
handle_sasl2_task_next/4, handle_sasl2_task_data/3]).
|
||||
handle_sasl2_task_next/4, handle_sasl2_task_data/3,
|
||||
get_fast_tokens_fun/2, fast_mechanisms/1]).
|
||||
%% Hooks
|
||||
-export([handle_unexpected_cast/2, handle_unexpected_call/3,
|
||||
process_auth_result/3, reject_unauthenticated_packet/2,
|
||||
@ -465,6 +466,20 @@ check_password_digest_fun(_Mech, #{lserver := LServer}) ->
|
||||
ejabberd_auth:check_password_with_authmodule(U, AuthzId, LServer, P, D, DG)
|
||||
end.
|
||||
|
||||
get_fast_tokens_fun(_Mech, #{lserver := LServer}) ->
|
||||
fun(User, UA) ->
|
||||
case gen_mod:is_loaded(LServer, mod_auth_fast) of
|
||||
false -> false;
|
||||
_ -> mod_auth_fast:get_tokens(LServer, User, UA)
|
||||
end
|
||||
end.
|
||||
|
||||
fast_mechanisms(#{lserver := LServer}) ->
|
||||
case gen_mod:is_loaded(LServer, mod_auth_fast) of
|
||||
false -> [];
|
||||
_ -> mod_auth_fast:get_mechanisms(LServer)
|
||||
end.
|
||||
|
||||
bind(<<"">>, State) ->
|
||||
bind(new_uniq_id(), State);
|
||||
bind(R, #{user := U, server := S, access := Access, lang := Lang,
|
||||
|
167
src/mod_auth_fast.erl
Normal file
167
src/mod_auth_fast.erl
Normal file
@ -0,0 +1,167 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% Author : Pawel Chmielowski <pawel@process-one.net>
|
||||
%%% Created : 1 Dec 2024 by Pawel Chmielowski <pawel@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2024 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(mod_auth_fast).
|
||||
-behaviour(gen_mod).
|
||||
-protocol({xep, 484, '0.2.0', '24.12', "complete", ""}).
|
||||
|
||||
%% gen_mod API
|
||||
-export([start/2, stop/1, reload/3, depends/2, mod_options/1, mod_opt_type/1]).
|
||||
-export([mod_doc/0]).
|
||||
%% Hooks
|
||||
-export([c2s_inline_features/2, c2s_handle_sasl2_inline/1,
|
||||
get_tokens/3, get_mechanisms/1]).
|
||||
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include_lib("xmpp/include/scram.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("translate.hrl").
|
||||
|
||||
-callback get_tokens(binary(), binary(), binary()) ->
|
||||
[{current | next, binary(), non_neg_integer()}].
|
||||
-callback rotate_token(binary(), binary(), binary()) ->
|
||||
ok | {error, atom()}.
|
||||
-callback del_token(binary(), binary(), binary(), current | next) ->
|
||||
ok | {error, atom()}.
|
||||
-callback set_token(binary(), binary(), binary(), current | next, binary(), non_neg_integer()) ->
|
||||
ok | {error, atom()}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
-spec start(binary(), gen_mod:opts()) -> {ok, [gen_mod:registration()]}.
|
||||
start(Host, Opts) ->
|
||||
Mod = gen_mod:db_mod(Opts, ?MODULE),
|
||||
Mod:init(Host, Opts),
|
||||
{ok, [{hook, c2s_inline_features, c2s_inline_features, 50},
|
||||
{hook, c2s_handle_sasl2_inline, c2s_handle_sasl2_inline, 10}]}.
|
||||
|
||||
-spec stop(binary()) -> ok.
|
||||
stop(_Host) ->
|
||||
ok.
|
||||
|
||||
-spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok.
|
||||
reload(Host, NewOpts, OldOpts) ->
|
||||
NewMod = gen_mod:db_mod(NewOpts, ?MODULE),
|
||||
OldMod = gen_mod:db_mod(OldOpts, ?MODULE),
|
||||
if NewMod /= OldMod ->
|
||||
NewMod:init(Host, NewOpts);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
ok.
|
||||
|
||||
-spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}].
|
||||
depends(_Host, _Opts) ->
|
||||
[].
|
||||
|
||||
-spec mod_opt_type(atom()) -> econf:validator().
|
||||
mod_opt_type(db_type) ->
|
||||
econf:db_type(?MODULE);
|
||||
mod_opt_type(token_lifetime) ->
|
||||
econf:timeout(second);
|
||||
mod_opt_type(token_refresh_age) ->
|
||||
econf:timeout(second).
|
||||
|
||||
-spec mod_options(binary()) -> [{atom(), any()}].
|
||||
mod_options(Host) ->
|
||||
[{db_type, ejabberd_config:default_db(Host, ?MODULE)},
|
||||
{token_lifetime, timer:hours(30*24)},
|
||||
{token_refresh_age, timer:hours(24)}].
|
||||
|
||||
mod_doc() ->
|
||||
#{desc =>
|
||||
[?T("The module adds support for "
|
||||
"https://xmpp.org/extensions/xep-0484.html"
|
||||
"[XEP-0480: Fast Authentication Streamlining Tokens] that allows users to authenticate "
|
||||
"using self managed tokens.")],
|
||||
note => "added in 24.12",
|
||||
opts =>
|
||||
[{db_type,
|
||||
#{value => "mnesia | sql",
|
||||
desc =>
|
||||
?T("Same as top-level _`default_db`_ option, but applied to this module only.")}},
|
||||
{token_lifetime,
|
||||
#{value => "timeout()",
|
||||
desc => ?T("Time that tokens will be keept, measured from it's creation time. "
|
||||
"Default value set to 30 days")}},
|
||||
{token_refresh_age,
|
||||
#{value => "timeout()",
|
||||
desc => ?T("This time determines age of token, that qualifies for automatic refresh. "
|
||||
"Default value set to 1 day")}}],
|
||||
example =>
|
||||
["modules:",
|
||||
" mod_auth_fast:",
|
||||
" token_timeout: 14days"]}.
|
||||
|
||||
get_mechanisms(_LServer) ->
|
||||
[<<"HT-SHA-256-NONE">>, <<"HT-SHA-256-UNIQ">>, <<"HT-SHA-256-EXPR">>, <<"HT-SHA-256-ENDP">>].
|
||||
|
||||
ua_hash(UA) ->
|
||||
crypto:hash(sha256, UA).
|
||||
|
||||
get_tokens(LServer, LUser, UA) ->
|
||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||
ToRefresh = erlang:system_time(second) - mod_auth_fast_opt:token_refresh_age(LServer),
|
||||
lists:map(
|
||||
fun({Type, Token, CreatedAt}) ->
|
||||
{{Type, CreatedAt < ToRefresh}, Token}
|
||||
end, Mod:get_tokens(LServer, LUser, ua_hash(UA))).
|
||||
|
||||
c2s_inline_features({Sasl, Bind, Extra}, Host) ->
|
||||
{Sasl ++ [#fast{mechs = get_mechanisms(Host)}], Bind, Extra}.
|
||||
|
||||
gen_token(#{sasl2_ua_id := UA, server := Server, user := User}) ->
|
||||
Mod = gen_mod:db_mod(Server, ?MODULE),
|
||||
Token = base64url:encode(ua_hash(<<UA/binary, (p1_rand:get_string())/binary>>)),
|
||||
ExpiresAt = erlang:system_time(second) + mod_auth_fast_opt:token_lifetime(Server),
|
||||
Mod:set_token(Server, User, ua_hash(UA), next, Token, ExpiresAt),
|
||||
#fast_token{token = Token, expiry = misc:usec_to_now(ExpiresAt)}.
|
||||
|
||||
c2s_handle_sasl2_inline({#{server := Server, user := User, sasl2_ua_id := UA,
|
||||
sasl2_axtra_auth_info := Extra} = State, Els, Results} = Acc) ->
|
||||
Mod = gen_mod:db_mod(Server, ?MODULE),
|
||||
?ERROR_MSG("inl ~p", [Extra]),
|
||||
NeedRegen =
|
||||
case Extra of
|
||||
{token, {next, Rotate}} ->
|
||||
Mod:rotate_token(Server, User, ua_hash(UA)),
|
||||
Rotate;
|
||||
{token, {_, true}} ->
|
||||
true;
|
||||
_ ->
|
||||
false
|
||||
end,
|
||||
case {lists:keyfind(fast_request_token, 1, Els), lists:keyfind(fast, 1, Els)} of
|
||||
{#fast_request_token{mech = _Mech}, #fast{invalidate = true}} ->
|
||||
Mod:del_token(Server, User, ua_hash(UA), current),
|
||||
{State, Els, [gen_token(State) | Results]};
|
||||
{_, #fast{invalidate = true}} ->
|
||||
Mod:del_token(Server, User, ua_hash(UA), current),
|
||||
Acc;
|
||||
{#fast_request_token{mech = _Mech}, _} ->
|
||||
{State, Els, [gen_token(State) | Results]};
|
||||
_ when NeedRegen ->
|
||||
{State, Els, [gen_token(State) | Results]};
|
||||
_ ->
|
||||
Acc
|
||||
end.
|
123
src/mod_auth_fast_mnesia.erl
Normal file
123
src/mod_auth_fast_mnesia.erl
Normal file
@ -0,0 +1,123 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : mod_announce_mnesia.erl
|
||||
%%% Author : Pawel Chmielowski <pawel@process-one.net>
|
||||
%%% Created : 1 Dec 2024 by Pawel Chmielowski <pawel@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2024 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License along
|
||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(mod_auth_fast_mnesia).
|
||||
|
||||
-behaviour(mod_auth_fast).
|
||||
|
||||
%% API
|
||||
-export([init/2]).
|
||||
-export([get_tokens/3, del_token/4, set_token/6, rotate_token/3]).
|
||||
|
||||
-include_lib("xmpp/include/xmpp.hrl").
|
||||
-include("logger.hrl").
|
||||
|
||||
-record(mod_auth_fast, {key = {<<"">>, <<"">>, <<"">>} :: {binary(), binary(), binary()} | '$1',
|
||||
token = <<>> :: binary() | '_',
|
||||
created_at = 0 :: non_neg_integer() | '_',
|
||||
expires_at = 0 :: non_neg_integer() | '_'}).
|
||||
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
init(_Host, _Opts) ->
|
||||
ejabberd_mnesia:create(?MODULE, mod_auth_fast,
|
||||
[{disc_only_copies, [node()]},
|
||||
{attributes,
|
||||
record_info(fields, mod_auth_fast)}]).
|
||||
|
||||
-spec get_tokens(binary(), binary(), binary()) ->
|
||||
[{current | next, binary(), non_neg_integer()}].
|
||||
get_tokens(LServer, LUser, UA) ->
|
||||
Now = erlang:system_time(second),
|
||||
case mnesia:dirty_read(mod_auth_fast, {LServer, LUser, token_id(UA, next)}) of
|
||||
[#mod_auth_fast{token = Token, created_at = Created, expires_at = Expires}] when Expires > Now ->
|
||||
[{next, Token, Created}];
|
||||
[#mod_auth_fast{}] ->
|
||||
del_token(LServer, LUser, UA, next),
|
||||
[];
|
||||
_ ->
|
||||
[]
|
||||
end ++
|
||||
case mnesia:dirty_read(mod_auth_fast, {LServer, LUser, token_id(UA, current)}) of
|
||||
[#mod_auth_fast{token = Token, created_at = Created, expires_at = Expires}] when Expires > Now ->
|
||||
[{current, Token, Created}];
|
||||
[#mod_auth_fast{}] ->
|
||||
del_token(LServer, LUser, UA, current),
|
||||
[];
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
-spec rotate_token(binary(), binary(), binary()) ->
|
||||
ok | {error, atom()}.
|
||||
rotate_token(LServer, LUser, UA) ->
|
||||
F = fun() ->
|
||||
case mnesia:dirty_read(mod_auth_fast, {LServer, LUser, token_id(UA, next)}) of
|
||||
[#mod_auth_fast{token = Token, created_at = Created, expires_at = Expires}] ->
|
||||
mnesia:write(#mod_auth_fast{key = {LServer, LUser, token_id(UA, current)},
|
||||
token = Token, created_at = Created,
|
||||
expires_at = Expires}),
|
||||
mnesia:delete({mod_auth_fast, {LServer, LUser, token_id(UA, next)}});
|
||||
_ ->
|
||||
ok
|
||||
end
|
||||
end,
|
||||
transaction(F).
|
||||
|
||||
-spec del_token(binary(), binary(), binary(), current | next) ->
|
||||
ok | {error, atom()}.
|
||||
del_token(LServer, LUser, UA, Type) ->
|
||||
F = fun() ->
|
||||
mnesia:delete({mod_auth_fast, {LServer, LUser, token_id(UA, Type)}})
|
||||
end,
|
||||
transaction(F).
|
||||
|
||||
-spec set_token(binary(), binary(), binary(), current | next, binary(), non_neg_integer()) ->
|
||||
ok | {error, atom()}.
|
||||
set_token(LServer, LUser, UA, Type, Token, Expires) ->
|
||||
F = fun() ->
|
||||
mnesia:write(#mod_auth_fast{key = {LServer, LUser, token_id(UA, Type)},
|
||||
token = Token, created_at = erlang:system_time(second),
|
||||
expires_at = Expires})
|
||||
end,
|
||||
transaction(F).
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%===================================================================
|
||||
|
||||
token_id(UA, current) ->
|
||||
<<"c:", UA/binary>>;
|
||||
token_id(UA, _) ->
|
||||
<<"n:", UA/binary>>.
|
||||
|
||||
transaction(F) ->
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, Res} ->
|
||||
Res;
|
||||
{aborted, Reason} ->
|
||||
?ERROR_MSG("Mnesia transaction failed: ~p", [Reason]),
|
||||
{error, db_failure}
|
||||
end.
|
27
src/mod_auth_fast_opt.erl
Normal file
27
src/mod_auth_fast_opt.erl
Normal file
@ -0,0 +1,27 @@
|
||||
%% Generated automatically
|
||||
%% DO NOT EDIT: run `make options` instead
|
||||
|
||||
-module(mod_auth_fast_opt).
|
||||
|
||||
-export([db_type/1]).
|
||||
-export([token_lifetime/1]).
|
||||
-export([token_refresh_age/1]).
|
||||
|
||||
-spec db_type(gen_mod:opts() | global | binary()) -> atom().
|
||||
db_type(Opts) when is_map(Opts) ->
|
||||
gen_mod:get_opt(db_type, Opts);
|
||||
db_type(Host) ->
|
||||
gen_mod:get_module_opt(Host, mod_auth_fast, db_type).
|
||||
|
||||
-spec token_lifetime(gen_mod:opts() | global | binary()) -> pos_integer().
|
||||
token_lifetime(Opts) when is_map(Opts) ->
|
||||
gen_mod:get_opt(token_lifetime, Opts);
|
||||
token_lifetime(Host) ->
|
||||
gen_mod:get_module_opt(Host, mod_auth_fast, token_lifetime).
|
||||
|
||||
-spec token_refresh_age(gen_mod:opts() | global | binary()) -> pos_integer().
|
||||
token_refresh_age(Opts) when is_map(Opts) ->
|
||||
gen_mod:get_opt(token_refresh_age, Opts);
|
||||
token_refresh_age(Host) ->
|
||||
gen_mod:get_module_opt(Host, mod_auth_fast, token_refresh_age).
|
||||
|
Loading…
Reference in New Issue
Block a user