1 |
|
-module(mongoose_credentials). |
2 |
|
|
3 |
|
-export([make_opts/1, |
4 |
|
new/3, |
5 |
|
lserver/1, |
6 |
|
host_type/1, |
7 |
|
auth_modules/1, |
8 |
|
get/2, get/3, |
9 |
|
set/3, |
10 |
|
extend/2, |
11 |
|
register/3]). |
12 |
|
|
13 |
|
-export_type([t/0, opts/0]). |
14 |
|
|
15 |
|
-record(mongoose_credentials, {lserver, host_type, registry = [], extra = [], modules}). |
16 |
|
|
17 |
|
-type auth_event() :: any(). |
18 |
|
|
19 |
|
-opaque t() :: |
20 |
|
#mongoose_credentials{ %% These values are always present. |
21 |
|
lserver :: jid:lserver(), |
22 |
|
host_type :: mongooseim:host_type(), |
23 |
|
%% Authorization success / failure registry. |
24 |
|
registry :: [{mongoose_gen_auth:t(), auth_event()}], |
25 |
|
%% These values are dependent on the ejabberd_auth backend in use. |
26 |
|
%% Each backend may require different values to be present. |
27 |
|
extra :: [proplists:property()], |
28 |
|
modules :: [ejabberd_auth:authmodule()] }. |
29 |
|
|
30 |
|
-type opts() :: #{}. |
31 |
|
|
32 |
|
-spec make_opts(mongoose_listener:options()) -> opts(). |
33 |
|
make_opts(#{allowed_auth_methods := Methods}) -> |
34 |
2 |
#{allowed_modules => ejabberd_auth:methods_to_modules(Methods)}; |
35 |
|
make_opts(#{}) -> |
36 |
3659 |
#{}. |
37 |
|
|
38 |
|
-spec new(jid:lserver(), binary(), opts()) -> mongoose_credentials:t(). |
39 |
|
new(LServer, HostType, Opts) when is_binary(LServer), is_binary(HostType) -> |
40 |
4006 |
HostTypeModules = ejabberd_auth:auth_modules_for_host_type(HostType), |
41 |
4006 |
Modules = filter_modules(HostTypeModules, Opts), |
42 |
4006 |
#mongoose_credentials{lserver = LServer, host_type = HostType, |
43 |
|
modules = Modules}. |
44 |
|
|
45 |
|
%% Allows to enable only some modules for some listeners |
46 |
|
-spec filter_modules([ejabberd_auth:authmodule()], opts()) -> |
47 |
|
[ejabberd_auth:authmodule()]. |
48 |
|
filter_modules(Modules, #{allowed_modules := AllowedModules}) -> |
49 |
2 |
[M || M <- Modules, lists:member(M, AllowedModules)]; |
50 |
|
filter_modules(Modules, _) -> |
51 |
4004 |
Modules. |
52 |
|
|
53 |
|
-spec host_type(t()) -> mongooseim:host_type(). |
54 |
7319 |
host_type(#mongoose_credentials{host_type = HostType}) -> HostType. |
55 |
|
|
56 |
|
-spec lserver(t()) -> jid:lserver(). |
57 |
3723 |
lserver(#mongoose_credentials{lserver = S}) -> S. |
58 |
|
|
59 |
|
-spec auth_modules(t()) -> [ejabberd_auth:authmodule()]. |
60 |
3600 |
auth_modules(#mongoose_credentials{modules = Modules}) -> Modules. |
61 |
|
|
62 |
|
%% @doc Calls erlang:error/2 when Key is not found! |
63 |
|
-spec get(t(), Key) -> Value when |
64 |
|
Key :: any(), |
65 |
|
Value :: any(). |
66 |
|
get(#mongoose_credentials{extra = Extra} = C, Key) -> |
67 |
13672 |
case lists:keyfind(Key, 1, Extra) of |
68 |
:-( |
false -> error({not_found, Key}, [C, Key]); |
69 |
13672 |
{Key, Value} -> Value |
70 |
|
end. |
71 |
|
|
72 |
|
%% @doc Returns Default when Key is not found. |
73 |
|
-spec get(t(), Key, Default) -> Value when |
74 |
|
Key :: any(), |
75 |
|
Default :: any(), |
76 |
|
Value :: any(). |
77 |
|
get(#mongoose_credentials{extra = Extra}, Key, Default) -> |
78 |
17228 |
case lists:keyfind(Key, 1, Extra) of |
79 |
13872 |
false -> Default; |
80 |
3356 |
{Key, Value} -> Value |
81 |
|
end. |
82 |
|
|
83 |
|
-spec set(t(), Key, Value) -> t() when |
84 |
|
Key :: any(), |
85 |
|
Value :: any(). |
86 |
|
set(#mongoose_credentials{extra = Extra} = C, Key, Value) -> |
87 |
14327 |
NewExtra = lists:keystore(Key, 1, Extra, {Key, Value}), |
88 |
14327 |
C#mongoose_credentials{extra = NewExtra}. |
89 |
|
|
90 |
|
-spec extend(t(), [{Key, Value}]) -> t() when |
91 |
|
Key :: any(), |
92 |
|
Value :: any(). |
93 |
|
extend(#mongoose_credentials{} = C, KVPairs) -> |
94 |
3366 |
lists:foldl(fun ({K, V}, Creds) -> |
95 |
10066 |
?MODULE:set(Creds, K, V) |
96 |
|
end, C, KVPairs). |
97 |
|
|
98 |
|
-spec register(t(), mongoose_gen_auth:t(), auth_event()) -> t(). |
99 |
|
register(#mongoose_credentials{} = C, Mod, Event) -> |
100 |
3600 |
#mongoose_credentials{registry = R} = C, |
101 |
3600 |
C#mongoose_credentials{registry = [{Mod, Event} | R]}. |