mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-02 16:37:52 +01:00
feat: support loading Elixir modules for auth
Allow to specify an Elixir module name in `auth_method`. If the referenced module, `M`, cannot be loaded as `ejabberd_auth_M`, try to load it as `Elixir.M`.
This commit is contained in:
parent
715b5b64c6
commit
17b5b34e3c
39
lib/ejabberd_auth_example.ex
Normal file
39
lib/ejabberd_auth_example.ex
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
defmodule ModAuthExample do
|
||||||
|
@moduledoc """
|
||||||
|
|
||||||
|
This is a dummy auth module to demonstrate the usage of Elixir to
|
||||||
|
create Ejabberd Auth modules.
|
||||||
|
|
||||||
|
"""
|
||||||
|
import Ejabberd.Logger
|
||||||
|
@behaviour :ejabberd_auth
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def start(host) do
|
||||||
|
info("Using mod_auth_example to authenticate #{host} users")
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def stop(host) do
|
||||||
|
info("Stop using mod_auth_example to authenticate #{host} users")
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def check_password("alice", _authz_id, _host, "secret"), do: {:nocache, true}
|
||||||
|
def check_password(_username, _authz_id, _host, _secret), do: {:nocache, false}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def user_exists("alice", _host), do: {:nocache, true}
|
||||||
|
def user_exists(_username, _host), do: {:nocache, false}
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def plain_password_required(_binary), do: true
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def store_type(_host), do: :external
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def use_cache(_host), do: false
|
||||||
|
end
|
@ -505,10 +505,15 @@ db_type(M) ->
|
|||||||
and_then(
|
and_then(
|
||||||
atom(),
|
atom(),
|
||||||
fun(T) ->
|
fun(T) ->
|
||||||
case code:ensure_loaded(db_module(M, T)) of
|
case code:ensure_loaded(db_module(M, T)) of
|
||||||
{module, _} -> T;
|
{module, _} -> T;
|
||||||
{error, _} -> fail({bad_db_type, M, T})
|
{error, _} ->
|
||||||
end
|
ElixirModule = "Elixir." ++ atom_to_list(T),
|
||||||
|
case code:ensure_loaded(list_to_atom(ElixirModule)) of
|
||||||
|
{module, _} -> list_to_atom(ElixirModule);
|
||||||
|
{error, _} -> fail({bad_db_type, M, T})
|
||||||
|
end
|
||||||
|
end
|
||||||
end).
|
end).
|
||||||
|
|
||||||
-spec queue_type() -> yconf:validator(ram | file).
|
-spec queue_type() -> yconf:validator(ram | file).
|
||||||
|
@ -177,6 +177,15 @@ module_name([Dir, _, <<H,_/binary>> | _] = Mod) when H >= 65, H =< 90 ->
|
|||||||
Lib -> <<"Elixir.Ejabberd.", Lib/binary, ".">>
|
Lib -> <<"Elixir.Ejabberd.", Lib/binary, ".">>
|
||||||
end,
|
end,
|
||||||
misc:binary_to_atom(<<Prefix/binary, Module/binary>>);
|
misc:binary_to_atom(<<Prefix/binary, Module/binary>>);
|
||||||
|
|
||||||
|
module_name([<<"auth">> | T] = Mod) ->
|
||||||
|
case hd(T) of
|
||||||
|
%% T already starts with "Elixir" if an Elixir module is
|
||||||
|
%% loaded with that name, as per `econf:db_type/1`
|
||||||
|
<<"Elixir", _/binary>> -> misc:binary_to_atom(hd(T));
|
||||||
|
_ -> module_name([<<"ejabberd">>] ++ Mod)
|
||||||
|
end;
|
||||||
|
|
||||||
module_name([<<"ejabberd">> | _] = Mod) ->
|
module_name([<<"ejabberd">> | _] = Mod) ->
|
||||||
Module = str:join([erlang_name(M) || M<-Mod], $_),
|
Module = str:join([erlang_name(M) || M<-Mod], $_),
|
||||||
misc:binary_to_atom(Module);
|
misc:binary_to_atom(Module);
|
||||||
|
@ -893,7 +893,7 @@ auth_modules() ->
|
|||||||
auth_modules(Server) ->
|
auth_modules(Server) ->
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
Methods = ejabberd_option:auth_method(LServer),
|
Methods = ejabberd_option:auth_method(LServer),
|
||||||
[ejabberd:module_name([<<"ejabberd">>, <<"auth">>,
|
[ejabberd:module_name([<<"auth">>,
|
||||||
misc:atom_to_binary(M)])
|
misc:atom_to_binary(M)])
|
||||||
|| M <- Methods].
|
|| M <- Methods].
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user