1 |
|
-module(mod_domain_isolation). |
2 |
|
-behaviour(gen_mod). |
3 |
|
|
4 |
|
-include_lib("exml/include/exml.hrl"). |
5 |
|
-include_lib("jid/include/jid.hrl"). |
6 |
|
-include("mongoose_config_spec.hrl"). |
7 |
|
|
8 |
|
%% gen_mod handlers |
9 |
|
-export([start/2, stop/1]). |
10 |
|
-export([config_spec/0]). |
11 |
|
-export([supported_features/0]). |
12 |
|
|
13 |
|
%% hooks |
14 |
|
-export([filter_local_packet/1]). |
15 |
|
|
16 |
|
-ignore_xref([filter_local_packet/1]). |
17 |
|
|
18 |
|
-type fpacket() :: {From :: jid:jid(), |
19 |
|
To :: jid:jid(), |
20 |
|
Acc :: mongoose_acc:t(), |
21 |
|
Packet :: exml:element()}. |
22 |
|
|
23 |
|
-spec config_spec() -> mongoose_config_spec:config_section(). |
24 |
|
config_spec() -> |
25 |
164 |
#section{items = #{}}. |
26 |
|
|
27 |
|
start(HostType, _Opts) -> |
28 |
2 |
ejabberd_hooks:add(filter_local_packet, HostType, ?MODULE, filter_local_packet, 10). |
29 |
|
|
30 |
|
stop(HostType) -> |
31 |
2 |
ejabberd_hooks:delete(filter_local_packet, HostType, ?MODULE, filter_local_packet, 10). |
32 |
|
|
33 |
|
-spec supported_features() -> [atom()]. |
34 |
:-( |
supported_features() -> [dynamic_domains]. |
35 |
|
|
36 |
|
-spec filter_local_packet(Value :: fpacket() | drop) -> fpacket() | drop. |
37 |
|
filter_local_packet(drop) -> |
38 |
:-( |
drop; |
39 |
|
filter_local_packet({#jid{lserver = Server}, |
40 |
|
#jid{lserver = Server}, _Acc, _Packet} = Arg) -> |
41 |
29 |
Arg; |
42 |
|
filter_local_packet({#jid{lserver = FromServer} = From, |
43 |
|
#jid{lserver = ToServer} = To, Acc, _Packet} = Arg) -> |
44 |
8 |
FromHost = domain_to_host(FromServer), |
45 |
8 |
ToHost = domain_to_host(ToServer), |
46 |
8 |
case FromHost =:= ToHost of |
47 |
|
true -> |
48 |
2 |
Arg; |
49 |
|
false -> |
50 |
|
%% Allow errors from this module to be passed |
51 |
6 |
case mongoose_acc:get(domain_isolation, ignore, false, Acc) of |
52 |
|
true -> |
53 |
3 |
Arg; |
54 |
|
false -> |
55 |
3 |
maybe_send_back_error(From, To, Acc, Arg), |
56 |
3 |
drop |
57 |
|
end |
58 |
|
end. |
59 |
|
|
60 |
|
%% muc.localhost becomes localhost. |
61 |
|
%% localhost stays localhost. |
62 |
|
domain_to_host(Domain) -> |
63 |
16 |
case mongoose_domain_api:get_subdomain_info(Domain) of |
64 |
4 |
{ok, #{parent_domain := Parent}} when is_binary(Parent) -> Parent; |
65 |
12 |
_ -> Domain |
66 |
|
end. |
67 |
|
|
68 |
|
maybe_send_back_error(From, To, Acc, Arg) -> |
69 |
3 |
case mongoose_acc:stanza_type(Acc) of |
70 |
|
<<"error">> -> %% Never reply to the errors |
71 |
:-( |
Arg; |
72 |
|
_ -> |
73 |
3 |
Err = mongoose_xmpp_errors:service_unavailable(<<"en">>, |
74 |
|
<<"Filtered by the domain isolation">>), |
75 |
3 |
Acc2 = mongoose_acc:set_permanent(domain_isolation, ignore, true, Acc), |
76 |
3 |
send_back_error(Err, From, To, Acc2), |
77 |
3 |
drop |
78 |
|
end. |
79 |
|
|
80 |
|
send_back_error(Etype, From, To, Acc) -> |
81 |
3 |
{Acc1, Err} = jlib:make_error_reply(Acc, Etype), |
82 |
3 |
ejabberd_router:route(To, From, Acc1, Err). |