Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi tenancy hooks #3089

Merged
merged 12 commits into from
Apr 22, 2021
Merged
14 changes: 11 additions & 3 deletions big_tests/tests/dynamic_domains_pm_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
-define(TEST_NODES, [mim() | ?CLUSTER_NODES]).
-define(CLUSTER_NODES, [mim2()]).
-define(DOMAINS, [<<"example.com">>, <<"example.org">>]).
-define(HOST_TYPE, <<"test type">>). %% preconfigured in the toml file

suite() ->
require_rpc_nodes([mim, mim2]).

all() ->
[can_authenticate,
pm_messages,
disconnected_on_domain_disabling].
disconnected_on_domain_disabling,
auth_domain_removal_is_triggered_on_hook].

init_per_suite(Config0) ->
Config = cluster_nodes(?CLUSTER_NODES, Config0),
Expand Down Expand Up @@ -60,11 +62,17 @@ disconnected_on_domain_disabling(Config) ->
end,
escalus:story(Config, [{alice3, 1}, {bob3, 1}], StoryFn).

auth_domain_removal_is_triggered_on_hook(_Config) ->
ok = rpc(mim(), meck, new, [ejabberd_auth_dummy, [passthrough, no_link]]),
Params = [?HOST_TYPE, <<"dummy.domain.name">>],
rpc(mim(), mongoose_hooks, remove_domain, Params),
1 = rpc(mim(), meck, num_calls, [ejabberd_auth_dummy, remove_domain, Params]),
rpc(mim(), meck, unload, [ejabberd_auth_dummy]).

%% helper functions
insert_domains(Nodes, Domains) ->
Source = dummy_source, %% can be anything, we don't care about it
HostType = <<"test type">>, %% preconfigured in the toml file
[ok = rpc(Node, mongoose_domain_core, insert, [Domain, HostType, Source]) ||
[ok = rpc(Node, mongoose_domain_core, insert, [Domain, ?HOST_TYPE, Source]) ||
Node <- Nodes, Domain <- Domains].

remove_domains(Nodes, Domains) ->
Expand Down
2 changes: 1 addition & 1 deletion big_tests/tests/ejabberdctl_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ end_per_group(Rosters, Config) when (Rosters == roster) or (Rosters == roster_ad
[#{ location => {?MODULE, ?FUNCTION_NAME, ?LINE},
lserver => SB,
element => undefined }]),
rpc(mim(), ejabberd_hooks, run_fold, [remove_user, SB, Acc, [UB, SB]]);
rpc(mim(), mongoose_hooks, remove_user, [SB, Acc, UB]);
_ ->
ok
end
Expand Down
4 changes: 2 additions & 2 deletions big_tests/tests/oauth_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,8 @@ extract_bound_jid(BindReply) ->
cdata]).

get_provision_key(Domain) ->
RPCArgs = [get_key, Domain, [], [{provision_pre_shared, Domain}]],
[{_, RawKey}] = rpc(mim(), ejabberd_hooks, run_fold, RPCArgs),
RPCArgs = [Domain, provision_pre_shared],
[{_, RawKey}] = rpc(mim(), mongoose_hooks, get_key, RPCArgs),
RawKey.

make_vcard(Config, User) ->
Expand Down
2 changes: 1 addition & 1 deletion src/admin_extra/service_admin_extra_gdpr.erl
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ get_data_from_modules(Username, Domain) ->

-spec get_data_from_modules(jid:jid()) -> gdpr:personal_data().
get_data_from_modules(JID) ->
mongoose_hooks:get_personal_data(JID#jid.lserver, [], JID).
mongoose_hooks:get_personal_data(JID#jid.lserver, JID).

-spec to_csv_file(CsvFilename :: binary(), gdpr:schema(), gdpr:entities(), file:name()) -> ok.
to_csv_file(Filename, DataSchema, DataRows, TmpDir) ->
Expand Down
17 changes: 16 additions & 1 deletion src/auth/ejabberd_auth.erl
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ start() ->
-spec start(HostType :: binary()) -> 'ok'.
start(HostType) ->
ensure_metrics(HostType),
ejabberd_hooks:add(remove_domain, global, fun remove_domain/3, 50),
lists:foreach(
fun(M) ->
M:start(HostType)
end, auth_modules_for_host_type(HostType)).

-spec stop(HostType :: binary()) -> 'ok'.
stop(HostType) ->
ejabberd_hooks:delete(remove_domain, global, fun remove_domain/3, 50),
lists:foreach(
fun(M) ->
M:stop(HostType)
Expand Down Expand Up @@ -270,7 +272,7 @@ do_try_register_in_backend([], _, _, _, _) ->
do_try_register_in_backend([M | Backends], HostType, LUser, LServer, Password) ->
case M:try_register(HostType, LUser, LServer, Password) of
ok ->
mongoose_hooks:register_user(LServer, ok, LUser);
mongoose_hooks:register_user(LServer, LUser);
_ ->
do_try_register_in_backend(Backends, HostType, LUser, LServer, Password)
end.
Expand Down Expand Up @@ -503,6 +505,19 @@ get_auth_method_as_a_list(undefined) -> [];
get_auth_method_as_a_list(AuthMethod) when is_list(AuthMethod) -> AuthMethod;
get_auth_method_as_a_list(AuthMethod) when is_atom(AuthMethod) -> [AuthMethod].

remove_domain(Acc, HostType, Domain) ->
Modules = auth_modules_for_host_type(HostType),
lists:foreach(fun(M) -> maybe_return_domain(M, HostType, Domain) end, Modules),
Acc.

maybe_return_domain(Module, HostType, Domain) ->
chrzaszcz marked this conversation as resolved.
Show resolved Hide resolved
%% removal of domain can be triggered only from the dynamic domains service,
%% all the auth modules should be loaded and initialised by that time
case erlang:function_exported(Module, remove_domain, 2) of
true -> erlang:apply(Module, remove_domain, [HostType, Domain]);
false -> ok
end.

ensure_metrics(Host) ->
Metrics = [authorize, check_password, try_register, does_user_exist],
[mongoose_metrics:ensure_metric(Host, ?METRIC(Metric), histogram)
Expand Down
2 changes: 1 addition & 1 deletion src/auth/ejabberd_auth_anonymous.erl
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ remove_connection(SID, LUser, LServer) ->
register_connection(Acc, SID, #jid{luser = LUser, lserver = LServer}, Info) ->
case lists:keyfind(auth_module, 1, Info) of
{_, ?MODULE} ->
mongoose_hooks:register_user(LServer, ok, LUser),
mongoose_hooks:register_user(LServer, LUser),
US = {LUser, LServer},
mnesia:sync_dirty(
fun() -> mnesia:write(#anonymous{us = US, sid=SID})
Expand Down
4 changes: 2 additions & 2 deletions src/auth/ejabberd_auth_dummy.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
check_password/4,
check_password/6,
authorize/1,
remove_domain/1,
remove_domain/2,
supported_features/0]).

%% ejabberd_auth compatibility layer - not supported features
Expand Down Expand Up @@ -92,7 +92,7 @@ does_user_exist(_User, _Server) ->
remove_user(_User, _Server) ->
ok.

remove_domain(_Server) -> ok.
remove_domain(_HostType, _Server) -> ok.
chrzaszcz marked this conversation as resolved.
Show resolved Hide resolved

supported_features() -> [dynamic_domains].

Expand Down
5 changes: 3 additions & 2 deletions src/auth/ejabberd_gen_auth.erl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
Server :: jid:lserver()
) -> ok | {error, not_allowed}.

-callback remove_domain(Server :: jid:lserver()) -> ok | {error, term()}.
-callback remove_domain(HostType :: binary(), Server :: jid:lserver()) ->
ok | {error, term()}.

-callback supported_features() -> [Feature::atom()].

Expand All @@ -78,7 +79,7 @@
Digest :: binary(),
DigestGen :: fun()) -> boolean().

-optional_callbacks([remove_domain/1, supported_features/0]).
-optional_callbacks([remove_domain/2, supported_features/0]).

-export_type([t/0]).

Expand Down
Loading