mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
Don't validate an option in gen_mod:get*opt() functions
The changes are very similar to those from previous commit: * Now there is no need to pass validating function in gen_mod:get_opt() and gen_mod:get_module_opt() functions, because the modules' configuration keeps already validated values. * New functions gen_mod:get_opt/2 and gen_mod:get_module_opt/3 are introduced. * Functions gen_mod:get_opt/4 and get_module_opt/5 are deprecated. If the functions are still called, the "function" argument is simply ignored. * Validating callback Mod:listen_opt_type/1 is introduced to validate listening options at startup.
This commit is contained in:
parent
2b63d07329
commit
fddd6110e0
@ -364,24 +364,11 @@ parse_options(Host) ->
|
|||||||
Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?MODULE)),
|
Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?MODULE)),
|
||||||
Bind_Eldap_ID = misc:atom_to_binary(
|
Bind_Eldap_ID = misc:atom_to_binary(
|
||||||
gen_mod:get_module_proc(Host, bind_ejabberd_auth_ldap)),
|
gen_mod:get_module_proc(Host, bind_ejabberd_auth_ldap)),
|
||||||
UIDsTemp = gen_mod:get_opt(
|
UIDsTemp = ejabberd_config:get_option(
|
||||||
{ldap_uids, Host}, [],
|
{ldap_uids, Host}, [{<<"uid">>, <<"%u">>}]),
|
||||||
fun(Us) ->
|
|
||||||
lists:map(
|
|
||||||
fun({U, P}) ->
|
|
||||||
{iolist_to_binary(U),
|
|
||||||
iolist_to_binary(P)};
|
|
||||||
({U}) ->
|
|
||||||
{iolist_to_binary(U)};
|
|
||||||
(U) ->
|
|
||||||
{iolist_to_binary(U)}
|
|
||||||
end, lists:flatten(Us))
|
|
||||||
end, [{<<"uid">>, <<"%u">>}]),
|
|
||||||
UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp),
|
UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp),
|
||||||
SubFilter = eldap_utils:generate_subfilter(UIDs),
|
SubFilter = eldap_utils:generate_subfilter(UIDs),
|
||||||
UserFilter = case gen_mod:get_opt(
|
UserFilter = case ejabberd_config:get_option({ldap_filter, Host}, <<"">>) of
|
||||||
{ldap_filter, Host}, [],
|
|
||||||
fun eldap_utils:check_filter/1, <<"">>) of
|
|
||||||
<<"">> ->
|
<<"">> ->
|
||||||
SubFilter;
|
SubFilter;
|
||||||
F ->
|
F ->
|
||||||
@ -390,20 +377,8 @@ parse_options(Host) ->
|
|||||||
SearchFilter = eldap_filter:do_sub(UserFilter,
|
SearchFilter = eldap_filter:do_sub(UserFilter,
|
||||||
[{<<"%u">>, <<"*">>}]),
|
[{<<"%u">>, <<"*">>}]),
|
||||||
{DNFilter, DNFilterAttrs} =
|
{DNFilter, DNFilterAttrs} =
|
||||||
gen_mod:get_opt({ldap_dn_filter, Host}, [],
|
ejabberd_config:get_option({ldap_dn_filter, Host}, {undefined, []}),
|
||||||
fun([{DNF, DNFA}]) ->
|
LocalFilter = ejabberd_config:get_option({ldap_local_filter, Host}),
|
||||||
NewDNFA = case DNFA of
|
|
||||||
undefined ->
|
|
||||||
[];
|
|
||||||
_ ->
|
|
||||||
[iolist_to_binary(A)
|
|
||||||
|| A <- DNFA]
|
|
||||||
end,
|
|
||||||
NewDNF = eldap_utils:check_filter(DNF),
|
|
||||||
{NewDNF, NewDNFA}
|
|
||||||
end, {undefined, []}),
|
|
||||||
LocalFilter = gen_mod:get_opt(
|
|
||||||
{ldap_local_filter, Host}, [], fun(V) -> V end),
|
|
||||||
#state{host = Host, eldap_id = Eldap_ID,
|
#state{host = Host, eldap_id = Eldap_ID,
|
||||||
bind_eldap_id = Bind_Eldap_ID,
|
bind_eldap_id = Bind_Eldap_ID,
|
||||||
servers = Cfg#eldap_config.servers,
|
servers = Cfg#eldap_config.servers,
|
||||||
|
@ -299,10 +299,7 @@ init([#body{attrs = Attrs}, IP, SID]) ->
|
|||||||
XMPPVer = get_attr('xmpp:version', Attrs),
|
XMPPVer = get_attr('xmpp:version', Attrs),
|
||||||
XMPPDomain = get_attr(to, Attrs),
|
XMPPDomain = get_attr(to, Attrs),
|
||||||
{InBuf, Opts} = case gen_mod:get_module_opt(
|
{InBuf, Opts} = case gen_mod:get_module_opt(
|
||||||
XMPPDomain,
|
XMPPDomain, mod_bosh, prebind, false) of
|
||||||
mod_bosh, prebind,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false) of
|
|
||||||
true ->
|
true ->
|
||||||
JID = make_random_jid(XMPPDomain),
|
JID = make_random_jid(XMPPDomain),
|
||||||
{buf_new(XMPPDomain), [{jid, JID} | Opts2]};
|
{buf_new(XMPPDomain), [{jid, JID} | Opts2]};
|
||||||
@ -315,12 +312,9 @@ init([#body{attrs = Attrs}, IP, SID]) ->
|
|||||||
Opts),
|
Opts),
|
||||||
Inactivity = gen_mod:get_module_opt(XMPPDomain,
|
Inactivity = gen_mod:get_module_opt(XMPPDomain,
|
||||||
mod_bosh, max_inactivity,
|
mod_bosh, max_inactivity,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
?DEFAULT_INACTIVITY),
|
?DEFAULT_INACTIVITY),
|
||||||
MaxConcat = gen_mod:get_module_opt(XMPPDomain, mod_bosh, max_concat,
|
MaxConcat = gen_mod:get_module_opt(XMPPDomain, mod_bosh, max_concat,
|
||||||
fun(unlimited) -> unlimited;
|
unlimited),
|
||||||
(N) when is_integer(N), N>0 -> N
|
|
||||||
end, unlimited),
|
|
||||||
ShapedReceivers = buf_new(XMPPDomain, ?MAX_SHAPED_REQUESTS_QUEUE_LEN),
|
ShapedReceivers = buf_new(XMPPDomain, ?MAX_SHAPED_REQUESTS_QUEUE_LEN),
|
||||||
State = #state{host = XMPPDomain, sid = SID, ip = IP,
|
State = #state{host = XMPPDomain, sid = SID, ip = IP,
|
||||||
xmpp_ver = XMPPVer, el_ibuf = InBuf,
|
xmpp_ver = XMPPVer, el_ibuf = InBuf,
|
||||||
@ -366,7 +360,6 @@ wait_for_session(#body{attrs = Attrs} = Req, From,
|
|||||||
end,
|
end,
|
||||||
MaxPause = gen_mod:get_module_opt(State#state.host,
|
MaxPause = gen_mod:get_module_opt(State#state.host,
|
||||||
mod_bosh, max_pause,
|
mod_bosh, max_pause,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
?DEFAULT_MAXPAUSE),
|
?DEFAULT_MAXPAUSE),
|
||||||
Resp = #body{attrs =
|
Resp = #body{attrs =
|
||||||
[{sid, State#state.sid}, {wait, Wait},
|
[{sid, State#state.sid}, {wait, Wait},
|
||||||
@ -1039,12 +1032,9 @@ buf_new(Host) ->
|
|||||||
buf_new(Host, unlimited).
|
buf_new(Host, unlimited).
|
||||||
|
|
||||||
buf_new(Host, Limit) ->
|
buf_new(Host, Limit) ->
|
||||||
QueueType = case gen_mod:get_module_opt(
|
QueueType = gen_mod:get_module_opt(
|
||||||
Host, mod_bosh, queue_type,
|
Host, mod_bosh, queue_type,
|
||||||
mod_bosh:mod_opt_type(queue_type)) of
|
ejabberd_config:default_queue_type(Host)),
|
||||||
undefined -> ejabberd_config:default_queue_type(Host);
|
|
||||||
T -> T
|
|
||||||
end,
|
|
||||||
p1_queue:new(QueueType, Limit).
|
p1_queue:new(QueueType, Limit).
|
||||||
|
|
||||||
buf_in(Xs, Buf) ->
|
buf_in(Xs, Buf) ->
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
%% ejabberd_socket callbacks
|
%% ejabberd_socket callbacks
|
||||||
-export([start/2, start_link/2, socket_type/0]).
|
-export([start/2, start_link/2, socket_type/0]).
|
||||||
%% ejabberd_config callbacks
|
%% ejabberd_config callbacks
|
||||||
-export([opt_type/1, transform_listen_option/2]).
|
-export([opt_type/1, listen_opt_type/1, transform_listen_option/2]).
|
||||||
%% xmpp_stream_in callbacks
|
%% xmpp_stream_in callbacks
|
||||||
-export([init/1, handle_call/3, handle_cast/2,
|
-export([init/1, handle_call/3, handle_cast/2,
|
||||||
handle_info/2, terminate/2, code_change/3]).
|
handle_info/2, terminate/2, code_change/3]).
|
||||||
@ -490,30 +490,25 @@ handle_send(Pkt, Result, #{lserver := LServer} = State) ->
|
|||||||
ejabberd_hooks:run_fold(c2s_handle_send, LServer, State, [Pkt, Result]).
|
ejabberd_hooks:run_fold(c2s_handle_send, LServer, State, [Pkt, Result]).
|
||||||
|
|
||||||
init([State, Opts]) ->
|
init([State, Opts]) ->
|
||||||
Access = gen_mod:get_opt(access, Opts, fun acl:access_rules_validator/1, all),
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
Shaper = gen_mod:get_opt(shaper, Opts, fun acl:shaper_rules_validator/1, none),
|
Shaper = gen_mod:get_opt(shaper, Opts, none),
|
||||||
TLSOpts1 = lists:filter(
|
TLSOpts1 = lists:filter(
|
||||||
fun({certfile, _}) -> true;
|
fun({certfile, _}) -> true;
|
||||||
({ciphers, _}) -> true;
|
({ciphers, _}) -> true;
|
||||||
({dhfile, _}) -> true;
|
({dhfile, _}) -> true;
|
||||||
({cafile, _}) -> true;
|
({cafile, _}) -> true;
|
||||||
|
({protocol_options, _}) -> true;
|
||||||
(_) -> false
|
(_) -> false
|
||||||
end, Opts),
|
end, Opts),
|
||||||
TLSOpts2 = case lists:keyfind(protocol_options, 1, Opts) of
|
TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of
|
||||||
false -> TLSOpts1;
|
false -> [compression_none | TLSOpts1];
|
||||||
{_, OptString} ->
|
true -> TLSOpts1
|
||||||
ProtoOpts = str:join(OptString, <<$|>>),
|
|
||||||
[{protocol_options, ProtoOpts}|TLSOpts1]
|
|
||||||
end,
|
|
||||||
TLSOpts3 = case proplists:get_bool(tls_compression, Opts) of
|
|
||||||
false -> [compression_none | TLSOpts2];
|
|
||||||
true -> TLSOpts2
|
|
||||||
end,
|
end,
|
||||||
TLSEnabled = proplists:get_bool(starttls, Opts),
|
TLSEnabled = proplists:get_bool(starttls, Opts),
|
||||||
TLSRequired = proplists:get_bool(starttls_required, Opts),
|
TLSRequired = proplists:get_bool(starttls_required, Opts),
|
||||||
TLSVerify = proplists:get_bool(tls_verify, Opts),
|
TLSVerify = proplists:get_bool(tls_verify, Opts),
|
||||||
Zlib = proplists:get_bool(zlib, Opts),
|
Zlib = proplists:get_bool(zlib, Opts),
|
||||||
State1 = State#{tls_options => TLSOpts3,
|
State1 = State#{tls_options => TLSOpts2,
|
||||||
tls_required => TLSRequired,
|
tls_required => TLSRequired,
|
||||||
tls_enabled => TLSEnabled,
|
tls_enabled => TLSEnabled,
|
||||||
tls_verify => TLSVerify,
|
tls_verify => TLSVerify,
|
||||||
@ -660,9 +655,7 @@ process_presence_out(#{user := User, server := Server, lserver := LServer,
|
|||||||
send_error(State, Pres, Err);
|
send_error(State, Pres, Err);
|
||||||
allow when Type == subscribe; Type == subscribed;
|
allow when Type == subscribe; Type == subscribed;
|
||||||
Type == unsubscribe; Type == unsubscribed ->
|
Type == unsubscribe; Type == unsubscribed ->
|
||||||
Access = gen_mod:get_module_opt(LServer, mod_roster, access,
|
Access = gen_mod:get_module_opt(LServer, mod_roster, access, all),
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
all),
|
|
||||||
MyBareJID = jid:remove_resource(JID),
|
MyBareJID = jid:remove_resource(JID),
|
||||||
case acl:match_rule(LServer, Access, MyBareJID) of
|
case acl:match_rule(LServer, Access, MyBareJID) of
|
||||||
deny ->
|
deny ->
|
||||||
@ -926,3 +919,36 @@ opt_type(_) ->
|
|||||||
[c2s_certfile, c2s_ciphers, c2s_cafile,
|
[c2s_certfile, c2s_ciphers, c2s_cafile,
|
||||||
c2s_protocol_options, c2s_tls_compression, resource_conflict,
|
c2s_protocol_options, c2s_tls_compression, resource_conflict,
|
||||||
disable_sasl_mechanisms].
|
disable_sasl_mechanisms].
|
||||||
|
|
||||||
|
listen_opt_type(access) -> fun acl:access_rules_validator/1;
|
||||||
|
listen_opt_type(shaper) -> fun acl:shaper_rules_validator/1;
|
||||||
|
listen_opt_type(certfile) -> opt_type(c2s_certfile);
|
||||||
|
listen_opt_type(ciphers) -> opt_type(c2s_ciphers);
|
||||||
|
listen_opt_type(dhfile) -> opt_type(c2s_dhfile);
|
||||||
|
listen_opt_type(cafile) -> opt_type(c2s_cafile);
|
||||||
|
listen_opt_type(protocol_options) -> opt_type(c2s_protocol_options);
|
||||||
|
listen_opt_type(tls_compression) -> opt_type(c2s_tls_compression);
|
||||||
|
listen_opt_type(tls) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(starttls) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(starttls_required) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(tls_verify) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(zlib) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(supervisor) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(max_stanza_size) ->
|
||||||
|
fun(I) when is_integer(I) -> I;
|
||||||
|
(unlimited) -> infinity;
|
||||||
|
(infinity) -> infinity
|
||||||
|
end;
|
||||||
|
listen_opt_type(max_fsm_queue) ->
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end;
|
||||||
|
listen_opt_type(O) ->
|
||||||
|
%% This hack should be removed in future releases: it is intended
|
||||||
|
%% for backward compatibility with ejabberd 17.01 or older
|
||||||
|
case mod_stream_mgmt:mod_opt_type(O) of
|
||||||
|
L when is_list(L) ->
|
||||||
|
[access, shaper, certfile, ciphers, dhfile, cafile,
|
||||||
|
protocol_options, tls, tls_compression, starttls,
|
||||||
|
starttls_required, tls_verify, zlib, max_fsm_queue] ++ L;
|
||||||
|
VFun ->
|
||||||
|
VFun
|
||||||
|
end.
|
||||||
|
@ -614,12 +614,12 @@ execute_check_access(undefined, _Command, _Arguments) ->
|
|||||||
execute_check_access(FromJID, #ejabberd_commands{access = AccessRefs} = Command, Arguments) ->
|
execute_check_access(FromJID, #ejabberd_commands{access = AccessRefs} = Command, Arguments) ->
|
||||||
%% TODO Review: Do we have smarter / better way to check rule on other Host than global ?
|
%% TODO Review: Do we have smarter / better way to check rule on other Host than global ?
|
||||||
Host = global,
|
Host = global,
|
||||||
Rules = lists:map(fun({Mod, AccessName, Default}) ->
|
Rules = lists:map(
|
||||||
gen_mod:get_module_opt(Host, Mod,
|
fun({Mod, AccessName, Default}) ->
|
||||||
AccessName, fun(A) -> A end, Default);
|
gen_mod:get_module_opt(Host, Mod, AccessName, Default);
|
||||||
(Default) ->
|
(Default) ->
|
||||||
Default
|
Default
|
||||||
end, AccessRefs),
|
end, AccessRefs),
|
||||||
case acl:any_rules_allowed(Host, Rules, FromJID) of
|
case acl:any_rules_allowed(Host, Rules, FromJID) of
|
||||||
true ->
|
true ->
|
||||||
do_execute_command(Command, Arguments);
|
do_execute_command(Command, Arguments);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
%% External exports
|
%% External exports
|
||||||
-export([start/2, start_link/2, become_controller/1,
|
-export([start/2, start_link/2, become_controller/1,
|
||||||
socket_type/0, receive_headers/1, url_encode/1,
|
socket_type/0, receive_headers/1, url_encode/1,
|
||||||
transform_listen_option/2]).
|
transform_listen_option/2, listen_opt_type/1]).
|
||||||
|
|
||||||
-export([init/2, opt_type/1]).
|
-export([init/2, opt_type/1]).
|
||||||
|
|
||||||
@ -100,23 +100,15 @@ init({SockMod, Socket}, Opts) ->
|
|||||||
TLSOpts1 = lists:filter(fun ({certfile, _}) -> true;
|
TLSOpts1 = lists:filter(fun ({certfile, _}) -> true;
|
||||||
({ciphers, _}) -> true;
|
({ciphers, _}) -> true;
|
||||||
({dhfile, _}) -> true;
|
({dhfile, _}) -> true;
|
||||||
|
({protocol_options, _}) -> true;
|
||||||
(_) -> false
|
(_) -> false
|
||||||
end,
|
end,
|
||||||
Opts),
|
Opts),
|
||||||
TLSOpts2 = case lists:keysearch(protocol_options, 1, Opts) of
|
TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of
|
||||||
{value, {_, O}} ->
|
false -> [compression_none | TLSOpts1];
|
||||||
[_|ProtocolOptions] = lists:foldl(
|
true -> TLSOpts1
|
||||||
fun(X, Acc) -> X ++ Acc end, [],
|
|
||||||
[["|" | binary_to_list(Opt)] || Opt <- O, is_binary(Opt)]
|
|
||||||
),
|
|
||||||
[{protocol_options, iolist_to_binary(ProtocolOptions)} | TLSOpts1];
|
|
||||||
_ -> TLSOpts1
|
|
||||||
end,
|
end,
|
||||||
TLSOpts3 = case proplists:get_bool(tls_compression, Opts) of
|
TLSOpts = [verify_none | TLSOpts2],
|
||||||
false -> [compression_none | TLSOpts2];
|
|
||||||
true -> TLSOpts2
|
|
||||||
end,
|
|
||||||
TLSOpts = [verify_none | TLSOpts3],
|
|
||||||
{SockMod1, Socket1} = if TLSEnabled ->
|
{SockMod1, Socket1} = if TLSEnabled ->
|
||||||
inet:setopts(Socket, [{recbuf, 8192}]),
|
inet:setopts(Socket, [{recbuf, 8192}]),
|
||||||
{ok, TLSSocket} = fast_tls:tcp_to_tls(Socket,
|
{ok, TLSSocket} = fast_tls:tcp_to_tls(Socket,
|
||||||
@ -144,33 +136,15 @@ init({SockMod, Socket}, Opts) ->
|
|||||||
true -> [{[], ejabberd_xmlrpc}];
|
true -> [{[], ejabberd_xmlrpc}];
|
||||||
false -> []
|
false -> []
|
||||||
end,
|
end,
|
||||||
DefinedHandlers = gen_mod:get_opt(
|
DefinedHandlers = gen_mod:get_opt(request_handlers, Opts, []),
|
||||||
request_handlers, Opts,
|
|
||||||
fun(Hs) ->
|
|
||||||
Hs1 = lists:map(fun
|
|
||||||
({Mod, Path}) when is_atom(Mod) -> {Path, Mod};
|
|
||||||
({Path, Mod}) -> {Path, Mod}
|
|
||||||
end, Hs),
|
|
||||||
|
|
||||||
Hs2 = [{str:tokens(
|
|
||||||
iolist_to_binary(Path), <<"/">>),
|
|
||||||
Mod} || {Path, Mod} <- Hs1],
|
|
||||||
[{Path,
|
|
||||||
case Mod of
|
|
||||||
mod_http_bind -> mod_bosh;
|
|
||||||
_ -> Mod
|
|
||||||
end} || {Path, Mod} <- Hs2]
|
|
||||||
end, []),
|
|
||||||
RequestHandlers = DefinedHandlers ++ Captcha ++ Register ++
|
RequestHandlers = DefinedHandlers ++ Captcha ++ Register ++
|
||||||
Admin ++ Bind ++ XMLRPC,
|
Admin ++ Bind ++ XMLRPC,
|
||||||
?DEBUG("S: ~p~n", [RequestHandlers]),
|
?DEBUG("S: ~p~n", [RequestHandlers]),
|
||||||
|
|
||||||
DefaultHost = gen_mod:get_opt(default_host, Opts, fun(A) -> A end, undefined),
|
DefaultHost = gen_mod:get_opt(default_host, Opts, undefined),
|
||||||
{ok, RE} = re:compile(<<"^(?:\\[(.*?)\\]|(.*?))(?::(\\d+))?$">>),
|
{ok, RE} = re:compile(<<"^(?:\\[(.*?)\\]|(.*?))(?::(\\d+))?$">>),
|
||||||
|
|
||||||
CustomHeaders = gen_mod:get_opt(custom_headers, Opts,
|
CustomHeaders = gen_mod:get_opt(custom_headers, Opts, []),
|
||||||
fun expand_custom_headers/1,
|
|
||||||
[]),
|
|
||||||
|
|
||||||
?INFO_MSG("started: ~p", [{SockMod1, Socket1}]),
|
?INFO_MSG("started: ~p", [{SockMod1, Socket1}]),
|
||||||
State = #state{sockmod = SockMod1,
|
State = #state{sockmod = SockMod1,
|
||||||
@ -929,3 +903,48 @@ opt_type(trusted_proxies) ->
|
|||||||
fun (all) -> all;
|
fun (all) -> all;
|
||||||
(TPs) -> [iolist_to_binary(TP) || TP <- TPs] end;
|
(TPs) -> [iolist_to_binary(TP) || TP <- TPs] end;
|
||||||
opt_type(_) -> [trusted_proxies].
|
opt_type(_) -> [trusted_proxies].
|
||||||
|
|
||||||
|
listen_opt_type(tls) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(certfile) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(ciphers) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(dhfile) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(protocol_options) ->
|
||||||
|
fun(Options) -> str:join(Options, <<"|">>) end;
|
||||||
|
listen_opt_type(tls_compression) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(captcha) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(register) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(web_admin) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(http_bind) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(xmlrpc) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(request_handlers) ->
|
||||||
|
fun(Hs) ->
|
||||||
|
Hs1 = lists:map(fun
|
||||||
|
({Mod, Path}) when is_atom(Mod) -> {Path, Mod};
|
||||||
|
({Path, Mod}) -> {Path, Mod}
|
||||||
|
end, Hs),
|
||||||
|
Hs2 = [{str:tokens(
|
||||||
|
iolist_to_binary(Path), <<"/">>),
|
||||||
|
Mod} || {Path, Mod} <- Hs1],
|
||||||
|
[{Path,
|
||||||
|
case Mod of
|
||||||
|
mod_http_bind -> mod_bosh;
|
||||||
|
_ -> Mod
|
||||||
|
end} || {Path, Mod} <- Hs2]
|
||||||
|
end;
|
||||||
|
listen_opt_type(default_host) ->
|
||||||
|
fun(A) -> A end;
|
||||||
|
listen_opt_type(custom_headers) ->
|
||||||
|
fun expand_custom_headers/1;
|
||||||
|
listen_opt_type(_) ->
|
||||||
|
%% TODO
|
||||||
|
fun(A) -> A end.
|
||||||
|
@ -52,7 +52,6 @@ listeners_childspec() ->
|
|||||||
Ls = ejabberd_config:get_option(listen, []),
|
Ls = ejabberd_config:get_option(listen, []),
|
||||||
Specs = lists:map(
|
Specs = lists:map(
|
||||||
fun({Port, Module, Opts}) ->
|
fun({Port, Module, Opts}) ->
|
||||||
maybe_start_sip(Module),
|
|
||||||
ets:insert(?MODULE, {Port, Module, Opts}),
|
ets:insert(?MODULE, {Port, Module, Opts}),
|
||||||
{Port,
|
{Port,
|
||||||
{?MODULE, start, [Port, Module, Opts]},
|
{?MODULE, start, [Port, Module, Opts]},
|
||||||
@ -82,10 +81,11 @@ report_duplicated_portips(L) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
start(Port, Module, Opts) ->
|
start(Port, Module, Opts) ->
|
||||||
|
NewOpts = validate_module_options(Module, Opts),
|
||||||
%% Check if the module is an ejabberd listener or an independent listener
|
%% Check if the module is an ejabberd listener or an independent listener
|
||||||
case Module:socket_type() of
|
case Module:socket_type() of
|
||||||
independent -> Module:start_listener(Port, Opts);
|
independent -> Module:start_listener(Port, NewOpts);
|
||||||
_ -> start_dependent(Port, Module, Opts)
|
_ -> start_dependent(Port, Module, NewOpts)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @spec(Port, Module, Opts) -> {ok, Pid} | {error, ErrorMessage}
|
%% @spec(Port, Module, Opts) -> {ok, Pid} | {error, ErrorMessage}
|
||||||
@ -356,7 +356,6 @@ start_listener2(Port, Module, Opts) ->
|
|||||||
%% It is only required to start the supervisor in some cases.
|
%% It is only required to start the supervisor in some cases.
|
||||||
%% But it doesn't hurt to attempt to start it for any listener.
|
%% But it doesn't hurt to attempt to start it for any listener.
|
||||||
%% So, it's normal (and harmless) that in most cases this call returns: {error, {already_started, pid()}}
|
%% So, it's normal (and harmless) that in most cases this call returns: {error, {already_started, pid()}}
|
||||||
maybe_start_sip(Module),
|
|
||||||
start_listener_sup(Port, Module, Opts).
|
start_listener_sup(Port, Module, Opts).
|
||||||
|
|
||||||
start_module_sup(_Port, Module) ->
|
start_module_sup(_Port, Module) ->
|
||||||
@ -427,12 +426,6 @@ delete_listener(PortIP, Module, Opts) ->
|
|||||||
PortIP1 = {Port, IPT, Proto},
|
PortIP1 = {Port, IPT, Proto},
|
||||||
stop_listener(PortIP1, Module).
|
stop_listener(PortIP1, Module).
|
||||||
|
|
||||||
|
|
||||||
maybe_start_sip(esip_socket) ->
|
|
||||||
ejabberd:start_app(esip);
|
|
||||||
maybe_start_sip(_) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
config_reloaded() ->
|
config_reloaded() ->
|
||||||
New = ejabberd_config:get_option(listen, []),
|
New = ejabberd_config:get_option(listen, []),
|
||||||
Old = ets:tab2list(?MODULE),
|
Old = ets:tab2list(?MODULE),
|
||||||
@ -626,6 +619,47 @@ transform_options({listen, LOpts}, Opts) ->
|
|||||||
transform_options(Opt, Opts) ->
|
transform_options(Opt, Opts) ->
|
||||||
[Opt|Opts].
|
[Opt|Opts].
|
||||||
|
|
||||||
|
-spec validate_module_options(module(), [{atom(), any()}]) -> [{atom(), any()}].
|
||||||
|
validate_module_options(Module, Opts) ->
|
||||||
|
try Module:listen_opt_type('') of
|
||||||
|
_ ->
|
||||||
|
lists:filtermap(
|
||||||
|
fun({Opt, Val}) ->
|
||||||
|
case validate_module_option(Module, Opt, Val) of
|
||||||
|
{ok, NewVal} -> {true, {Opt, NewVal}};
|
||||||
|
error -> false
|
||||||
|
end
|
||||||
|
end, Opts)
|
||||||
|
catch _:undef ->
|
||||||
|
?WARNING_MSG("module '~s' doesn't export listen_opt_type/1",
|
||||||
|
[Module]),
|
||||||
|
Opts
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec validate_module_option(module(), atom(), any()) -> {ok, any()} | error.
|
||||||
|
validate_module_option(Module, Opt, Val) ->
|
||||||
|
case Module:listen_opt_type(Opt) of
|
||||||
|
VFun when is_function(VFun) ->
|
||||||
|
try VFun(Val) of
|
||||||
|
NewVal -> {ok, NewVal}
|
||||||
|
catch {invalid_syntax, Error} ->
|
||||||
|
?ERROR_MSG("ignoring listen option '~s' with "
|
||||||
|
"invalid value: ~p: ~s",
|
||||||
|
[Opt, Val, Error]),
|
||||||
|
error;
|
||||||
|
_:_ ->
|
||||||
|
?ERROR_MSG("ignoring listen option '~s' with "
|
||||||
|
"invalid value: ~p",
|
||||||
|
[Opt, Val]),
|
||||||
|
error
|
||||||
|
end;
|
||||||
|
KnownOpts when is_list(KnownOpts) ->
|
||||||
|
?ERROR_MSG("unknown listen option '~s' for '~s' will be likely "
|
||||||
|
"ignored, available options are: ~s",
|
||||||
|
[Opt, Module, misc:join_atoms(KnownOpts, <<", ">>)]),
|
||||||
|
{ok, Val}
|
||||||
|
end.
|
||||||
|
|
||||||
-type transport() :: udp | tcp.
|
-type transport() :: udp | tcp.
|
||||||
-type port_ip_transport() :: inet:port_number() |
|
-type port_ip_transport() :: inet:port_number() |
|
||||||
{inet:port_number(), transport()} |
|
{inet:port_number(), transport()} |
|
||||||
@ -647,7 +681,7 @@ validate_cfg(L) ->
|
|||||||
true = ?IS_TRANSPORT(T),
|
true = ?IS_TRANSPORT(T),
|
||||||
{{Port, IP, T}, Mod, Opts};
|
{{Port, IP, T}, Mod, Opts};
|
||||||
({module, Mod}, {Port, _, Opts}) ->
|
({module, Mod}, {Port, _, Opts}) ->
|
||||||
{Port, prepare_mod(Mod), Opts};
|
{Port, Mod, Opts};
|
||||||
(Opt, {Port, Mod, Opts}) ->
|
(Opt, {Port, Mod, Opts}) ->
|
||||||
{Port, Mod, [Opt|Opts]}
|
{Port, Mod, [Opt|Opts]}
|
||||||
end, {{5222, all_zero_ip(LOpts), tcp}, ejabberd_c2s, []}, LOpts)
|
end, {{5222, all_zero_ip(LOpts), tcp}, ejabberd_c2s, []}, LOpts)
|
||||||
@ -666,13 +700,6 @@ prepare_ip(IP) when is_list(IP) ->
|
|||||||
prepare_ip(IP) when is_binary(IP) ->
|
prepare_ip(IP) when is_binary(IP) ->
|
||||||
prepare_ip(binary_to_list(IP)).
|
prepare_ip(binary_to_list(IP)).
|
||||||
|
|
||||||
prepare_mod(ejabberd_sip) ->
|
|
||||||
prepare_mod(sip);
|
|
||||||
prepare_mod(sip) ->
|
|
||||||
esip_socket;
|
|
||||||
prepare_mod(Mod) when is_atom(Mod) ->
|
|
||||||
Mod.
|
|
||||||
|
|
||||||
all_zero_ip(Opts) ->
|
all_zero_ip(Opts) ->
|
||||||
case proplists:get_bool(inet6, Opts) of
|
case proplists:get_bool(inet6, Opts) of
|
||||||
true -> {0,0,0,0,0,0,0,0};
|
true -> {0,0,0,0,0,0,0,0};
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
%% ejabberd_socket callbacks
|
%% ejabberd_socket callbacks
|
||||||
-export([start/2, start_link/2, socket_type/0]).
|
-export([start/2, start_link/2, socket_type/0]).
|
||||||
%% ejabberd_config callbacks
|
%% ejabberd_config callbacks
|
||||||
-export([opt_type/1]).
|
-export([opt_type/1, listen_opt_type/1]).
|
||||||
%% xmpp_stream_in callbacks
|
%% xmpp_stream_in callbacks
|
||||||
-export([init/1, handle_call/3, handle_cast/2,
|
-export([init/1, handle_call/3, handle_cast/2,
|
||||||
handle_info/2, terminate/2, code_change/3]).
|
handle_info/2, terminate/2, code_change/3]).
|
||||||
@ -245,25 +245,20 @@ handle_send(Pkt, Result, #{server_host := LServer} = State) ->
|
|||||||
State, [Pkt, Result]).
|
State, [Pkt, Result]).
|
||||||
|
|
||||||
init([State, Opts]) ->
|
init([State, Opts]) ->
|
||||||
Shaper = gen_mod:get_opt(shaper, Opts, fun acl:shaper_rules_validator/1, none),
|
Shaper = gen_mod:get_opt(shaper, Opts, none),
|
||||||
TLSOpts1 = lists:filter(
|
TLSOpts1 = lists:filter(
|
||||||
fun({certfile, _}) -> true;
|
fun({certfile, _}) -> true;
|
||||||
({ciphers, _}) -> true;
|
({ciphers, _}) -> true;
|
||||||
({dhfile, _}) -> true;
|
({dhfile, _}) -> true;
|
||||||
({cafile, _}) -> true;
|
({cafile, _}) -> true;
|
||||||
|
({protocol_options, _}) -> true;
|
||||||
(_) -> false
|
(_) -> false
|
||||||
end, Opts),
|
end, Opts),
|
||||||
TLSOpts2 = case lists:keyfind(protocol_options, 1, Opts) of
|
TLSOpts2 = case proplists:get_bool(tls_compression, Opts) of
|
||||||
false -> TLSOpts1;
|
false -> [compression_none | TLSOpts1];
|
||||||
{_, OptString} ->
|
true -> TLSOpts1
|
||||||
ProtoOpts = str:join(OptString, <<$|>>),
|
|
||||||
[{protocol_options, ProtoOpts}|TLSOpts1]
|
|
||||||
end,
|
|
||||||
TLSOpts3 = case proplists:get_bool(tls_compression, Opts) of
|
|
||||||
false -> [compression_none | TLSOpts2];
|
|
||||||
true -> TLSOpts2
|
|
||||||
end,
|
end,
|
||||||
State1 = State#{tls_options => TLSOpts3,
|
State1 = State#{tls_options => TLSOpts2,
|
||||||
auth_domains => sets:new(),
|
auth_domains => sets:new(),
|
||||||
xmlns => ?NS_SERVER,
|
xmlns => ?NS_SERVER,
|
||||||
lang => ?MYLANG,
|
lang => ?MYLANG,
|
||||||
@ -351,3 +346,23 @@ change_shaper(#{shaper := ShaperName, server_host := ServerHost} = State,
|
|||||||
|
|
||||||
opt_type(_) ->
|
opt_type(_) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
listen_opt_type(shaper) -> fun acl:shaper_rules_validator/1;
|
||||||
|
listen_opt_type(certfile) -> ejabberd_s2s:opt_type(s2s_certfile);
|
||||||
|
listen_opt_type(ciphers) -> ejabberd_s2s:opt_type(s2s_ciphers);
|
||||||
|
listen_opt_type(dhfile) -> ejabberd_s2s:opt_type(s2s_dhfile);
|
||||||
|
listen_opt_type(cafile) -> ejabberd_s2s:opt_type(s2s_cafile);
|
||||||
|
listen_opt_type(protocol_options) -> ejabberd_s2s:opt_type(s2s_protocol_options);
|
||||||
|
listen_opt_type(tls_compression) -> ejabberd_s2s:opt_type(s2s_tls_compression);
|
||||||
|
listen_opt_type(tls) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(supervisor) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(max_stanza_size) ->
|
||||||
|
fun(I) when is_integer(I) -> I;
|
||||||
|
(unlimited) -> infinity;
|
||||||
|
(infinity) -> infinity
|
||||||
|
end;
|
||||||
|
listen_opt_type(max_fsm_queue) ->
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end;
|
||||||
|
listen_opt_type(_) ->
|
||||||
|
[shaper, certfile, ciphers, dhfile, cafile, protocol_options,
|
||||||
|
tls_compression, tls, max_fsm_queue].
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
%% ejabberd_socket callbacks
|
%% ejabberd_socket callbacks
|
||||||
-export([start/2, start_link/2, socket_type/0, close/1, close/2]).
|
-export([start/2, start_link/2, socket_type/0, close/1, close/2]).
|
||||||
%% ejabberd_config callbacks
|
%% ejabberd_config callbacks
|
||||||
-export([opt_type/1, transform_listen_option/2]).
|
-export([opt_type/1, listen_opt_type/1, transform_listen_option/2]).
|
||||||
%% xmpp_stream_in callbacks
|
%% xmpp_stream_in callbacks
|
||||||
-export([init/1, handle_info/2, terminate/2, code_change/3]).
|
-export([init/1, handle_info/2, terminate/2, code_change/3]).
|
||||||
-export([handle_stream_start/2, handle_auth_success/4, handle_auth_failure/4,
|
-export([handle_stream_start/2, handle_auth_success/4, handle_auth_failure/4,
|
||||||
@ -80,49 +80,33 @@ tls_options(#{tls_options := TLSOptions}) ->
|
|||||||
TLSOptions.
|
TLSOptions.
|
||||||
|
|
||||||
init([State, Opts]) ->
|
init([State, Opts]) ->
|
||||||
Access = gen_mod:get_opt(access, Opts, fun acl:access_rules_validator/1, all),
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
Shaper = gen_mod:get_opt(shaper_rule, Opts, fun acl:shaper_rules_validator/1, none),
|
Shaper = gen_mod:get_opt(shaper_rule, Opts, none),
|
||||||
HostOpts = case lists:keyfind(hosts, 1, Opts) of
|
GlobalPassword = gen_mod:get_opt(password, Opts, random_password()),
|
||||||
{hosts, HOpts} ->
|
HostOpts = gen_mod:get_opt(hosts, Opts, [{global, GlobalPassword}]),
|
||||||
lists:foldl(
|
HostOpts1 = lists:map(
|
||||||
fun({H, Os}, D) ->
|
fun({Host, undefined}) -> {Host, GlobalPassword};
|
||||||
P = proplists:get_value(
|
({Host, Password}) -> {Host, Password}
|
||||||
password, Os,
|
end, HostOpts),
|
||||||
str:sha(randoms:bytes(20))),
|
CheckFrom = gen_mod:get_opt(check_from, Opts, true),
|
||||||
dict:store(H, P, D)
|
|
||||||
end, dict:new(), HOpts);
|
|
||||||
false ->
|
|
||||||
Pass = proplists:get_value(
|
|
||||||
password, Opts,
|
|
||||||
str:sha(randoms:bytes(20))),
|
|
||||||
dict:from_list([{global, Pass}])
|
|
||||||
end,
|
|
||||||
CheckFrom = gen_mod:get_opt(check_from, Opts,
|
|
||||||
fun(Flag) when is_boolean(Flag) -> Flag end,
|
|
||||||
true),
|
|
||||||
TLSOpts1 = lists:filter(
|
TLSOpts1 = lists:filter(
|
||||||
fun({certfile, _}) -> true;
|
fun({certfile, _}) -> true;
|
||||||
({ciphers, _}) -> true;
|
({ciphers, _}) -> true;
|
||||||
({dhfile, _}) -> true;
|
({dhfile, _}) -> true;
|
||||||
({cafile, _}) -> true;
|
({cafile, _}) -> true;
|
||||||
|
({protocol_options, _}) -> true;
|
||||||
(_) -> false
|
(_) -> false
|
||||||
end, Opts),
|
end, Opts),
|
||||||
TLSOpts2 = case lists:keyfind(protocol_options, 1, Opts) of
|
|
||||||
false -> TLSOpts1;
|
|
||||||
{_, OptString} ->
|
|
||||||
ProtoOpts = str:join(OptString, <<$|>>),
|
|
||||||
[{protocol_options, ProtoOpts}|TLSOpts1]
|
|
||||||
end,
|
|
||||||
TLSOpts = case proplists:get_bool(tls_compression, Opts) of
|
TLSOpts = case proplists:get_bool(tls_compression, Opts) of
|
||||||
false -> [compression_none | TLSOpts2];
|
false -> [compression_none | TLSOpts1];
|
||||||
true -> TLSOpts2
|
true -> TLSOpts1
|
||||||
end,
|
end,
|
||||||
xmpp_stream_in:change_shaper(State, Shaper),
|
xmpp_stream_in:change_shaper(State, Shaper),
|
||||||
State1 = State#{access => Access,
|
State1 = State#{access => Access,
|
||||||
xmlns => ?NS_COMPONENT,
|
xmlns => ?NS_COMPONENT,
|
||||||
lang => ?MYLANG,
|
lang => ?MYLANG,
|
||||||
server => ?MYNAME,
|
server => ?MYNAME,
|
||||||
host_opts => HostOpts,
|
host_opts => dict:from_list(HostOpts1),
|
||||||
stream_version => undefined,
|
stream_version => undefined,
|
||||||
tls_options => TLSOpts,
|
tls_options => TLSOpts,
|
||||||
check_from => CheckFrom},
|
check_from => CheckFrom},
|
||||||
@ -254,6 +238,9 @@ check_from(From, #{host_opts := HostOpts}) ->
|
|||||||
Server = From#jid.lserver,
|
Server = From#jid.lserver,
|
||||||
dict:is_key(Server, HostOpts).
|
dict:is_key(Server, HostOpts).
|
||||||
|
|
||||||
|
random_password() ->
|
||||||
|
str:sha(randoms:bytes(20)).
|
||||||
|
|
||||||
transform_listen_option({hosts, Hosts, O}, Opts) ->
|
transform_listen_option({hosts, Hosts, O}, Opts) ->
|
||||||
case lists:keyfind(hosts, 1, Opts) of
|
case lists:keyfind(hosts, 1, Opts) of
|
||||||
{_, PrevHostOpts} ->
|
{_, PrevHostOpts} ->
|
||||||
@ -273,3 +260,38 @@ transform_listen_option(Opt, Opts) ->
|
|||||||
[Opt|Opts].
|
[Opt|Opts].
|
||||||
|
|
||||||
opt_type(_) -> [].
|
opt_type(_) -> [].
|
||||||
|
|
||||||
|
listen_opt_type(access) -> fun acl:access_rules_validator/1;
|
||||||
|
listen_opt_type(shaper_rule) -> fun acl:shaper_rules_validator/1;
|
||||||
|
listen_opt_type(certfile) -> fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(ciphers) -> fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(dhfile) -> fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(cafile) -> fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(protocol_options) ->
|
||||||
|
fun(Options) -> str:join(Options, <<"|">>) end;
|
||||||
|
listen_opt_type(tls_compression) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(tls) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(check_from) -> fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(password) -> fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(hosts) ->
|
||||||
|
fun(HostOpts) ->
|
||||||
|
lists:map(
|
||||||
|
fun({Host, Opts}) ->
|
||||||
|
Password = case proplists:get_value(password, Opts) of
|
||||||
|
undefined -> undefined;
|
||||||
|
P -> iolist_to_binary(P)
|
||||||
|
end,
|
||||||
|
{iolist_to_binary(Host), Password}
|
||||||
|
end, HostOpts)
|
||||||
|
end;
|
||||||
|
listen_opt_type(max_stanza_size) ->
|
||||||
|
fun(I) when is_integer(I) -> I;
|
||||||
|
(unlimited) -> infinity;
|
||||||
|
(infinity) -> infinity
|
||||||
|
end;
|
||||||
|
listen_opt_type(max_fsm_queue) ->
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end;
|
||||||
|
listen_opt_type(_) ->
|
||||||
|
[access, shaper_rule, certfile, ciphers, dhfile, cafile, tls,
|
||||||
|
protocol_options, tls_compression, password, hosts, check_from,
|
||||||
|
max_fsm_queue].
|
||||||
|
58
src/ejabberd_sip.erl
Normal file
58
src/ejabberd_sip.erl
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% Created : 30 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%
|
||||||
|
%%%
|
||||||
|
%%% ejabberd, Copyright (C) 2013-2017 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(ejabberd_sip).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([tcp_init/2, udp_init/2, udp_recv/5, start/2,
|
||||||
|
socket_type/0, listen_opt_type/1]).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
tcp_init(Socket, Opts) ->
|
||||||
|
ejabberd:start_app(esip),
|
||||||
|
esip_socket:tcp_init(Socket, Opts).
|
||||||
|
|
||||||
|
udp_init(Socket, Opts) ->
|
||||||
|
ejabberd:start_app(esip),
|
||||||
|
esip_socket:udp_init(Socket, Opts).
|
||||||
|
|
||||||
|
udp_recv(Sock, Addr, Port, Data, Opts) ->
|
||||||
|
esip_socket:udp_recv(Sock, Addr, Port, Data, Opts).
|
||||||
|
|
||||||
|
start(Opaque, Opts) ->
|
||||||
|
esip_socket:start(Opaque, Opts).
|
||||||
|
|
||||||
|
socket_type() ->
|
||||||
|
raw.
|
||||||
|
|
||||||
|
listen_opt_type(certfile) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(tls) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(_) ->
|
||||||
|
[tls, certfile].
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
@ -28,7 +28,7 @@
|
|||||||
-protocol({xep, 176, '1.0'}).
|
-protocol({xep, 176, '1.0'}).
|
||||||
|
|
||||||
-export([tcp_init/2, udp_init/2, udp_recv/5, start/2,
|
-export([tcp_init/2, udp_init/2, udp_recv/5, start/2,
|
||||||
socket_type/0]).
|
socket_type/0, listen_opt_type/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -73,14 +73,9 @@ prepare_turn_opts(Opts, _UseTurn = true) ->
|
|||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
AuthFun = fun ejabberd_auth:get_password_s/2,
|
AuthFun = fun ejabberd_auth:get_password_s/2,
|
||||||
Shaper = gen_mod:get_opt(shaper, Opts,
|
Shaper = gen_mod:get_opt(shaper, Opts, none),
|
||||||
fun(S) when is_atom(S) -> S end,
|
AuthType = gen_mod:get_opt(auth_type, Opts, user),
|
||||||
none),
|
Realm = case gen_mod:get_opt(auth_realm, Opts) of
|
||||||
AuthType = gen_mod:get_opt(auth_type, Opts,
|
|
||||||
fun(anonymous) -> anonymous;
|
|
||||||
(user) -> user
|
|
||||||
end, user),
|
|
||||||
Realm = case gen_mod:get_opt(auth_realm, Opts, fun iolist_to_binary/1) of
|
|
||||||
undefined when AuthType == user ->
|
undefined when AuthType == user ->
|
||||||
if NumberOfMyHosts > 1 ->
|
if NumberOfMyHosts > 1 ->
|
||||||
?WARNING_MSG("you have several virtual "
|
?WARNING_MSG("you have several virtual "
|
||||||
@ -100,3 +95,43 @@ prepare_turn_opts(Opts, _UseTurn = true) ->
|
|||||||
MaxRate = shaper:get_max_rate(Shaper),
|
MaxRate = shaper:get_max_rate(Shaper),
|
||||||
Realm ++ [{auth_fun, AuthFun},{shaper, MaxRate} |
|
Realm ++ [{auth_fun, AuthFun},{shaper, MaxRate} |
|
||||||
lists:keydelete(shaper, 1, Opts)].
|
lists:keydelete(shaper, 1, Opts)].
|
||||||
|
|
||||||
|
listen_opt_type(use_turn) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(turn_ip) ->
|
||||||
|
fun(S) ->
|
||||||
|
{ok, Addr} = inet_parse:ipv4_address(binary_to_list(S)),
|
||||||
|
Addr
|
||||||
|
end;
|
||||||
|
listen_opt_type(shaper) ->
|
||||||
|
fun acl:shaper_rules_validator/1;
|
||||||
|
listen_opt_type(auth_type) ->
|
||||||
|
fun(anonymous) -> anonymous;
|
||||||
|
(user) -> user
|
||||||
|
end;
|
||||||
|
listen_opt_type(auth_realm) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(tls) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
|
listen_opt_type(certfile) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(turn_min_port) ->
|
||||||
|
fun(P) when is_integer(P), P > 0, P =< 65535 -> P end;
|
||||||
|
listen_opt_type(turn_max_port) ->
|
||||||
|
fun(P) when is_integer(P), P > 0, P =< 65535 -> P end;
|
||||||
|
listen_opt_type(turn_max_allocations) ->
|
||||||
|
fun(I) when is_integer(I), I>0 -> I;
|
||||||
|
(unlimited) -> infinity;
|
||||||
|
(infinity) -> infinity
|
||||||
|
end;
|
||||||
|
listen_opt_type(turn_max_permissions) ->
|
||||||
|
fun(I) when is_integer(I), I>0 -> I;
|
||||||
|
(unlimited) -> infinity;
|
||||||
|
(infinity) -> infinity
|
||||||
|
end;
|
||||||
|
listen_opt_type(server_name) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(_) ->
|
||||||
|
[shaper, auth_type, auth_realm, tls, certfile, turn_min_port,
|
||||||
|
turn_max_port, turn_max_allocations, turn_max_permissions,
|
||||||
|
server_name].
|
||||||
|
@ -75,25 +75,25 @@ get_acl_rule([<<"vhosts">>], _) ->
|
|||||||
get_acl_rule([<<"server">>, VHost | _RPath], Method)
|
get_acl_rule([<<"server">>, VHost | _RPath], Method)
|
||||||
when Method =:= 'GET' orelse Method =:= 'HEAD' ->
|
when Method =:= 'GET' orelse Method =:= 'HEAD' ->
|
||||||
AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin,
|
AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin,
|
||||||
access, fun(A) -> A end, configure),
|
access, configure),
|
||||||
ACR = gen_mod:get_module_opt(VHost, ejabberd_web_admin,
|
ACR = gen_mod:get_module_opt(VHost, ejabberd_web_admin,
|
||||||
access_readonly, fun(A) -> A end, webadmin_view),
|
access_readonly, webadmin_view),
|
||||||
{VHost, [AC, ACR]};
|
{VHost, [AC, ACR]};
|
||||||
get_acl_rule([<<"server">>, VHost | _RPath], 'POST') ->
|
get_acl_rule([<<"server">>, VHost | _RPath], 'POST') ->
|
||||||
AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin,
|
AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin,
|
||||||
access, fun(A) -> A end, configure),
|
access, configure),
|
||||||
{VHost, [AC]};
|
{VHost, [AC]};
|
||||||
%% Default rule: only global admins can access any other random page
|
%% Default rule: only global admins can access any other random page
|
||||||
get_acl_rule(_RPath, Method)
|
get_acl_rule(_RPath, Method)
|
||||||
when Method =:= 'GET' orelse Method =:= 'HEAD' ->
|
when Method =:= 'GET' orelse Method =:= 'HEAD' ->
|
||||||
AC = gen_mod:get_module_opt(global, ejabberd_web_admin,
|
AC = gen_mod:get_module_opt(global, ejabberd_web_admin,
|
||||||
access, fun(A) -> A end, configure),
|
access, configure),
|
||||||
ACR = gen_mod:get_module_opt(global, ejabberd_web_admin,
|
ACR = gen_mod:get_module_opt(global, ejabberd_web_admin,
|
||||||
access_readonly, fun(A) -> A end, webadmin_view),
|
access_readonly, webadmin_view),
|
||||||
{global, [AC, ACR]};
|
{global, [AC, ACR]};
|
||||||
get_acl_rule(_RPath, 'POST') ->
|
get_acl_rule(_RPath, 'POST') ->
|
||||||
AC = gen_mod:get_module_opt(global, ejabberd_web_admin,
|
AC = gen_mod:get_module_opt(global, ejabberd_web_admin,
|
||||||
access, fun(A) -> A end, configure),
|
access, configure),
|
||||||
{global, [AC]}.
|
{global, [AC]}.
|
||||||
|
|
||||||
%%%==================================
|
%%%==================================
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
-author('badlop@process-one.net').
|
-author('badlop@process-one.net').
|
||||||
|
|
||||||
-export([start/2, handler/2, process/2, socket_type/0,
|
-export([start/2, handler/2, process/2, socket_type/0,
|
||||||
transform_listen_option/2]).
|
transform_listen_option/2, listen_opt_type/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -197,36 +197,7 @@ socket_type() -> raw.
|
|||||||
%% HTTP interface
|
%% HTTP interface
|
||||||
%% -----------------------------
|
%% -----------------------------
|
||||||
process(_, #request{method = 'POST', data = Data, opts = Opts, ip = {IP, _}}) ->
|
process(_, #request{method = 'POST', data = Data, opts = Opts, ip = {IP, _}}) ->
|
||||||
AccessCommandsOpts = gen_mod:get_opt(access_commands, Opts,
|
AccessCommands = gen_mod:get_opt(access_commands, Opts),
|
||||||
fun(L) when is_list(L) -> L end,
|
|
||||||
undefined),
|
|
||||||
AccessCommands =
|
|
||||||
case AccessCommandsOpts of
|
|
||||||
undefined -> undefined;
|
|
||||||
_ ->
|
|
||||||
lists:flatmap(
|
|
||||||
fun({Ac, AcOpts}) ->
|
|
||||||
Commands = gen_mod:get_opt(
|
|
||||||
commands, lists:flatten(AcOpts),
|
|
||||||
fun(A) when is_atom(A) ->
|
|
||||||
A;
|
|
||||||
(L) when is_list(L) ->
|
|
||||||
true = lists:all(
|
|
||||||
fun is_atom/1,
|
|
||||||
L),
|
|
||||||
L
|
|
||||||
end, all),
|
|
||||||
%% CommOpts = gen_mod:get_opt(
|
|
||||||
%% options, AcOpts,
|
|
||||||
%% fun(L) when is_list(L) -> L end,
|
|
||||||
%% []),
|
|
||||||
[{<<"ejabberd_xmlrpc compatibility shim">>, {[?MODULE], [{access, Ac}], Commands}}];
|
|
||||||
(Wrong) ->
|
|
||||||
?WARNING_MSG("wrong options format for ~p: ~p",
|
|
||||||
[?MODULE, Wrong]),
|
|
||||||
[]
|
|
||||||
end, lists:flatten(AccessCommandsOpts))
|
|
||||||
end,
|
|
||||||
GetAuth = true,
|
GetAuth = true,
|
||||||
State = #state{access_commands = AccessCommands, get_auth = GetAuth, ip = IP},
|
State = #state{access_commands = AccessCommands, get_auth = GetAuth, ip = IP},
|
||||||
case fxml_stream:parse_element(Data) of
|
case fxml_stream:parse_element(Data) of
|
||||||
@ -590,3 +561,25 @@ transform_listen_option({access_commands, ACOpts}, Opts) ->
|
|||||||
[{access_commands, NewACOpts}|Opts];
|
[{access_commands, NewACOpts}|Opts];
|
||||||
transform_listen_option(Opt, Opts) ->
|
transform_listen_option(Opt, Opts) ->
|
||||||
[Opt|Opts].
|
[Opt|Opts].
|
||||||
|
|
||||||
|
listen_opt_type(access_commands) ->
|
||||||
|
fun(Opts) ->
|
||||||
|
lists:map(
|
||||||
|
fun({Ac, AcOpts}) ->
|
||||||
|
Commands = case proplists:get_value(
|
||||||
|
commands, lists:flatten(AcOpts), all) of
|
||||||
|
Cmd when is_atom(Cmd) -> Cmd;
|
||||||
|
Cmds when is_list(Cmds) ->
|
||||||
|
true = lists:all(fun is_atom/1, Cmds),
|
||||||
|
Cmds
|
||||||
|
end,
|
||||||
|
{<<"ejabberd_xmlrpc compatibility shim">>,
|
||||||
|
{[?MODULE], [{access, Ac}], Commands}}
|
||||||
|
end, lists:flatten(Opts))
|
||||||
|
end;
|
||||||
|
listen_opt_type(maxsessions) ->
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end;
|
||||||
|
listen_opt_type(timeout) ->
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end;
|
||||||
|
listen_opt_type(_) ->
|
||||||
|
[access_commands, maxsessions, timeout].
|
||||||
|
@ -565,11 +565,7 @@ get_handle(Name) when is_binary(Name) ->
|
|||||||
%% process.
|
%% process.
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
init([Hosts, Port, Rootdn, Passwd, Opts]) ->
|
init([Hosts, Port, Rootdn, Passwd, Opts]) ->
|
||||||
Encrypt = case gen_mod:get_opt(encrypt, Opts,
|
Encrypt = case gen_mod:get_opt(encrypt, Opts) of
|
||||||
fun(tls) -> tls;
|
|
||||||
(starttls) -> starttls;
|
|
||||||
(none) -> none
|
|
||||||
end) of
|
|
||||||
tls -> tls;
|
tls -> tls;
|
||||||
_ -> none
|
_ -> none
|
||||||
end,
|
end,
|
||||||
@ -581,35 +577,19 @@ init([Hosts, Port, Rootdn, Passwd, Opts]) ->
|
|||||||
end;
|
end;
|
||||||
PT -> PT
|
PT -> PT
|
||||||
end,
|
end,
|
||||||
CacertOpts = case gen_mod:get_opt(
|
CacertOpts = case gen_mod:get_opt(tls_cacertfile, Opts) of
|
||||||
tls_cacertfile, Opts,
|
|
||||||
fun(S) when is_binary(S) ->
|
|
||||||
binary_to_list(S);
|
|
||||||
(undefined) ->
|
|
||||||
undefined
|
|
||||||
end) of
|
|
||||||
undefined ->
|
undefined ->
|
||||||
[];
|
[];
|
||||||
Path ->
|
Path ->
|
||||||
[{cacertfile, Path}]
|
[{cacertfile, Path}]
|
||||||
end,
|
end,
|
||||||
DepthOpts = case gen_mod:get_opt(
|
DepthOpts = case gen_mod:get_opt(tls_depth, Opts) of
|
||||||
tls_depth, Opts,
|
|
||||||
fun(I) when is_integer(I), I>=0 ->
|
|
||||||
I;
|
|
||||||
(undefined) ->
|
|
||||||
undefined
|
|
||||||
end) of
|
|
||||||
undefined ->
|
undefined ->
|
||||||
[];
|
[];
|
||||||
Depth ->
|
Depth ->
|
||||||
[{depth, Depth}]
|
[{depth, Depth}]
|
||||||
end,
|
end,
|
||||||
Verify = gen_mod:get_opt(tls_verify, Opts,
|
Verify = gen_mod:get_opt(tls_verify, Opts, false),
|
||||||
fun(hard) -> hard;
|
|
||||||
(soft) -> soft;
|
|
||||||
(false) -> false
|
|
||||||
end, false),
|
|
||||||
TLSOpts = if (Verify == hard orelse Verify == soft)
|
TLSOpts = if (Verify == hard orelse Verify == soft)
|
||||||
andalso CacertOpts == [] ->
|
andalso CacertOpts == [] ->
|
||||||
?WARNING_MSG("TLS verification is enabled but no CA "
|
?WARNING_MSG("TLS verification is enabled but no CA "
|
||||||
|
@ -173,58 +173,25 @@ uids_domain_subst(Host, UIDs) ->
|
|||||||
-spec get_config(binary(), list()) -> eldap_config().
|
-spec get_config(binary(), list()) -> eldap_config().
|
||||||
|
|
||||||
get_config(Host, Opts) ->
|
get_config(Host, Opts) ->
|
||||||
Servers = gen_mod:get_opt({ldap_servers, Host}, Opts,
|
Servers = gen_mod:get_opt({ldap_servers, Host}, Opts, [<<"localhost">>]),
|
||||||
fun(L) ->
|
Backups = gen_mod:get_opt({ldap_backups, Host}, Opts, []),
|
||||||
[iolist_to_binary(H) || H <- L]
|
Encrypt = gen_mod:get_opt({ldap_encrypt, Host}, Opts, none),
|
||||||
end, [<<"localhost">>]),
|
TLSVerify = gen_mod:get_opt({ldap_tls_verify, Host}, Opts, false),
|
||||||
Backups = gen_mod:get_opt({ldap_backups, Host}, Opts,
|
TLSCAFile = gen_mod:get_opt({ldap_tls_cacertfile, Host}, Opts),
|
||||||
fun(L) ->
|
TLSDepth = gen_mod:get_opt({ldap_tls_depth, Host}, Opts),
|
||||||
[iolist_to_binary(H) || H <- L]
|
|
||||||
end, []),
|
|
||||||
Encrypt = gen_mod:get_opt({ldap_encrypt, Host}, Opts,
|
|
||||||
fun(tls) -> tls;
|
|
||||||
(starttls) -> starttls;
|
|
||||||
(none) -> none
|
|
||||||
end, none),
|
|
||||||
TLSVerify = gen_mod:get_opt({ldap_tls_verify, Host}, Opts,
|
|
||||||
fun(hard) -> hard;
|
|
||||||
(soft) -> soft;
|
|
||||||
(false) -> false
|
|
||||||
end, false),
|
|
||||||
TLSCAFile = gen_mod:get_opt({ldap_tls_cacertfile, Host}, Opts,
|
|
||||||
fun iolist_to_binary/1),
|
|
||||||
TLSDepth = gen_mod:get_opt({ldap_tls_depth, Host}, Opts,
|
|
||||||
fun(I) when is_integer(I), I>=0 -> I end),
|
|
||||||
Port = gen_mod:get_opt({ldap_port, Host}, Opts,
|
Port = gen_mod:get_opt({ldap_port, Host}, Opts,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
case Encrypt of
|
||||||
case Encrypt of
|
tls -> ?LDAPS_PORT;
|
||||||
tls -> ?LDAPS_PORT;
|
starttls -> ?LDAP_PORT;
|
||||||
starttls -> ?LDAP_PORT;
|
_ -> ?LDAP_PORT
|
||||||
_ -> ?LDAP_PORT
|
end),
|
||||||
end),
|
RootDN = gen_mod:get_opt({ldap_rootdn, Host}, Opts, <<"">>),
|
||||||
RootDN = gen_mod:get_opt({ldap_rootdn, Host}, Opts,
|
Password = gen_mod:get_opt({ldap_password, Host}, Opts, <<"">>),
|
||||||
fun iolist_to_binary/1,
|
Base = gen_mod:get_opt({ldap_base, Host}, Opts, <<"">>),
|
||||||
<<"">>),
|
OldDerefAliases = gen_mod:get_opt({deref_aliases, Host}, Opts, unspecified),
|
||||||
Password = gen_mod:get_opt({ldap_password, Host}, Opts,
|
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"">>),
|
|
||||||
Base = gen_mod:get_opt({ldap_base, Host}, Opts,
|
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"">>),
|
|
||||||
OldDerefAliases = gen_mod:get_opt({deref_aliases, Host}, Opts,
|
|
||||||
fun(never) -> never;
|
|
||||||
(searching) -> searching;
|
|
||||||
(finding) -> finding;
|
|
||||||
(always) -> always
|
|
||||||
end, unspecified),
|
|
||||||
DerefAliases =
|
DerefAliases =
|
||||||
if OldDerefAliases == unspecified ->
|
if OldDerefAliases == unspecified ->
|
||||||
gen_mod:get_opt({ldap_deref_aliases, Host}, Opts,
|
gen_mod:get_opt({ldap_deref_aliases, Host}, Opts, never);
|
||||||
fun(never) -> never;
|
|
||||||
(searching) -> searching;
|
|
||||||
(finding) -> finding;
|
|
||||||
(always) -> always
|
|
||||||
end, never);
|
|
||||||
true ->
|
true ->
|
||||||
?WARNING_MSG("Option 'deref_aliases' is deprecated. "
|
?WARNING_MSG("Option 'deref_aliases' is deprecated. "
|
||||||
"The option is still supported "
|
"The option is still supported "
|
||||||
@ -377,7 +344,8 @@ opt_type(ldap_port) ->
|
|||||||
opt_type(ldap_rootdn) -> fun iolist_to_binary/1;
|
opt_type(ldap_rootdn) -> fun iolist_to_binary/1;
|
||||||
opt_type(ldap_servers) ->
|
opt_type(ldap_servers) ->
|
||||||
fun (L) -> [iolist_to_binary(H) || H <- L] end;
|
fun (L) -> [iolist_to_binary(H) || H <- L] end;
|
||||||
opt_type(ldap_tls_cacertfile) -> fun iolist_to_binary/1;
|
opt_type(ldap_tls_cacertfile) ->
|
||||||
|
fun(S) -> binary_to_list(iolist_to_binary(S)) end;
|
||||||
opt_type(ldap_tls_depth) ->
|
opt_type(ldap_tls_depth) ->
|
||||||
fun (I) when is_integer(I), I >= 0 -> I end;
|
fun (I) when is_integer(I), I >= 0 -> I end;
|
||||||
opt_type(ldap_tls_verify) ->
|
opt_type(ldap_tls_verify) ->
|
||||||
|
171
src/gen_mod.erl
171
src/gen_mod.erl
@ -33,16 +33,18 @@
|
|||||||
-export([init/1, start_link/0, start_child/3, start_child/4,
|
-export([init/1, start_link/0, start_child/3, start_child/4,
|
||||||
stop_child/1, stop_child/2, config_reloaded/0]).
|
stop_child/1, stop_child/2, config_reloaded/0]).
|
||||||
-export([start_module/2, start_module/3,
|
-export([start_module/2, start_module/3,
|
||||||
stop_module/2, stop_module_keep_config/2, get_opt/3,
|
stop_module/2, stop_module_keep_config/2,
|
||||||
get_opt/4, get_opt_host/3, opt_type/1, is_equal_opt/5,
|
get_opt/2, get_opt/3, get_opt_host/3, opt_type/1, is_equal_opt/4,
|
||||||
get_module_opt/4, get_module_opt/5, get_module_opt_host/3,
|
get_module_opt/3, get_module_opt/4, get_module_opt_host/3,
|
||||||
loaded_modules/1, loaded_modules_with_opts/1,
|
loaded_modules/1, loaded_modules_with_opts/1,
|
||||||
get_hosts/2, get_module_proc/2, is_loaded/2, is_loaded_elsewhere/2,
|
get_hosts/2, get_module_proc/2, is_loaded/2, is_loaded_elsewhere/2,
|
||||||
start_modules/0, start_modules/1, stop_modules/0, stop_modules/1,
|
start_modules/0, start_modules/1, stop_modules/0, stop_modules/1,
|
||||||
db_mod/2, db_mod/3, ram_db_mod/2, ram_db_mod/3,
|
db_mod/2, db_mod/3, ram_db_mod/2, ram_db_mod/3,
|
||||||
db_type/2, db_type/3, ram_db_type/2, ram_db_type/3]).
|
db_type/2, db_type/3, ram_db_type/2, ram_db_type/3]).
|
||||||
|
|
||||||
%%-export([behaviour_info/1]).
|
%% Deprecated functions
|
||||||
|
-export([get_opt/4, get_module_opt/5]).
|
||||||
|
-deprecated([{get_opt, 4}, {get_module_opt, 5}]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -73,7 +75,7 @@
|
|||||||
start_link() ->
|
start_link() ->
|
||||||
case supervisor:start_link({local, ejabberd_gen_mod_sup}, ?MODULE, []) of
|
case supervisor:start_link({local, ejabberd_gen_mod_sup}, ?MODULE, []) of
|
||||||
{ok, Pid} ->
|
{ok, Pid} ->
|
||||||
gen_mod:start_modules(),
|
start_modules(),
|
||||||
{ok, Pid};
|
{ok, Pid};
|
||||||
Err ->
|
Err ->
|
||||||
Err
|
Err
|
||||||
@ -303,7 +305,7 @@ stop_modules(Host) ->
|
|||||||
Modules = get_modules_options(Host),
|
Modules = get_modules_options(Host),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({Module, _Args}) ->
|
fun({Module, _Args}) ->
|
||||||
gen_mod:stop_module_keep_config(Host, Module)
|
stop_module_keep_config(Host, Module)
|
||||||
end, Modules).
|
end, Modules).
|
||||||
|
|
||||||
-spec stop_module(binary(), atom()) -> error | {aborted, any()} | {atomic, any()}.
|
-spec stop_module(binary(), atom()) -> error | {aborted, any()} | {atomic, any()}.
|
||||||
@ -351,40 +353,47 @@ wait_for_stop1(MonitorReference) ->
|
|||||||
|
|
||||||
-type check_fun() :: fun((any()) -> any()) | {module(), atom()}.
|
-type check_fun() :: fun((any()) -> any()) | {module(), atom()}.
|
||||||
|
|
||||||
-spec get_opt(atom() | {atom(), binary()|global}, opts(), check_fun()) -> any().
|
-spec get_opt(atom() | {atom(), binary() | global}, opts()) -> any().
|
||||||
|
get_opt(Opt, Opts) ->
|
||||||
|
get_opt(Opt, Opts, undefined).
|
||||||
|
|
||||||
get_opt(Opt, Opts, F) ->
|
-spec get_opt(atom() | {atom(), binary()|global}, opts(), check_fun() | any()) -> any().
|
||||||
get_opt(Opt, Opts, F, undefined).
|
|
||||||
|
|
||||||
-spec get_opt(atom() | {atom(), binary()|global}, opts(), check_fun(), any()) -> any().
|
get_opt(Opt, Opts, F) when is_function(F) ->
|
||||||
|
get_opt(Opt, Opts, undefined);
|
||||||
get_opt({Opt, Host}, Opts, F, Default) ->
|
get_opt({Opt, Host}, Opts, Default) ->
|
||||||
case lists:keysearch(Opt, 1, Opts) of
|
case lists:keyfind(Opt, 1, Opts) of
|
||||||
false ->
|
false ->
|
||||||
ejabberd_config:get_option({Opt, Host}, Default);
|
ejabberd_config:get_option({Opt, Host}, Default);
|
||||||
{value, {_, Val}} ->
|
{_, Val} ->
|
||||||
ejabberd_config:prepare_opt_val(Opt, Val, F, Default)
|
Val
|
||||||
end;
|
end;
|
||||||
get_opt(Opt, Opts, F, Default) ->
|
get_opt(Opt, Opts, Default) ->
|
||||||
case lists:keysearch(Opt, 1, Opts) of
|
case lists:keyfind(Opt, 1, Opts) of
|
||||||
false ->
|
false ->
|
||||||
Default;
|
Default;
|
||||||
{value, {_, Val}} ->
|
{_, Val} ->
|
||||||
ejabberd_config:prepare_opt_val(Opt, Val, F, Default)
|
Val
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec get_module_opt(global | binary(), atom(), atom(), check_fun()) -> any().
|
-spec get_opt(atom() | {atom(), binary()}, opts(), check_fun(), any()) -> any().
|
||||||
|
get_opt(Opt, Opts, _, Default) ->
|
||||||
|
get_opt(Opt, Opts, Default).
|
||||||
|
|
||||||
get_module_opt(Host, Module, Opt, F) ->
|
-spec get_module_opt(global | binary(), atom(), atom()) -> any().
|
||||||
get_module_opt(Host, Module, Opt, F, undefined).
|
|
||||||
|
|
||||||
-spec get_module_opt(global | binary(), atom(), atom(), check_fun(), any()) -> any().
|
get_module_opt(Host, Module, Opt) ->
|
||||||
|
get_module_opt(Host, Module, Opt, undefined).
|
||||||
|
|
||||||
get_module_opt(global, Module, Opt, F, Default) ->
|
-spec get_module_opt(global | binary(), atom(), atom(), any()) -> any().
|
||||||
|
|
||||||
|
get_module_opt(Host, Module, Opt, F) when is_function(F) ->
|
||||||
|
get_module_opt(Host, Module, Opt, undefined);
|
||||||
|
get_module_opt(global, Module, Opt, Default) ->
|
||||||
Hosts = (?MYHOSTS),
|
Hosts = (?MYHOSTS),
|
||||||
[Value | Values] = lists:map(fun (Host) ->
|
[Value | Values] = lists:map(fun (Host) ->
|
||||||
get_module_opt(Host, Module, Opt,
|
get_module_opt(Host, Module, Opt,
|
||||||
F, Default)
|
Default)
|
||||||
end,
|
end,
|
||||||
Hosts),
|
Hosts),
|
||||||
Same_all = lists:all(fun (Other_value) ->
|
Same_all = lists:all(fun (Other_value) ->
|
||||||
@ -395,26 +404,28 @@ get_module_opt(global, Module, Opt, F, Default) ->
|
|||||||
true -> Value;
|
true -> Value;
|
||||||
false -> Default
|
false -> Default
|
||||||
end;
|
end;
|
||||||
get_module_opt(Host, Module, Opt, F, Default) ->
|
get_module_opt(Host, Module, Opt, Default) ->
|
||||||
OptsList = ets:lookup(ejabberd_modules, {Module, Host}),
|
OptsList = ets:lookup(ejabberd_modules, {Module, Host}),
|
||||||
case OptsList of
|
case OptsList of
|
||||||
[] -> Default;
|
[] -> Default;
|
||||||
[#ejabberd_module{opts = Opts} | _] ->
|
[#ejabberd_module{opts = Opts} | _] ->
|
||||||
get_opt(Opt, Opts, F, Default)
|
get_opt(Opt, Opts, Default)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec get_module_opt(global | binary(), atom(), atom(), check_fun(), any()) -> any().
|
||||||
|
get_module_opt(Host, Module, Opt, _, Default) ->
|
||||||
|
get_module_opt(Host, Module, Opt, Default).
|
||||||
|
|
||||||
-spec get_module_opt_host(global | binary(), atom(), binary()) -> binary().
|
-spec get_module_opt_host(global | binary(), atom(), binary()) -> binary().
|
||||||
|
|
||||||
get_module_opt_host(Host, Module, Default) ->
|
get_module_opt_host(Host, Module, Default) ->
|
||||||
Val = get_module_opt(Host, Module, host,
|
Val = get_module_opt(Host, Module, host, Default),
|
||||||
fun iolist_to_binary/1,
|
|
||||||
Default),
|
|
||||||
ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host).
|
ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host).
|
||||||
|
|
||||||
-spec get_opt_host(binary(), opts(), binary()) -> binary().
|
-spec get_opt_host(binary(), opts(), binary()) -> binary().
|
||||||
|
|
||||||
get_opt_host(Host, Opts, Default) ->
|
get_opt_host(Host, Opts, Default) ->
|
||||||
Val = get_opt(host, Opts, fun iolist_to_binary/1, Default),
|
Val = get_opt(host, Opts, Default),
|
||||||
ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host).
|
ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host).
|
||||||
|
|
||||||
|
|
||||||
@ -436,23 +447,19 @@ get_module_mod_opt_type_fun(Module) ->
|
|||||||
throw({'EXIT', {undef, mod_opt_type}});
|
throw({'EXIT', {undef, mod_opt_type}});
|
||||||
{[], Args, _} -> Args;
|
{[], Args, _} -> Args;
|
||||||
{Funs, _, _} ->
|
{Funs, _, _} ->
|
||||||
fun(Val) ->
|
fun(Val) -> try_mod_opt_type(Funs, Val) end
|
||||||
lists:any(fun(F) ->
|
|
||||||
try F(Val) of
|
|
||||||
_ ->
|
|
||||||
true
|
|
||||||
catch {replace_with, _NewVal} = E ->
|
|
||||||
throw(E);
|
|
||||||
{invalid_syntax, _Error} = E2 ->
|
|
||||||
throw(E2);
|
|
||||||
_:_ ->
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end, Funs)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
try_mod_opt_type([Fun|Funs], Val) ->
|
||||||
|
try Fun(Val) of
|
||||||
|
NewVal -> NewVal
|
||||||
|
catch {invalid_syntax, _Error} = E2 ->
|
||||||
|
throw(E2);
|
||||||
|
_:_ ->
|
||||||
|
try_mod_opt_type(Funs, Val)
|
||||||
|
end.
|
||||||
|
|
||||||
validate_opts(Module, Opts) ->
|
validate_opts(Module, Opts) ->
|
||||||
ModOptFun = get_module_mod_opt_type_fun(Module),
|
ModOptFun = get_module_mod_opt_type_fun(Module),
|
||||||
lists:filtermap(
|
lists:filtermap(
|
||||||
@ -460,11 +467,9 @@ validate_opts(Module, Opts) ->
|
|||||||
case catch ModOptFun(Opt) of
|
case catch ModOptFun(Opt) of
|
||||||
VFun when is_function(VFun) ->
|
VFun when is_function(VFun) ->
|
||||||
try VFun(Val) of
|
try VFun(Val) of
|
||||||
_ ->
|
NewVal ->
|
||||||
true
|
{true, {Opt, NewVal}}
|
||||||
catch {replace_with, NewVal} ->
|
catch {invalid_syntax, Error} ->
|
||||||
{true, {Opt, NewVal}};
|
|
||||||
{invalid_syntax, Error} ->
|
|
||||||
?ERROR_MSG("ignoring invalid value '~p' for "
|
?ERROR_MSG("ignoring invalid value '~p' for "
|
||||||
"option '~s' of module '~s': ~s",
|
"option '~s' of module '~s': ~s",
|
||||||
[Val, Opt, Module, Error]),
|
[Val, Opt, Module, Error]),
|
||||||
@ -498,27 +503,21 @@ validate_opts(Module, Opts) ->
|
|||||||
db_type(Opts, Module) when is_list(Opts) ->
|
db_type(Opts, Module) when is_list(Opts) ->
|
||||||
db_type(global, Opts, Module);
|
db_type(global, Opts, Module);
|
||||||
db_type(Host, Module) when is_atom(Module) ->
|
db_type(Host, Module) when is_atom(Module) ->
|
||||||
case catch Module:mod_opt_type(db_type) of
|
case get_module_opt(Host, Module, db_type) of
|
||||||
F when is_function(F) ->
|
undefined ->
|
||||||
case get_module_opt(Host, Module, db_type, F) of
|
ejabberd_config:default_db(Host, Module);
|
||||||
undefined -> ejabberd_config:default_db(Host, Module);
|
Type ->
|
||||||
Type -> Type
|
Type
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
undefined
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec db_type(binary() | global, opts(), module()) -> db_type().
|
-spec db_type(binary() | global, opts(), module()) -> db_type().
|
||||||
|
|
||||||
db_type(Host, Opts, Module) ->
|
db_type(Host, Opts, Module) ->
|
||||||
case catch Module:mod_opt_type(db_type) of
|
case get_opt(db_type, Opts) of
|
||||||
F when is_function(F) ->
|
undefined ->
|
||||||
case get_opt(db_type, Opts, F) of
|
ejabberd_config:default_db(Host, Module);
|
||||||
undefined -> ejabberd_config:default_db(Host, Module);
|
Type ->
|
||||||
Type -> Type
|
Type
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
undefined
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec db_mod(binary() | global | db_type(), module()) -> module().
|
-spec db_mod(binary() | global | db_type(), module()) -> module().
|
||||||
@ -538,26 +537,20 @@ db_mod(Host, Opts, Module) when is_list(Opts) ->
|
|||||||
ram_db_type(Opts, Module) when is_list(Opts) ->
|
ram_db_type(Opts, Module) when is_list(Opts) ->
|
||||||
ram_db_type(global, Opts, Module);
|
ram_db_type(global, Opts, Module);
|
||||||
ram_db_type(Host, Module) when is_atom(Module) ->
|
ram_db_type(Host, Module) when is_atom(Module) ->
|
||||||
case catch Module:mod_opt_type(ram_db_type) of
|
case get_module_opt(Host, Module, ram_db_type) of
|
||||||
F when is_function(F) ->
|
undefined ->
|
||||||
case get_module_opt(Host, Module, ram_db_type, F) of
|
ejabberd_config:default_ram_db(Host, Module);
|
||||||
undefined -> ejabberd_config:default_ram_db(Host, Module);
|
Type ->
|
||||||
Type -> Type
|
Type
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
undefined
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec ram_db_type(binary() | global, opts(), module()) -> db_type().
|
-spec ram_db_type(binary() | global, opts(), module()) -> db_type().
|
||||||
ram_db_type(Host, Opts, Module) ->
|
ram_db_type(Host, Opts, Module) ->
|
||||||
case catch Module:mod_opt_type(ram_db_type) of
|
case get_opt(ram_db_type, Opts) of
|
||||||
F when is_function(F) ->
|
undefined ->
|
||||||
case get_opt(ram_db_type, Opts, F) of
|
ejabberd_config:default_ram_db(Host, Module);
|
||||||
undefined -> ejabberd_config:default_ram_db(Host, Module);
|
Type ->
|
||||||
Type -> Type
|
Type
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
undefined
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec ram_db_mod(binary() | global | db_type(), module()) -> module().
|
-spec ram_db_mod(binary() | global | db_type(), module()) -> module().
|
||||||
@ -588,11 +581,9 @@ loaded_modules_with_opts(Host) ->
|
|||||||
-spec get_hosts(opts(), binary()) -> [binary()].
|
-spec get_hosts(opts(), binary()) -> [binary()].
|
||||||
|
|
||||||
get_hosts(Opts, Prefix) ->
|
get_hosts(Opts, Prefix) ->
|
||||||
case get_opt(hosts, Opts,
|
case get_opt(hosts, Opts) of
|
||||||
fun(Hs) -> [iolist_to_binary(H) || H <- Hs] end) of
|
|
||||||
undefined ->
|
undefined ->
|
||||||
case get_opt(host, Opts,
|
case get_opt(host, Opts) of
|
||||||
fun iolist_to_binary/1) of
|
|
||||||
undefined ->
|
undefined ->
|
||||||
[<<Prefix/binary, Host/binary>> || Host <- ?MYHOSTS];
|
[<<Prefix/binary, Host/binary>> || Host <- ?MYHOSTS];
|
||||||
Host ->
|
Host ->
|
||||||
@ -631,11 +622,11 @@ config_reloaded() ->
|
|||||||
reload_modules(Host)
|
reload_modules(Host)
|
||||||
end, ?MYHOSTS).
|
end, ?MYHOSTS).
|
||||||
|
|
||||||
-spec is_equal_opt(atom(), opts(), opts(), check_fun(), any()) ->
|
-spec is_equal_opt(atom(), opts(), opts(), any()) ->
|
||||||
true | {false, any(), any()}.
|
true | {false, any(), any()}.
|
||||||
is_equal_opt(Opt, NewOpts, OldOpts, VFun, Default) ->
|
is_equal_opt(Opt, NewOpts, OldOpts, Default) ->
|
||||||
NewVal = get_opt(Opt, NewOpts, VFun, Default),
|
NewVal = get_opt(Opt, NewOpts, Default),
|
||||||
OldVal = get_opt(Opt, OldOpts, VFun, Default),
|
OldVal = get_opt(Opt, OldOpts, Default),
|
||||||
if NewVal /= OldVal ->
|
if NewVal /= OldVal ->
|
||||||
{false, NewVal, OldVal};
|
{false, NewVal, OldVal};
|
||||||
true ->
|
true ->
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
hex_to_bin/1, hex_to_base64/1, expand_keyword/3,
|
hex_to_bin/1, hex_to_base64/1, expand_keyword/3,
|
||||||
atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1,
|
atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1,
|
||||||
l2i/1, i2l/1, i2l/2, expr_to_term/1, term_to_expr/1,
|
l2i/1, i2l/1, i2l/2, expr_to_term/1, term_to_expr/1,
|
||||||
encode_pid/1, decode_pid/2, compile_exprs/2]).
|
encode_pid/1, decode_pid/2, compile_exprs/2, join_atoms/2]).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
@ -237,6 +237,10 @@ compile_exprs(Mod, Exprs) ->
|
|||||||
{error, compile_failed}
|
{error, compile_failed}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec join_atoms([atom()], binary()) -> binary().
|
||||||
|
join_atoms(Atoms, Sep) ->
|
||||||
|
str:join([io_lib:format("~p", [A]) || A <- Atoms], Sep).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -42,8 +42,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_COMMANDS, ?MODULE, process_local_iq,
|
?NS_COMMANDS, ?MODULE, process_local_iq,
|
||||||
IQDisc),
|
IQDisc),
|
||||||
@ -89,9 +88,7 @@ stop(Host) ->
|
|||||||
?NS_COMMANDS).
|
?NS_COMMANDS).
|
||||||
|
|
||||||
reload(Host, NewOpts, OldOpts) ->
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
@ -108,7 +105,6 @@ get_local_commands(Acc, _From,
|
|||||||
Lang) ->
|
Lang) ->
|
||||||
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
report_commands_node,
|
report_commands_node,
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false),
|
false),
|
||||||
case Display of
|
case Display of
|
||||||
false -> Acc;
|
false -> Acc;
|
||||||
@ -138,7 +134,6 @@ get_sm_commands(Acc, _From,
|
|||||||
#jid{lserver = LServer} = To, <<"">>, Lang) ->
|
#jid{lserver = LServer} = To, <<"">>, Lang) ->
|
||||||
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
Display = gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
report_commands_node,
|
report_commands_node,
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false),
|
false),
|
||||||
case Display of
|
case Display of
|
||||||
false -> Acc;
|
false -> Acc;
|
||||||
|
@ -763,9 +763,7 @@ send_announcement_to_all(Host, SubjectS, BodyS) ->
|
|||||||
-spec get_access(global | binary()) -> atom().
|
-spec get_access(global | binary()) -> atom().
|
||||||
|
|
||||||
get_access(Host) ->
|
get_access(Host) ->
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, access,
|
gen_mod:get_module_opt(Host, ?MODULE, access, none).
|
||||||
fun(A) -> A end,
|
|
||||||
none).
|
|
||||||
|
|
||||||
-spec add_store_hint(stanza()) -> stanza().
|
-spec add_store_hint(stanza()) -> stanza().
|
||||||
add_store_hint(El) ->
|
add_store_hint(El) ->
|
||||||
|
@ -74,14 +74,8 @@ filter_packet({#message{} = Msg, State} = Acc) ->
|
|||||||
Acc;
|
Acc;
|
||||||
false ->
|
false ->
|
||||||
#{lserver := LServer} = State,
|
#{lserver := LServer} = State,
|
||||||
Drop =
|
Drop = gen_mod:get_module_opt(LServer, ?MODULE, drop, true),
|
||||||
gen_mod:get_module_opt(LServer, ?MODULE, drop,
|
Log = gen_mod:get_module_opt(LServer, ?MODULE, log, false),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
Log =
|
|
||||||
gen_mod:get_module_opt(LServer, ?MODULE, log,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false),
|
|
||||||
if
|
if
|
||||||
Log ->
|
Log ->
|
||||||
?INFO_MSG("Drop packet: ~s",
|
?INFO_MSG("Drop packet: ~s",
|
||||||
|
@ -46,8 +46,7 @@
|
|||||||
-type block_event() :: {block, [jid()]} | {unblock, [jid()]} | unblock_all.
|
-type block_event() :: {block, [jid()]} | {unblock, [jid()]} | unblock_all.
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
|
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
||||||
?NS_BLOCKING, ?MODULE, process_iq, IQDisc).
|
?NS_BLOCKING, ?MODULE, process_iq, IQDisc).
|
||||||
@ -57,9 +56,7 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING).
|
||||||
|
|
||||||
reload(Host, NewOpts, OldOpts) ->
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING,
|
||||||
?MODULE, process_iq, IQDisc);
|
?MODULE, process_iq, IQDisc);
|
||||||
|
@ -144,10 +144,7 @@ reload(_Host, NewOpts, _OldOpts) ->
|
|||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
start_jiffy(Opts) ->
|
start_jiffy(Opts) ->
|
||||||
case gen_mod:get_opt(json, Opts,
|
case gen_mod:get_opt(json, Opts, false) of
|
||||||
fun(false) -> false;
|
|
||||||
(true) -> true
|
|
||||||
end, false) of
|
|
||||||
false ->
|
false ->
|
||||||
ok;
|
ok;
|
||||||
true ->
|
true ->
|
||||||
@ -220,7 +217,7 @@ use_cache(Mod) ->
|
|||||||
true -> Mod:use_cache();
|
true -> Mod:use_cache();
|
||||||
false ->
|
false ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(
|
||||||
global, ?MODULE, use_cache, mod_opt_type(use_cache),
|
global, ?MODULE, use_cache,
|
||||||
ejabberd_config:use_cache(global))
|
ejabberd_config:use_cache(global))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -244,15 +241,12 @@ delete_cache(Mod, SID) ->
|
|||||||
cache_opts() ->
|
cache_opts() ->
|
||||||
MaxSize = gen_mod:get_module_opt(
|
MaxSize = gen_mod:get_module_opt(
|
||||||
global, ?MODULE, cache_size,
|
global, ?MODULE, cache_size,
|
||||||
mod_opt_type(cache_size),
|
|
||||||
ejabberd_config:cache_size(global)),
|
ejabberd_config:cache_size(global)),
|
||||||
CacheMissed = gen_mod:get_module_opt(
|
CacheMissed = gen_mod:get_module_opt(
|
||||||
global, ?MODULE, cache_missed,
|
global, ?MODULE, cache_missed,
|
||||||
mod_opt_type(cache_missed),
|
|
||||||
ejabberd_config:cache_missed(global)),
|
ejabberd_config:cache_missed(global)),
|
||||||
LifeTime = case gen_mod:get_module_opt(
|
LifeTime = case gen_mod:get_module_opt(
|
||||||
global, ?MODULE, cache_life_time,
|
global, ?MODULE, cache_life_time,
|
||||||
mod_opt_type(cache_life_time),
|
|
||||||
ejabberd_config:cache_life_time(global)) of
|
ejabberd_config:cache_life_time(global)) of
|
||||||
infinity -> infinity;
|
infinity -> infinity;
|
||||||
I -> timer:seconds(I)
|
I -> timer:seconds(I)
|
||||||
|
@ -247,8 +247,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(cache_size, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(cache_size, NewOpts, OldOpts,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
ejabberd_config:cache_size(Host)) of
|
||||||
1000) of
|
|
||||||
{false, MaxSize, _} ->
|
{false, MaxSize, _} ->
|
||||||
ets_cache:setopts(caps_features_cache, [{max_size, MaxSize}]),
|
ets_cache:setopts(caps_features_cache, [{max_size, MaxSize}]),
|
||||||
ets_cache:setopts(caps_requests_cache, [{max_size, MaxSize}]);
|
ets_cache:setopts(caps_requests_cache, [{max_size, MaxSize}]);
|
||||||
@ -256,9 +255,12 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(cache_life_time, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(cache_life_time, NewOpts, OldOpts,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
ejabberd_config:cache_life_time(Host)) of
|
||||||
timer:hours(24) div 1000) of
|
{false, Time, _} ->
|
||||||
{false, LifeTime, _} ->
|
LifeTime = case Time of
|
||||||
|
infinity -> infinity;
|
||||||
|
_ -> timer:seconds(Time)
|
||||||
|
end,
|
||||||
ets_cache:setopts(caps_features_cache, [{life_time, LifeTime}]);
|
ets_cache:setopts(caps_features_cache, [{life_time, LifeTime}]);
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
@ -483,18 +485,14 @@ init_cache(Host, Opts) ->
|
|||||||
{life_time, timer:seconds(?BAD_HASH_LIFETIME)}]).
|
{life_time, timer:seconds(?BAD_HASH_LIFETIME)}]).
|
||||||
|
|
||||||
use_cache(Host, Opts) ->
|
use_cache(Host, Opts) ->
|
||||||
gen_mod:get_opt(use_cache, Opts, mod_opt_type(use_cache),
|
gen_mod:get_opt(use_cache, Opts, ejabberd_config:use_cache(Host)).
|
||||||
ejabberd_config:use_cache(Host)).
|
|
||||||
|
|
||||||
cache_opts(Host, Opts) ->
|
cache_opts(Host, Opts) ->
|
||||||
MaxSize = gen_mod:get_opt(cache_size, Opts,
|
MaxSize = gen_mod:get_opt(cache_size, Opts,
|
||||||
mod_opt_type(cache_size),
|
|
||||||
ejabberd_config:cache_size(Host)),
|
ejabberd_config:cache_size(Host)),
|
||||||
CacheMissed = gen_mod:get_opt(cache_missed, Opts,
|
CacheMissed = gen_mod:get_opt(cache_missed, Opts,
|
||||||
mod_opt_type(cache_missed),
|
|
||||||
ejabberd_config:cache_missed(Host)),
|
ejabberd_config:cache_missed(Host)),
|
||||||
LifeTime = case gen_mod:get_opt(cache_life_time, Opts,
|
LifeTime = case gen_mod:get_opt(cache_life_time, Opts,
|
||||||
mod_opt_type(cache_life_time),
|
|
||||||
ejabberd_config:cache_life_time(Host)) of
|
ejabberd_config:cache_life_time(Host)) of
|
||||||
infinity -> infinity;
|
infinity -> infinity;
|
||||||
I -> timer:seconds(I)
|
I -> timer:seconds(I)
|
||||||
|
@ -61,7 +61,7 @@ is_carbon_copy(_) ->
|
|||||||
false.
|
false.
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts,fun gen_iq_handler:check_type/1, one_queue),
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
|
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
|
||||||
Mod = gen_mod:ram_db_mod(Host, ?MODULE),
|
Mod = gen_mod:ram_db_mod(Host, ?MODULE),
|
||||||
init_cache(Mod, Host, Opts),
|
init_cache(Mod, Host, Opts),
|
||||||
@ -95,9 +95,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
false ->
|
false ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2,
|
||||||
?MODULE, iq_handler, IQDisc);
|
?MODULE, iq_handler, IQDisc);
|
||||||
@ -331,13 +329,13 @@ init_cache(Mod, Host, Opts) ->
|
|||||||
-spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()].
|
-spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()].
|
||||||
cache_opts(Host, Opts) ->
|
cache_opts(Host, Opts) ->
|
||||||
MaxSize = gen_mod:get_opt(
|
MaxSize = gen_mod:get_opt(
|
||||||
cache_size, Opts, mod_opt_type(cache_size),
|
cache_size, Opts,
|
||||||
ejabberd_config:cache_size(Host)),
|
ejabberd_config:cache_size(Host)),
|
||||||
CacheMissed = gen_mod:get_opt(
|
CacheMissed = gen_mod:get_opt(
|
||||||
cache_missed, Opts, mod_opt_type(cache_missed),
|
cache_missed, Opts,
|
||||||
ejabberd_config:cache_missed(Host)),
|
ejabberd_config:cache_missed(Host)),
|
||||||
LifeTime = case gen_mod:get_opt(
|
LifeTime = case gen_mod:get_opt(
|
||||||
cache_life_time, Opts, mod_opt_type(cache_life_time),
|
cache_life_time, Opts,
|
||||||
ejabberd_config:cache_life_time(Host)) of
|
ejabberd_config:cache_life_time(Host)) of
|
||||||
infinity -> infinity;
|
infinity -> infinity;
|
||||||
I -> timer:seconds(I)
|
I -> timer:seconds(I)
|
||||||
@ -350,7 +348,7 @@ use_cache(Mod, Host) ->
|
|||||||
true -> Mod:use_cache(Host);
|
true -> Mod:use_cache(Host);
|
||||||
false ->
|
false ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(
|
||||||
Host, ?MODULE, use_cache, mod_opt_type(use_cache),
|
Host, ?MODULE, use_cache,
|
||||||
ejabberd_config:use_cache(Host))
|
ejabberd_config:use_cache(Host))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -59,18 +59,9 @@
|
|||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-spec start(binary(), gen_mod:opts()) -> ok.
|
-spec start(binary(), gen_mod:opts()) -> ok.
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
QueuePresence =
|
QueuePresence = gen_mod:get_opt(queue_presence, Opts, true),
|
||||||
gen_mod:get_opt(queue_presence, Opts,
|
QueueChatStates = gen_mod:get_opt(queue_chat_states, Opts, true),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
QueuePEP = gen_mod:get_opt(queue_pep, Opts, true),
|
||||||
true),
|
|
||||||
QueueChatStates =
|
|
||||||
gen_mod:get_opt(queue_chat_states, Opts,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
QueuePEP =
|
|
||||||
gen_mod:get_opt(queue_pep, Opts,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
if QueuePresence; QueueChatStates; QueuePEP ->
|
if QueuePresence; QueueChatStates; QueuePEP ->
|
||||||
register_hooks(Host),
|
register_hooks(Host),
|
||||||
if QueuePresence ->
|
if QueuePresence ->
|
||||||
@ -93,18 +84,9 @@ start(Host, Opts) ->
|
|||||||
|
|
||||||
-spec stop(binary()) -> ok.
|
-spec stop(binary()) -> ok.
|
||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
QueuePresence =
|
QueuePresence = gen_mod:get_module_opt(Host, ?MODULE, queue_presence, true),
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, queue_presence,
|
QueueChatStates = gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states, true),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
QueuePEP = gen_mod:get_module_opt(Host, ?MODULE, queue_pep, true),
|
||||||
true),
|
|
||||||
QueueChatStates =
|
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
QueuePEP =
|
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, queue_pep,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
if QueuePresence; QueueChatStates; QueuePEP ->
|
if QueuePresence; QueueChatStates; QueuePEP ->
|
||||||
unregister_hooks(Host),
|
unregister_hooks(Host),
|
||||||
if QueuePresence ->
|
if QueuePresence ->
|
||||||
@ -127,15 +109,9 @@ stop(Host) ->
|
|||||||
|
|
||||||
-spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok.
|
-spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok.
|
||||||
reload(Host, NewOpts, _OldOpts) ->
|
reload(Host, NewOpts, _OldOpts) ->
|
||||||
QueuePresence = gen_mod:get_opt(queue_presence, NewOpts,
|
QueuePresence = gen_mod:get_opt(queue_presence, NewOpts, true),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
QueueChatStates = gen_mod:get_opt(queue_chat_states, NewOpts, true),
|
||||||
true),
|
QueuePEP = gen_mod:get_opt(queue_pep, NewOpts, true),
|
||||||
QueueChatStates = gen_mod:get_opt(queue_chat_states, NewOpts,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
QueuePEP = gen_mod:get_opt(queue_pep, NewOpts,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
if QueuePresence; QueueChatStates; QueuePEP ->
|
if QueuePresence; QueueChatStates; QueuePEP ->
|
||||||
register_hooks(Host);
|
register_hooks(Host);
|
||||||
true ->
|
true ->
|
||||||
|
@ -61,7 +61,15 @@ reload(_Host, _NewOpts, _OldOpts) ->
|
|||||||
ok.
|
ok.
|
||||||
|
|
||||||
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
|
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
|
||||||
mod_opt_type(namespaces) -> validate_fun();
|
mod_opt_type(namespaces) ->
|
||||||
|
fun(L) ->
|
||||||
|
lists:map(
|
||||||
|
fun({NS, Opts}) ->
|
||||||
|
Attrs = proplists:get_value(filtering, Opts, []),
|
||||||
|
Access = proplists:get_value(access, Opts, none),
|
||||||
|
{NS, Attrs, Access}
|
||||||
|
end, L)
|
||||||
|
end;
|
||||||
mod_opt_type(_) ->
|
mod_opt_type(_) ->
|
||||||
[namespaces, iqdisc].
|
[namespaces, iqdisc].
|
||||||
|
|
||||||
@ -142,8 +150,7 @@ handle_cast({component_connected, Host}, State) ->
|
|||||||
ServerHost = State#state.server_host,
|
ServerHost = State#state.server_host,
|
||||||
To = jid:make(Host),
|
To = jid:make(Host),
|
||||||
NSAttrsAccessList = gen_mod:get_module_opt(
|
NSAttrsAccessList = gen_mod:get_module_opt(
|
||||||
ServerHost, ?MODULE, namespaces,
|
ServerHost, ?MODULE, namespaces, []),
|
||||||
validate_fun(), []),
|
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({NS, _Attrs, Access}) ->
|
fun({NS, _Attrs, Access}) ->
|
||||||
case acl:match_rule(ServerHost, Access, To) of
|
case acl:match_rule(ServerHost, Access, To) of
|
||||||
@ -342,13 +349,3 @@ disco_identity(Acc, _From, _To, _Node, _Lang, _Type) ->
|
|||||||
|
|
||||||
my_features(ejabberd_local) -> [?NS_DELEGATION];
|
my_features(ejabberd_local) -> [?NS_DELEGATION];
|
||||||
my_features(ejabberd_sm) -> [].
|
my_features(ejabberd_sm) -> [].
|
||||||
|
|
||||||
validate_fun() ->
|
|
||||||
fun(L) ->
|
|
||||||
lists:map(
|
|
||||||
fun({NS, Opts}) ->
|
|
||||||
Attrs = proplists:get_value(filtering, Opts, []),
|
|
||||||
Access = proplists:get_value(access, Opts, none),
|
|
||||||
{NS, Attrs, Access}
|
|
||||||
end, L)
|
|
||||||
end.
|
|
||||||
|
@ -50,8 +50,7 @@
|
|||||||
-type items_acc() :: {error, stanza_error()} | {result, [disco_item()]} | empty.
|
-type items_acc() :: {error, stanza_error()} | {result, [disco_item()]} | empty.
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_DISCO_ITEMS, ?MODULE,
|
?NS_DISCO_ITEMS, ?MODULE,
|
||||||
process_local_iq_items, IQDisc),
|
process_local_iq_items, IQDisc),
|
||||||
@ -67,10 +66,7 @@ start(Host, Opts) ->
|
|||||||
catch ets:new(disco_extra_domains,
|
catch ets:new(disco_extra_domains,
|
||||||
[named_table, ordered_set, public,
|
[named_table, ordered_set, public,
|
||||||
{heir, erlang:group_leader(), none}]),
|
{heir, erlang:group_leader(), none}]),
|
||||||
ExtraDomains = gen_mod:get_opt(extra_domains, Opts,
|
ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []),
|
||||||
fun(Hs) ->
|
|
||||||
[iolist_to_binary(H) || H <- Hs]
|
|
||||||
end, []),
|
|
||||||
lists:foreach(fun (Domain) ->
|
lists:foreach(fun (Domain) ->
|
||||||
register_extra_domain(Host, Domain)
|
register_extra_domain(Host, Domain)
|
||||||
end,
|
end,
|
||||||
@ -119,10 +115,7 @@ stop(Host) ->
|
|||||||
ok.
|
ok.
|
||||||
|
|
||||||
reload(Host, NewOpts, OldOpts) ->
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
case gen_mod:is_equal_opt(extra_domains, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(extra_domains, NewOpts, OldOpts, []) of
|
||||||
fun(Hs) ->
|
|
||||||
[iolist_to_binary(H) || H <- Hs]
|
|
||||||
end, []) of
|
|
||||||
{false, NewDomains, OldDomains} ->
|
{false, NewDomains, OldDomains} ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(Domain) ->
|
fun(Domain) ->
|
||||||
@ -135,9 +128,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_DISCO_ITEMS, ?MODULE,
|
?NS_DISCO_ITEMS, ?MODULE,
|
||||||
@ -447,17 +438,7 @@ get_info(Acc, _, _, _Node, _) -> Acc.
|
|||||||
|
|
||||||
-spec get_fields(binary(), module()) -> [xdata_field()].
|
-spec get_fields(binary(), module()) -> [xdata_field()].
|
||||||
get_fields(Host, Module) ->
|
get_fields(Host, Module) ->
|
||||||
Fields = gen_mod:get_module_opt(
|
Fields = gen_mod:get_module_opt(Host, ?MODULE, server_info, []),
|
||||||
Host, ?MODULE, server_info,
|
|
||||||
fun(L) ->
|
|
||||||
lists:map(
|
|
||||||
fun(Opts) ->
|
|
||||||
Mods = proplists:get_value(modules, Opts, all),
|
|
||||||
Name = proplists:get_value(name, Opts, <<>>),
|
|
||||||
URLs = proplists:get_value(urls, Opts, []),
|
|
||||||
{Mods, Name, URLs}
|
|
||||||
end, L)
|
|
||||||
end, []),
|
|
||||||
Fields1 = lists:filter(fun ({Modules, _, _}) ->
|
Fields1 = lists:filter(fun ({Modules, _, _}) ->
|
||||||
case Modules of
|
case Modules of
|
||||||
all -> true;
|
all -> true;
|
||||||
|
@ -58,11 +58,9 @@ c2s_auth_result(#{ip := {Addr, _}, lserver := LServer} = State, false, _User) ->
|
|||||||
false ->
|
false ->
|
||||||
BanLifetime = gen_mod:get_module_opt(
|
BanLifetime = gen_mod:get_module_opt(
|
||||||
LServer, ?MODULE, c2s_auth_ban_lifetime,
|
LServer, ?MODULE, c2s_auth_ban_lifetime,
|
||||||
fun(T) when is_integer(T), T > 0 -> T end,
|
|
||||||
?C2S_AUTH_BAN_LIFETIME),
|
?C2S_AUTH_BAN_LIFETIME),
|
||||||
MaxFailures = gen_mod:get_module_opt(
|
MaxFailures = gen_mod:get_module_opt(
|
||||||
LServer, ?MODULE, c2s_max_auth_failures,
|
LServer, ?MODULE, c2s_max_auth_failures,
|
||||||
fun(I) when is_integer(I), I > 0 -> I end,
|
|
||||||
?C2S_MAX_AUTH_FAILURES),
|
?C2S_MAX_AUTH_FAILURES),
|
||||||
UnbanTS = p1_time_compat:system_time(seconds) + BanLifetime,
|
UnbanTS = p1_time_compat:system_time(seconds) + BanLifetime,
|
||||||
Attempts = case ets:lookup(failed_auth, Addr) of
|
Attempts = case ets:lookup(failed_auth, Addr) of
|
||||||
@ -179,9 +177,7 @@ log_and_disconnect(#{ip := {Addr, _}, lang := Lang} = State, Attempts, UnbanTS)
|
|||||||
{stop, ejabberd_c2s:send(State, Err)}.
|
{stop, ejabberd_c2s:send(State, Err)}.
|
||||||
|
|
||||||
is_whitelisted(Host, Addr) ->
|
is_whitelisted(Host, Addr) ->
|
||||||
Access = gen_mod:get_module_opt(Host, ?MODULE, access,
|
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||||
fun(A) -> A end,
|
|
||||||
none),
|
|
||||||
acl:match_rule(Host, Access, Addr) == allow.
|
acl:match_rule(Host, Access, Addr) == allow.
|
||||||
|
|
||||||
seconds_to_now(Secs) ->
|
seconds_to_now(Secs) ->
|
||||||
|
@ -543,9 +543,7 @@ log(Call, Args, IP) ->
|
|||||||
?INFO_MSG("API call ~s ~p (~p)", [Call, Args, IP]).
|
?INFO_MSG("API call ~s ~p (~p)", [Call, Args, IP]).
|
||||||
|
|
||||||
permission_addon() ->
|
permission_addon() ->
|
||||||
Access = gen_mod:get_module_opt(global, ?MODULE, admin_ip_access,
|
Access = gen_mod:get_module_opt(global, ?MODULE, admin_ip_access, none),
|
||||||
fun(V) -> V end,
|
|
||||||
none),
|
|
||||||
Rules = acl:resolve_access(Access, global),
|
Rules = acl:resolve_access(Access, global),
|
||||||
R = case Rules of
|
R = case Rules of
|
||||||
all ->
|
all ->
|
||||||
|
@ -118,41 +118,25 @@ init([Host, Opts]) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
initialize(Host, Opts) ->
|
initialize(Host, Opts) ->
|
||||||
DocRoot = gen_mod:get_opt(docroot, Opts, fun(A) -> A end, undefined),
|
DocRoot = gen_mod:get_opt(docroot, Opts),
|
||||||
check_docroot_defined(DocRoot, Host),
|
check_docroot_defined(DocRoot, Host),
|
||||||
DRInfo = check_docroot_exists(DocRoot),
|
DRInfo = check_docroot_exists(DocRoot),
|
||||||
check_docroot_is_dir(DRInfo, DocRoot),
|
check_docroot_is_dir(DRInfo, DocRoot),
|
||||||
check_docroot_is_readable(DRInfo, DocRoot),
|
check_docroot_is_readable(DRInfo, DocRoot),
|
||||||
AccessLog = gen_mod:get_opt(accesslog, Opts,
|
AccessLog = gen_mod:get_opt(accesslog, Opts),
|
||||||
fun iolist_to_binary/1,
|
|
||||||
undefined),
|
|
||||||
AccessLogFD = try_open_log(AccessLog, Host),
|
AccessLogFD = try_open_log(AccessLog, Host),
|
||||||
DirectoryIndices = gen_mod:get_opt(directory_indices, Opts,
|
DirectoryIndices = gen_mod:get_opt(directory_indices, Opts, []),
|
||||||
fun(L) when is_list(L) -> L end,
|
CustomHeaders = gen_mod:get_opt(custom_headers, Opts, []),
|
||||||
[]),
|
|
||||||
CustomHeaders = gen_mod:get_opt(custom_headers, Opts,
|
|
||||||
fun(L) when is_list(L) -> L end,
|
|
||||||
[]),
|
|
||||||
DefaultContentType = gen_mod:get_opt(default_content_type, Opts,
|
DefaultContentType = gen_mod:get_opt(default_content_type, Opts,
|
||||||
fun iolist_to_binary/1,
|
|
||||||
?DEFAULT_CONTENT_TYPE),
|
?DEFAULT_CONTENT_TYPE),
|
||||||
UserAccess0 = gen_mod:get_opt(must_authenticate_with, Opts,
|
UserAccess0 = gen_mod:get_opt(must_authenticate_with, Opts, []),
|
||||||
mod_opt_type(must_authenticate_with),
|
|
||||||
[]),
|
|
||||||
UserAccess = case UserAccess0 of
|
UserAccess = case UserAccess0 of
|
||||||
[] -> none;
|
[] -> none;
|
||||||
_ ->
|
_ ->
|
||||||
dict:from_list(UserAccess0)
|
dict:from_list(UserAccess0)
|
||||||
end,
|
end,
|
||||||
ContentTypes = build_list_content_types(
|
ContentTypes = build_list_content_types(
|
||||||
gen_mod:get_opt(content_types, Opts,
|
gen_mod:get_opt(content_types, Opts, []),
|
||||||
fun(L) when is_list(L) ->
|
|
||||||
lists:map(
|
|
||||||
fun({K, V}) ->
|
|
||||||
{iolist_to_binary(K),
|
|
||||||
iolist_to_binary(V)}
|
|
||||||
end, L)
|
|
||||||
end, []),
|
|
||||||
?DEFAULT_CONTENT_TYPES),
|
?DEFAULT_CONTENT_TYPES),
|
||||||
?DEBUG("known content types: ~s",
|
?DEBUG("known content types: ~s",
|
||||||
[str:join([[$*, K, " -> ", V] || {K, V} <- ContentTypes],
|
[str:join([[$*, K, " -> ", V] || {K, V} <- ContentTypes],
|
||||||
@ -493,7 +477,13 @@ ip_to_string(Address) when size(Address) == 8 ->
|
|||||||
|
|
||||||
mod_opt_type(accesslog) -> fun iolist_to_binary/1;
|
mod_opt_type(accesslog) -> fun iolist_to_binary/1;
|
||||||
mod_opt_type(content_types) ->
|
mod_opt_type(content_types) ->
|
||||||
fun (L) when is_list(L) -> L end;
|
fun(L) when is_list(L) ->
|
||||||
|
lists:map(
|
||||||
|
fun({K, V}) ->
|
||||||
|
{iolist_to_binary(K),
|
||||||
|
iolist_to_binary(V)}
|
||||||
|
end, L)
|
||||||
|
end;
|
||||||
mod_opt_type(custom_headers) ->
|
mod_opt_type(custom_headers) ->
|
||||||
fun (L) when is_list(L) -> L end;
|
fun (L) when is_list(L) -> L end;
|
||||||
mod_opt_type(default_content_type) ->
|
mod_opt_type(default_content_type) ->
|
||||||
|
@ -124,9 +124,7 @@
|
|||||||
-spec start(binary(), gen_mod:opts()) -> {ok, pid()}.
|
-spec start(binary(), gen_mod:opts()) -> {ok, pid()}.
|
||||||
|
|
||||||
start(ServerHost, Opts) ->
|
start(ServerHost, Opts) ->
|
||||||
case gen_mod:get_opt(rm_on_unregister, Opts,
|
case gen_mod:get_opt(rm_on_unregister, Opts, true) of
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true) of
|
|
||||||
true ->
|
true ->
|
||||||
ejabberd_hooks:add(remove_user, ServerHost, ?MODULE,
|
ejabberd_hooks:add(remove_user, ServerHost, ?MODULE,
|
||||||
remove_user, 50);
|
remove_user, 50);
|
||||||
@ -139,9 +137,7 @@ start(ServerHost, Opts) ->
|
|||||||
-spec stop(binary()) -> ok | {error, any()}.
|
-spec stop(binary()) -> ok | {error, any()}.
|
||||||
|
|
||||||
stop(ServerHost) ->
|
stop(ServerHost) ->
|
||||||
case gen_mod:get_module_opt(ServerHost, ?MODULE, rm_on_unregister,
|
case gen_mod:get_module_opt(ServerHost, ?MODULE, rm_on_unregister, true) of
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true) of
|
|
||||||
true ->
|
true ->
|
||||||
ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE,
|
ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE,
|
||||||
remove_user, 50);
|
remove_user, 50);
|
||||||
@ -216,49 +212,18 @@ depends(_Host, _Opts) ->
|
|||||||
init([ServerHost, Opts]) ->
|
init([ServerHost, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"upload.@HOST@">>),
|
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"upload.@HOST@">>),
|
||||||
Name = gen_mod:get_opt(name, Opts,
|
Name = gen_mod:get_opt(name, Opts, <<"HTTP File Upload">>),
|
||||||
fun iolist_to_binary/1,
|
Access = gen_mod:get_opt(access, Opts, local),
|
||||||
<<"HTTP File Upload">>),
|
MaxSize = gen_mod:get_opt(max_size, Opts, 104857600),
|
||||||
Access = gen_mod:get_opt(access, Opts,
|
SecretLength = gen_mod:get_opt(secret_length, Opts, 40),
|
||||||
fun acl:access_rules_validator/1,
|
JIDinURL = gen_mod:get_opt(jid_in_url, Opts, sha1),
|
||||||
local),
|
DocRoot = gen_mod:get_opt(docroot, Opts, <<"@HOME@/upload">>),
|
||||||
MaxSize = gen_mod:get_opt(max_size, Opts,
|
FileMode = gen_mod:get_opt(file_mode, Opts),
|
||||||
fun(I) when is_integer(I), I > 0 -> I;
|
DirMode = gen_mod:get_opt(dir_mode, Opts),
|
||||||
(infinity) -> infinity
|
PutURL = gen_mod:get_opt(put_url, Opts, <<"http://@HOST@:5444">>),
|
||||||
end,
|
GetURL = gen_mod:get_opt(get_url, Opts, PutURL),
|
||||||
104857600),
|
ServiceURL = gen_mod:get_opt(service_url, Opts),
|
||||||
SecretLength = gen_mod:get_opt(secret_length, Opts,
|
Thumbnail = gen_mod:get_opt(thumbnail, Opts, true),
|
||||||
fun(I) when is_integer(I), I >= 8 -> I end,
|
|
||||||
40),
|
|
||||||
JIDinURL = gen_mod:get_opt(jid_in_url, Opts,
|
|
||||||
fun(sha1) -> sha1;
|
|
||||||
(node) -> node
|
|
||||||
end,
|
|
||||||
sha1),
|
|
||||||
DocRoot = gen_mod:get_opt(docroot, Opts,
|
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"@HOME@/upload">>),
|
|
||||||
FileMode = gen_mod:get_opt(file_mode, Opts,
|
|
||||||
fun(Mode) -> ?STR_TO_INT(Mode, 8) end),
|
|
||||||
DirMode = gen_mod:get_opt(dir_mode, Opts,
|
|
||||||
fun(Mode) -> ?STR_TO_INT(Mode, 8) end),
|
|
||||||
PutURL = gen_mod:get_opt(put_url, Opts,
|
|
||||||
fun(<<"http://", _/binary>> = URL) -> URL;
|
|
||||||
(<<"https://", _/binary>> = URL) -> URL
|
|
||||||
end,
|
|
||||||
<<"http://@HOST@:5444">>),
|
|
||||||
GetURL = gen_mod:get_opt(get_url, Opts,
|
|
||||||
fun(<<"http://", _/binary>> = URL) -> URL;
|
|
||||||
(<<"https://", _/binary>> = URL) -> URL
|
|
||||||
end,
|
|
||||||
PutURL),
|
|
||||||
ServiceURL = gen_mod:get_opt(service_url, Opts,
|
|
||||||
fun(<<"http://", _/binary>> = URL) -> URL;
|
|
||||||
(<<"https://", _/binary>> = URL) -> URL
|
|
||||||
end),
|
|
||||||
Thumbnail = gen_mod:get_opt(thumbnail, Opts,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
DocRoot1 = expand_home(str:strip(DocRoot, right, $/)),
|
DocRoot1 = expand_home(str:strip(DocRoot, right, $/)),
|
||||||
DocRoot2 = expand_host(DocRoot1, ServerHost),
|
DocRoot2 = expand_host(DocRoot1, ServerHost),
|
||||||
case DirMode of
|
case DirMode of
|
||||||
@ -476,10 +441,6 @@ process(_LocalPath, #request{method = Method, host = Host, ip = IP}) ->
|
|||||||
|
|
||||||
get_proc_name(ServerHost, ModuleName) ->
|
get_proc_name(ServerHost, ModuleName) ->
|
||||||
PutURL = gen_mod:get_module_opt(ServerHost, ?MODULE, put_url,
|
PutURL = gen_mod:get_module_opt(ServerHost, ?MODULE, put_url,
|
||||||
fun(<<"http://", _/binary>> = URL) -> URL;
|
|
||||||
(<<"https://", _/binary>> = URL) -> URL;
|
|
||||||
(_) -> <<"http://@HOST@">>
|
|
||||||
end,
|
|
||||||
<<"http://@HOST@">>),
|
<<"http://@HOST@">>),
|
||||||
{ok, {_Scheme, _UserInfo, Host, _Port, Path, _Query}} =
|
{ok, {_Scheme, _UserInfo, Host, _Port, Path, _Query}} =
|
||||||
http_uri:parse(binary_to_list(expand_host(PutURL, ServerHost))),
|
http_uri:parse(binary_to_list(expand_host(PutURL, ServerHost))),
|
||||||
@ -709,11 +670,7 @@ yield_content_type(Type) -> Type.
|
|||||||
-spec iq_disco_info(binary(), binary(), binary(), [xdata()]) -> disco_info().
|
-spec iq_disco_info(binary(), binary(), binary(), [xdata()]) -> disco_info().
|
||||||
|
|
||||||
iq_disco_info(Host, Lang, Name, AddInfo) ->
|
iq_disco_info(Host, Lang, Name, AddInfo) ->
|
||||||
Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size,
|
Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size, 104857600) of
|
||||||
fun(I) when is_integer(I), I > 0 -> I;
|
|
||||||
(infinity) -> infinity
|
|
||||||
end,
|
|
||||||
104857600) of
|
|
||||||
infinity ->
|
infinity ->
|
||||||
AddInfo;
|
AddInfo;
|
||||||
MaxSize ->
|
MaxSize ->
|
||||||
@ -846,15 +803,7 @@ http_response(Host, Code, ExtraHeaders) ->
|
|||||||
-> {pos_integer(), [{binary(), binary()}], binary()}.
|
-> {pos_integer(), [{binary(), binary()}], binary()}.
|
||||||
|
|
||||||
http_response(Host, Code, ExtraHeaders, Body) ->
|
http_response(Host, Code, ExtraHeaders, Body) ->
|
||||||
CustomHeaders =
|
CustomHeaders = gen_mod:get_module_opt(Host, ?MODULE, custom_headers, []),
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, custom_headers,
|
|
||||||
fun(Headers) ->
|
|
||||||
lists:map(fun({K, V}) ->
|
|
||||||
{iolist_to_binary(K),
|
|
||||||
iolist_to_binary(V)}
|
|
||||||
end, Headers)
|
|
||||||
end,
|
|
||||||
[]),
|
|
||||||
Headers = case proplists:is_defined(<<"Content-Type">>, ExtraHeaders) of
|
Headers = case proplists:is_defined(<<"Content-Type">>, ExtraHeaders) of
|
||||||
true ->
|
true ->
|
||||||
ExtraHeaders;
|
ExtraHeaders;
|
||||||
@ -940,13 +889,8 @@ thumb_el(Path, URI) ->
|
|||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
ServerHost = jid:nameprep(Server),
|
ServerHost = jid:nameprep(Server),
|
||||||
DocRoot = gen_mod:get_module_opt(ServerHost, ?MODULE, docroot,
|
DocRoot = gen_mod:get_module_opt(ServerHost, ?MODULE, docroot,
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"@HOME@/upload">>),
|
<<"@HOME@/upload">>),
|
||||||
JIDinURL = gen_mod:get_module_opt(ServerHost, ?MODULE, jid_in_url,
|
JIDinURL = gen_mod:get_module_opt(ServerHost, ?MODULE, jid_in_url, sha1),
|
||||||
fun(sha1) -> sha1;
|
|
||||||
(node) -> node
|
|
||||||
end,
|
|
||||||
sha1),
|
|
||||||
DocRoot1 = expand_host(expand_home(DocRoot), ServerHost),
|
DocRoot1 = expand_host(expand_home(DocRoot), ServerHost),
|
||||||
UserStr = make_user_string(jid:make(User, Server), JIDinURL),
|
UserStr = make_user_string(jid:make(User, Server), JIDinURL),
|
||||||
UserDir = str:join([DocRoot1, UserStr], <<$/>>),
|
UserDir = str:join([DocRoot1, UserStr], <<$/>>),
|
||||||
|
@ -105,18 +105,11 @@ depends(_Host, _Opts) ->
|
|||||||
init([ServerHost, Opts]) ->
|
init([ServerHost, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
AccessSoftQuota = gen_mod:get_opt(access_soft_quota, Opts,
|
AccessSoftQuota = gen_mod:get_opt(access_soft_quota, Opts,
|
||||||
fun acl:shaper_rules_validator/1,
|
|
||||||
soft_upload_quota),
|
soft_upload_quota),
|
||||||
AccessHardQuota = gen_mod:get_opt(access_hard_quota, Opts,
|
AccessHardQuota = gen_mod:get_opt(access_hard_quota, Opts,
|
||||||
fun acl:shaper_rules_validator/1,
|
|
||||||
hard_upload_quota),
|
hard_upload_quota),
|
||||||
MaxDays = gen_mod:get_opt(max_days, Opts,
|
MaxDays = gen_mod:get_opt(max_days, Opts, infinity),
|
||||||
fun(I) when is_integer(I), I > 0 -> I;
|
|
||||||
(infinity) -> infinity
|
|
||||||
end,
|
|
||||||
infinity),
|
|
||||||
DocRoot1 = gen_mod:get_module_opt(ServerHost, mod_http_upload, docroot,
|
DocRoot1 = gen_mod:get_module_opt(ServerHost, mod_http_upload, docroot,
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"@HOME@/upload">>),
|
<<"@HOME@/upload">>),
|
||||||
DocRoot2 = mod_http_upload:expand_home(str:strip(DocRoot1, right, $/)),
|
DocRoot2 = mod_http_upload:expand_home(str:strip(DocRoot1, right, $/)),
|
||||||
DocRoot3 = mod_http_upload:expand_host(DocRoot2, ServerHost),
|
DocRoot3 = mod_http_upload:expand_host(DocRoot2, ServerHost),
|
||||||
|
@ -103,14 +103,11 @@ init([Host, Opts]) ->
|
|||||||
<<"irc.@HOST@">>),
|
<<"irc.@HOST@">>),
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
Access = gen_mod:get_opt(access, Opts,
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
fun acl:access_rules_validator/1,
|
|
||||||
all),
|
|
||||||
catch ets:new(irc_connection,
|
catch ets:new(irc_connection,
|
||||||
[named_table, public,
|
[named_table, public,
|
||||||
{keypos, #irc_connection.jid_server_host}]),
|
{keypos, #irc_connection.jid_server_host}]),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
register_hooks(MyHost, IQDisc),
|
register_hooks(MyHost, IQDisc),
|
||||||
ejabberd_router:register_route(MyHost, Host),
|
ejabberd_router:register_route(MyHost, Host),
|
||||||
{ok,
|
{ok,
|
||||||
@ -138,17 +135,11 @@ handle_call(stop, _From, State) ->
|
|||||||
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
|
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
|
||||||
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"irc.@HOST@">>),
|
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"irc.@HOST@">>),
|
||||||
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"irc.@HOST@">>),
|
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"irc.@HOST@">>),
|
||||||
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts,
|
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, one_queue),
|
||||||
fun gen_iq_handler:check_type/1,
|
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, one_queue),
|
||||||
one_queue),
|
|
||||||
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts,
|
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue),
|
|
||||||
NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE),
|
NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE),
|
||||||
OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE),
|
OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE),
|
||||||
Access = gen_mod:get_opt(access, NewOpts,
|
Access = gen_mod:get_opt(access, NewOpts, all),
|
||||||
fun acl:access_rules_validator/1,
|
|
||||||
all),
|
|
||||||
if NewMod /= OldMod ->
|
if NewMod /= OldMod ->
|
||||||
NewMod:init(ServerHost, NewOpts);
|
NewMod:init(ServerHost, NewOpts);
|
||||||
true ->
|
true ->
|
||||||
@ -166,9 +157,7 @@ handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
|
|||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
Access = gen_mod:get_opt(access, NewOpts,
|
Access = gen_mod:get_opt(access, NewOpts, all),
|
||||||
fun acl:access_rules_validator/1,
|
|
||||||
all),
|
|
||||||
{noreply, State#state{host = NewHost, access = Access}};
|
{noreply, State#state{host = NewHost, access = Access}};
|
||||||
handle_cast(Msg, State) ->
|
handle_cast(Msg, State) ->
|
||||||
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
@ -593,7 +582,6 @@ get_connection_params(Host, From, IRCServer) ->
|
|||||||
|
|
||||||
get_default_encoding(ServerHost) ->
|
get_default_encoding(ServerHost) ->
|
||||||
Result = gen_mod:get_module_opt(ServerHost, ?MODULE, default_encoding,
|
Result = gen_mod:get_module_opt(ServerHost, ?MODULE, default_encoding,
|
||||||
fun iolist_to_binary/1,
|
|
||||||
?DEFAULT_IRC_ENCODING),
|
?DEFAULT_IRC_ENCODING),
|
||||||
?INFO_MSG("The default_encoding configured for "
|
?INFO_MSG("The default_encoding configured for "
|
||||||
"host ~p is: ~p~n",
|
"host ~p is: ~p~n",
|
||||||
@ -601,10 +589,10 @@ get_default_encoding(ServerHost) ->
|
|||||||
Result.
|
Result.
|
||||||
|
|
||||||
get_realname(ServerHost) ->
|
get_realname(ServerHost) ->
|
||||||
gen_mod:get_module_opt(ServerHost, ?MODULE, realname, fun iolist_to_binary/1, ?DEFAULT_REALNAME).
|
gen_mod:get_module_opt(ServerHost, ?MODULE, realname, ?DEFAULT_REALNAME).
|
||||||
|
|
||||||
get_webirc_password(ServerHost) ->
|
get_webirc_password(ServerHost) ->
|
||||||
gen_mod:get_module_opt(ServerHost, ?MODULE, webirc_password, fun iolist_to_binary/1, ?DEFAULT_WEBIRC_PASSWORD).
|
gen_mod:get_module_opt(ServerHost, ?MODULE, webirc_password, ?DEFAULT_WEBIRC_PASSWORD).
|
||||||
|
|
||||||
get_connection_params(Host, ServerHost, From,
|
get_connection_params(Host, ServerHost, From,
|
||||||
IRCServer) ->
|
IRCServer) ->
|
||||||
|
@ -53,8 +53,7 @@
|
|||||||
-callback remove_user(binary(), binary()) -> any().
|
-callback remove_user(binary(), binary()) -> any().
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
@ -92,9 +91,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
|
@ -72,8 +72,7 @@
|
|||||||
%%% API
|
%%% API
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
init_cache(Host, Opts),
|
init_cache(Host, Opts),
|
||||||
@ -100,8 +99,7 @@ start(Host, Opts) ->
|
|||||||
get_room_config, 50),
|
get_room_config, 50),
|
||||||
ejabberd_hooks:add(set_room_option, Host, ?MODULE,
|
ejabberd_hooks:add(set_room_option, Host, ?MODULE,
|
||||||
set_room_option, 50),
|
set_room_option, 50),
|
||||||
case gen_mod:get_opt(assume_mam_usage, Opts,
|
case gen_mod:get_opt(assume_mam_usage, Opts, false) of
|
||||||
fun(B) when is_boolean(B) -> B end, false) of
|
|
||||||
true ->
|
true ->
|
||||||
ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
|
ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
|
||||||
message_is_archived, 50);
|
message_is_archived, 50);
|
||||||
@ -117,7 +115,6 @@ use_cache(Host, Opts) ->
|
|||||||
true -> Mod:use_cache(Host, Opts);
|
true -> Mod:use_cache(Host, Opts);
|
||||||
false ->
|
false ->
|
||||||
gen_mod:get_opt(use_cache, Opts,
|
gen_mod:get_opt(use_cache, Opts,
|
||||||
mod_opt_type(use_cache),
|
|
||||||
ejabberd_config:use_cache(Host))
|
ejabberd_config:use_cache(Host))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -131,13 +128,10 @@ init_cache(Host, Opts) ->
|
|||||||
|
|
||||||
cache_opts(Host, Opts) ->
|
cache_opts(Host, Opts) ->
|
||||||
MaxSize = gen_mod:get_opt(cache_size, Opts,
|
MaxSize = gen_mod:get_opt(cache_size, Opts,
|
||||||
mod_opt_type(cache_size),
|
|
||||||
ejabberd_config:cache_size(Host)),
|
ejabberd_config:cache_size(Host)),
|
||||||
CacheMissed = gen_mod:get_opt(cache_missed, Opts,
|
CacheMissed = gen_mod:get_opt(cache_missed, Opts,
|
||||||
mod_opt_type(cache_missed),
|
|
||||||
ejabberd_config:cache_missed(Host)),
|
ejabberd_config:cache_missed(Host)),
|
||||||
LifeTime = case gen_mod:get_opt(cache_life_time, Opts,
|
LifeTime = case gen_mod:get_opt(cache_life_time, Opts,
|
||||||
mod_opt_type(cache_life_time),
|
|
||||||
ejabberd_config:cache_life_time(Host)) of
|
ejabberd_config:cache_life_time(Host)) of
|
||||||
infinity -> infinity;
|
infinity -> infinity;
|
||||||
I -> timer:seconds(I)
|
I -> timer:seconds(I)
|
||||||
@ -168,8 +162,7 @@ stop(Host) ->
|
|||||||
get_room_config, 50),
|
get_room_config, 50),
|
||||||
ejabberd_hooks:delete(set_room_option, Host, ?MODULE,
|
ejabberd_hooks:delete(set_room_option, Host, ?MODULE,
|
||||||
set_room_option, 50),
|
set_room_option, 50),
|
||||||
case gen_mod:get_module_opt(Host, ?MODULE, assume_mam_usage,
|
case gen_mod:get_module_opt(Host, ?MODULE, assume_mam_usage, false) of
|
||||||
fun(B) when is_boolean(B) -> B end, false) of
|
|
||||||
true ->
|
true ->
|
||||||
ejabberd_hooks:delete(message_is_archived, Host, ?MODULE,
|
ejabberd_hooks:delete(message_is_archived, Host, ?MODULE,
|
||||||
message_is_archived, 50);
|
message_is_archived, 50);
|
||||||
@ -188,16 +181,13 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
ets_cache:setopts(archive_prefs_cache, NewOpts),
|
ets_cache:setopts(archive_prefs_cache, NewOpts),
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
register_iq_handlers(Host, IQDisc);
|
register_iq_handlers(Host, IQDisc);
|
||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(assume_mam_usage, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(assume_mam_usage, NewOpts, OldOpts, false) of
|
||||||
fun(B) when is_boolean(B) -> B end, false) of
|
|
||||||
{false, true, _} ->
|
{false, true, _} ->
|
||||||
ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
|
ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
|
||||||
message_is_archived, 50);
|
message_is_archived, 50);
|
||||||
@ -431,8 +421,7 @@ message_is_archived(true, _C2SState, _Pkt) ->
|
|||||||
message_is_archived(false, #{jid := JID} = C2SState, Pkt) ->
|
message_is_archived(false, #{jid := JID} = C2SState, Pkt) ->
|
||||||
#jid{luser = LUser, lserver = LServer} = JID,
|
#jid{luser = LUser, lserver = LServer} = JID,
|
||||||
Peer = xmpp:get_from(Pkt),
|
Peer = xmpp:get_from(Pkt),
|
||||||
case gen_mod:get_module_opt(LServer, ?MODULE, assume_mam_usage,
|
case gen_mod:get_module_opt(LServer, ?MODULE, assume_mam_usage, false) of
|
||||||
fun(B) when is_boolean(B) -> B end, false) of
|
|
||||||
true ->
|
true ->
|
||||||
should_archive(strip_my_archived_tag(Pkt, LServer), LServer)
|
should_archive(strip_my_archived_tag(Pkt, LServer), LServer)
|
||||||
andalso should_archive_peer(C2SState, LUser, LServer,
|
andalso should_archive_peer(C2SState, LUser, LServer,
|
||||||
@ -788,18 +777,14 @@ get_prefs(LUser, LServer) ->
|
|||||||
Prefs;
|
Prefs;
|
||||||
error ->
|
error ->
|
||||||
ActivateOpt = gen_mod:get_module_opt(
|
ActivateOpt = gen_mod:get_module_opt(
|
||||||
LServer, ?MODULE, request_activates_archiving,
|
LServer, ?MODULE,
|
||||||
fun(B) when is_boolean(B) -> B end, false),
|
request_activates_archiving, false),
|
||||||
case ActivateOpt of
|
case ActivateOpt of
|
||||||
true ->
|
true ->
|
||||||
#archive_prefs{us = {LUser, LServer}, default = never};
|
#archive_prefs{us = {LUser, LServer}, default = never};
|
||||||
false ->
|
false ->
|
||||||
Default = gen_mod:get_module_opt(
|
Default = gen_mod:get_module_opt(
|
||||||
LServer, ?MODULE, default,
|
LServer, ?MODULE, default, never),
|
||||||
fun(always) -> always;
|
|
||||||
(never) -> never;
|
|
||||||
(roster) -> roster
|
|
||||||
end, never),
|
|
||||||
#archive_prefs{us = {LUser, LServer}, default = Default}
|
#archive_prefs{us = {LUser, LServer}, default = Default}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
@ -811,10 +796,8 @@ prefs_el(Default, Always, Never, NS) ->
|
|||||||
xmlns = NS}.
|
xmlns = NS}.
|
||||||
|
|
||||||
maybe_activate_mam(LUser, LServer) ->
|
maybe_activate_mam(LUser, LServer) ->
|
||||||
ActivateOpt = gen_mod:get_module_opt(LServer, ?MODULE,
|
ActivateOpt = gen_mod:get_module_opt(
|
||||||
request_activates_archiving,
|
LServer, ?MODULE, request_activates_archiving, false),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false),
|
|
||||||
case ActivateOpt of
|
case ActivateOpt of
|
||||||
true ->
|
true ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
@ -826,11 +809,8 @@ maybe_activate_mam(LUser, LServer) ->
|
|||||||
{ok, _Prefs} ->
|
{ok, _Prefs} ->
|
||||||
ok;
|
ok;
|
||||||
error ->
|
error ->
|
||||||
Default = gen_mod:get_module_opt(LServer, ?MODULE, default,
|
Default = gen_mod:get_module_opt(
|
||||||
fun(always) -> always;
|
LServer, ?MODULE, default, never),
|
||||||
(never) -> never;
|
|
||||||
(roster) -> roster
|
|
||||||
end, never),
|
|
||||||
write_prefs(LUser, LServer, LServer, Default, [], [])
|
write_prefs(LUser, LServer, LServer, Default, [], [])
|
||||||
end;
|
end;
|
||||||
false ->
|
false ->
|
||||||
|
@ -125,8 +125,7 @@ process_iq(#iq{lang = Lang} = IQ) ->
|
|||||||
init([ServerHost, Opts]) ->
|
init([ServerHost, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"mix.@HOST@">>),
|
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"mix.@HOST@">>),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
ConfigTab = gen_mod:get_module_proc(Host, config),
|
ConfigTab = gen_mod:get_module_proc(Host, config),
|
||||||
ets:new(ConfigTab, [named_table]),
|
ets:new(ConfigTab, [named_table]),
|
||||||
ets:insert(ConfigTab, {plugins, [<<"mix">>]}),
|
ets:insert(ConfigTab, {plugins, [<<"mix">>]}),
|
||||||
|
@ -224,8 +224,7 @@ get_online_rooms_by_user(ServerHost, LUser, LServer) ->
|
|||||||
|
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
#state{access = Access, host = MyHost,
|
#state{access = Access, host = MyHost,
|
||||||
history_size = HistorySize, queue_type = QueueType,
|
history_size = HistorySize, queue_type = QueueType,
|
||||||
room_shaper = RoomShaper} = State = init_state(Host, Opts),
|
room_shaper = RoomShaper} = State = init_state(Host, Opts),
|
||||||
@ -260,12 +259,8 @@ handle_call({create, Room, From, Nick, Opts}, _From,
|
|||||||
{reply, ok, State}.
|
{reply, ok, State}.
|
||||||
|
|
||||||
handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{host = OldHost}) ->
|
handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{host = OldHost}) ->
|
||||||
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts,
|
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, one_queue),
|
||||||
fun gen_iq_handler:check_type/1,
|
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, one_queue),
|
||||||
one_queue),
|
|
||||||
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts,
|
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue),
|
|
||||||
NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE),
|
NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE),
|
||||||
NewRMod = gen_mod:ram_db_mod(ServerHost, NewOpts, ?MODULE),
|
NewRMod = gen_mod:ram_db_mod(ServerHost, NewOpts, ?MODULE),
|
||||||
OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE),
|
OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE),
|
||||||
@ -336,32 +331,15 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
|||||||
init_state(Host, Opts) ->
|
init_state(Host, Opts) ->
|
||||||
MyHost = gen_mod:get_opt_host(Host, Opts,
|
MyHost = gen_mod:get_opt_host(Host, Opts,
|
||||||
<<"conference.@HOST@">>),
|
<<"conference.@HOST@">>),
|
||||||
Access = gen_mod:get_opt(access, Opts,
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
fun acl:access_rules_validator/1, all),
|
AccessCreate = gen_mod:get_opt(access_create, Opts, all),
|
||||||
AccessCreate = gen_mod:get_opt(access_create, Opts,
|
AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
|
||||||
fun acl:access_rules_validator/1, all),
|
AccessPersistent = gen_mod:get_opt(access_persistent, Opts, all),
|
||||||
AccessAdmin = gen_mod:get_opt(access_admin, Opts,
|
HistorySize = gen_mod:get_opt(history_size, Opts, 20),
|
||||||
fun acl:access_rules_validator/1,
|
MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts, 100),
|
||||||
none),
|
DefRoomOpts1 = gen_mod:get_opt(default_room_options, Opts, []),
|
||||||
AccessPersistent = gen_mod:get_opt(access_persistent, Opts,
|
QueueType = gen_mod:get_opt(queue_type, Opts,
|
||||||
fun acl:access_rules_validator/1,
|
ejabberd_config:default_queue_type(Host)),
|
||||||
all),
|
|
||||||
HistorySize = gen_mod:get_opt(history_size, Opts,
|
|
||||||
fun(I) when is_integer(I), I>=0 -> I end,
|
|
||||||
20),
|
|
||||||
MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts,
|
|
||||||
fun(I) when is_integer(I), I>=0 -> I end,
|
|
||||||
100),
|
|
||||||
DefRoomOpts1 = gen_mod:get_opt(default_room_options, Opts,
|
|
||||||
fun(L) when is_list(L) -> L end,
|
|
||||||
[]),
|
|
||||||
QueueType = case gen_mod:get_opt(queue_type, Opts,
|
|
||||||
mod_opt_type(queue_type)) of
|
|
||||||
undefined ->
|
|
||||||
ejabberd_config:default_queue_type(Host);
|
|
||||||
Type ->
|
|
||||||
Type
|
|
||||||
end,
|
|
||||||
DefRoomOpts =
|
DefRoomOpts =
|
||||||
lists:flatmap(
|
lists:flatmap(
|
||||||
fun({Opt, Val}) ->
|
fun({Opt, Val}) ->
|
||||||
@ -407,14 +385,12 @@ init_state(Host, Opts) ->
|
|||||||
[Opt, Val]),
|
[Opt, Val]),
|
||||||
fun(_) -> undefined end
|
fun(_) -> undefined end
|
||||||
end,
|
end,
|
||||||
case gen_mod:get_opt(Opt, [{Opt, Val}], VFun) of
|
case ejabberd_config:prepare_opt_val(Opt, Val, VFun, undefined) of
|
||||||
undefined -> [];
|
undefined -> [];
|
||||||
NewVal -> [{Opt, NewVal}]
|
NewVal -> [{Opt, NewVal}]
|
||||||
end
|
end
|
||||||
end, DefRoomOpts1),
|
end, DefRoomOpts1),
|
||||||
RoomShaper = gen_mod:get_opt(room_shaper, Opts,
|
RoomShaper = gen_mod:get_opt(room_shaper, Opts, none),
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
none),
|
|
||||||
#state{host = MyHost,
|
#state{host = MyHost,
|
||||||
server_host = Host,
|
server_host = Host,
|
||||||
access = {Access, AccessCreate, AccessAdmin, AccessPersistent},
|
access = {Access, AccessCreate, AccessAdmin, AccessPersistent},
|
||||||
@ -601,7 +577,6 @@ process_disco_items(#iq{type = get, from = From, to = To, lang = Lang,
|
|||||||
ServerHost = ejabberd_router:host_of_route(Host),
|
ServerHost = ejabberd_router:host_of_route(Host),
|
||||||
MaxRoomsDiscoItems = gen_mod:get_module_opt(
|
MaxRoomsDiscoItems = gen_mod:get_module_opt(
|
||||||
ServerHost, ?MODULE, max_rooms_discoitems,
|
ServerHost, ?MODULE, max_rooms_discoitems,
|
||||||
fun(I) when is_integer(I), I>=0 -> I end,
|
|
||||||
100),
|
100),
|
||||||
case iq_disco_items(ServerHost, Host, From, Lang,
|
case iq_disco_items(ServerHost, Host, From, Lang,
|
||||||
MaxRoomsDiscoItems, Node, RSM) of
|
MaxRoomsDiscoItems, Node, RSM) of
|
||||||
@ -655,12 +630,8 @@ check_user_can_create_room(ServerHost, AccessCreate,
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
check_create_roomid(ServerHost, RoomID) ->
|
check_create_roomid(ServerHost, RoomID) ->
|
||||||
Max = gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id,
|
Max = gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id, infinity),
|
||||||
fun(infinity) -> infinity;
|
Regexp = gen_mod:get_module_opt(ServerHost, ?MODULE, regexp_room_id, ""),
|
||||||
(I) when is_integer(I), I>0 -> I
|
|
||||||
end, infinity),
|
|
||||||
Regexp = gen_mod:get_module_opt(ServerHost, ?MODULE, regexp_room_id,
|
|
||||||
fun iolist_to_binary/1, ""),
|
|
||||||
(byte_size(RoomID) =< Max) and
|
(byte_size(RoomID) =< Max) and
|
||||||
(re:run(RoomID, Regexp, [unicode, {capture, none}]) == match).
|
(re:run(RoomID, Regexp, [unicode, {capture, none}]) == match).
|
||||||
|
|
||||||
@ -956,7 +927,7 @@ mod_opt_type(max_users_admin_threshold) ->
|
|||||||
mod_opt_type(max_users_presence) ->
|
mod_opt_type(max_users_presence) ->
|
||||||
fun (MUP) when is_integer(MUP) -> MUP end;
|
fun (MUP) when is_integer(MUP) -> MUP end;
|
||||||
mod_opt_type(min_message_interval) ->
|
mod_opt_type(min_message_interval) ->
|
||||||
fun (MMI) when is_number(MMI) -> MMI end;
|
fun (MMI) when is_number(MMI), MMI >= 0 -> MMI end;
|
||||||
mod_opt_type(min_presence_interval) ->
|
mod_opt_type(min_presence_interval) ->
|
||||||
fun (I) when is_number(I), I >= 0 -> I end;
|
fun (I) when is_number(I), I >= 0 -> I end;
|
||||||
mod_opt_type(room_shaper) ->
|
mod_opt_type(room_shaper) ->
|
||||||
|
@ -476,7 +476,7 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) ->
|
|||||||
|
|
||||||
%% Get the default room options from the muc configuration
|
%% Get the default room options from the muc configuration
|
||||||
DefRoomOpts = gen_mod:get_module_opt(ServerHost, mod_muc,
|
DefRoomOpts = gen_mod:get_module_opt(ServerHost, mod_muc,
|
||||||
default_room_options, fun(X) -> X end, []),
|
default_room_options, []),
|
||||||
%% Change default room options as required
|
%% Change default room options as required
|
||||||
FormattedRoomOpts = [format_room_option(Opt, Val) || {Opt, Val}<-CustomRoomOpts],
|
FormattedRoomOpts = [format_room_option(Opt, Val) || {Opt, Val}<-CustomRoomOpts],
|
||||||
RoomOpts = lists:ukeymerge(1,
|
RoomOpts = lists:ukeymerge(1,
|
||||||
@ -487,13 +487,13 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) ->
|
|||||||
mod_muc:store_room(ServerHost, Host, Name, RoomOpts),
|
mod_muc:store_room(ServerHost, Host, Name, RoomOpts),
|
||||||
|
|
||||||
%% Get all remaining mod_muc parameters that might be utilized
|
%% Get all remaining mod_muc parameters that might be utilized
|
||||||
Access = gen_mod:get_module_opt(ServerHost, mod_muc, access, fun(X) -> X end, all),
|
Access = gen_mod:get_module_opt(ServerHost, mod_muc, access, all),
|
||||||
AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create, fun(X) -> X end, all),
|
AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create, all),
|
||||||
AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin, fun(X) -> X end, none),
|
AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin, none),
|
||||||
AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent, fun(X) -> X end, all),
|
AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent, all),
|
||||||
HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, fun(X) -> X end, 20),
|
HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, 20),
|
||||||
RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper, fun(X) -> X end, none),
|
RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper, none),
|
||||||
QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type, fun(X) -> X end,
|
QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type,
|
||||||
ejabberd_config:default_queue_type(ServerHost)),
|
ejabberd_config:default_queue_type(ServerHost)),
|
||||||
|
|
||||||
%% If the room does not exist yet in the muc_online_room
|
%% If the room does not exist yet in the muc_online_room
|
||||||
@ -596,8 +596,7 @@ create_rooms_file(Filename) ->
|
|||||||
file:close(F),
|
file:close(F),
|
||||||
%% Read the default room options defined for the first virtual host
|
%% Read the default room options defined for the first virtual host
|
||||||
DefRoomOpts = gen_mod:get_module_opt(?MYNAME, mod_muc,
|
DefRoomOpts = gen_mod:get_module_opt(?MYNAME, mod_muc,
|
||||||
default_room_options,
|
default_room_options, []),
|
||||||
fun(L) when is_list(L) -> L end, []),
|
|
||||||
[muc_create_room(?MYNAME, A, DefRoomOpts) || A <- Rooms],
|
[muc_create_room(?MYNAME, A, DefRoomOpts) || A <- Rooms],
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -138,48 +138,16 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
|||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
init_state(Host, Opts) ->
|
init_state(Host, Opts) ->
|
||||||
OutDir = gen_mod:get_opt(outdir, Opts,
|
OutDir = gen_mod:get_opt(outdir, Opts, <<"www/muc">>),
|
||||||
fun iolist_to_binary/1,
|
DirType = gen_mod:get_opt(dirtype, Opts, subdirs),
|
||||||
<<"www/muc">>),
|
DirName = gen_mod:get_opt(dirname, Opts, room_jid),
|
||||||
DirType = gen_mod:get_opt(dirtype, Opts,
|
FileFormat = gen_mod:get_opt(file_format, Opts, html),
|
||||||
fun(subdirs) -> subdirs;
|
FilePermissions = gen_mod:get_opt(file_permissions, Opts, {644, 33}),
|
||||||
(plain) -> plain
|
CSSFile = gen_mod:get_opt(cssfile, Opts, false),
|
||||||
end, subdirs),
|
AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin),
|
||||||
DirName = gen_mod:get_opt(dirname, Opts,
|
Timezone = gen_mod:get_opt(timezone, Opts, local),
|
||||||
fun(room_jid) -> room_jid;
|
Top_link = gen_mod:get_opt(top_link, Opts, {<<"/">>, <<"Home">>}),
|
||||||
(room_name) -> room_name
|
NoFollow = gen_mod:get_opt(spam_prevention, Opts, true),
|
||||||
end, room_jid),
|
|
||||||
FileFormat = gen_mod:get_opt(file_format, Opts,
|
|
||||||
fun(html) -> html;
|
|
||||||
(plaintext) -> plaintext
|
|
||||||
end, html),
|
|
||||||
FilePermissions = gen_mod:get_opt(file_permissions, Opts,
|
|
||||||
fun(SubOpts) ->
|
|
||||||
F = fun({mode, Mode}, {_M, G}) ->
|
|
||||||
{Mode, G};
|
|
||||||
({group, Group}, {M, _G}) ->
|
|
||||||
{M, Group}
|
|
||||||
end,
|
|
||||||
lists:foldl(F, {644, 33}, SubOpts)
|
|
||||||
end, {644, 33}),
|
|
||||||
CSSFile = gen_mod:get_opt(cssfile, Opts,
|
|
||||||
fun iolist_to_binary/1,
|
|
||||||
false),
|
|
||||||
AccessLog = gen_mod:get_opt(access_log, Opts,
|
|
||||||
fun acl:access_rules_validator/1,
|
|
||||||
muc_admin),
|
|
||||||
Timezone = gen_mod:get_opt(timezone, Opts,
|
|
||||||
fun(local) -> local;
|
|
||||||
(universal) -> universal
|
|
||||||
end, local),
|
|
||||||
Top_link = gen_mod:get_opt(top_link, Opts,
|
|
||||||
fun([{S1, S2}]) ->
|
|
||||||
{iolist_to_binary(S1),
|
|
||||||
iolist_to_binary(S2)}
|
|
||||||
end, {<<"/">>, <<"Home">>}),
|
|
||||||
NoFollow = gen_mod:get_opt(spam_prevention, Opts,
|
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true),
|
|
||||||
Lang = ejabberd_config:get_lang(Host),
|
Lang = ejabberd_config:get_lang(Host),
|
||||||
#logstate{host = Host, out_dir = OutDir,
|
#logstate{host = Host, out_dir = OutDir,
|
||||||
dir_type = DirType, dir_name = DirName,
|
dir_type = DirType, dir_name = DirName,
|
||||||
@ -1201,7 +1169,7 @@ has_no_permanent_store_hint(Packet) ->
|
|||||||
xmpp:has_subtag(Packet, #hint{type = 'no-permanent-storage'}).
|
xmpp:has_subtag(Packet, #hint{type = 'no-permanent-storage'}).
|
||||||
|
|
||||||
mod_opt_type(access_log) ->
|
mod_opt_type(access_log) ->
|
||||||
fun (A) when is_atom(A) -> A end;
|
fun acl:access_rules_validator/1;
|
||||||
mod_opt_type(cssfile) -> fun iolist_to_binary/1;
|
mod_opt_type(cssfile) -> fun iolist_to_binary/1;
|
||||||
mod_opt_type(dirname) ->
|
mod_opt_type(dirname) ->
|
||||||
fun (room_jid) -> room_jid;
|
fun (room_jid) -> room_jid;
|
||||||
|
@ -165,8 +165,7 @@ normal_state({route, <<"">>,
|
|||||||
MinMessageInterval = trunc(gen_mod:get_module_opt(
|
MinMessageInterval = trunc(gen_mod:get_module_opt(
|
||||||
StateData#state.server_host,
|
StateData#state.server_host,
|
||||||
mod_muc, min_message_interval,
|
mod_muc, min_message_interval,
|
||||||
fun(MMI) when is_number(MMI) -> MMI end, 0)
|
0) * 1000000),
|
||||||
* 1000000),
|
|
||||||
Size = element_size(Packet),
|
Size = element_size(Packet),
|
||||||
{MessageShaper, MessageShaperInterval} =
|
{MessageShaper, MessageShaperInterval} =
|
||||||
shaper:update(Activity#activity.message_shaper, Size),
|
shaper:update(Activity#activity.message_shaper, Size),
|
||||||
@ -347,10 +346,7 @@ normal_state({route, Nick, #presence{from = From} = Packet}, StateData) ->
|
|||||||
MinPresenceInterval =
|
MinPresenceInterval =
|
||||||
trunc(gen_mod:get_module_opt(StateData#state.server_host,
|
trunc(gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, min_presence_interval,
|
mod_muc, min_presence_interval,
|
||||||
fun(I) when is_number(I), I>=0 ->
|
0) * 1000000),
|
||||||
I
|
|
||||||
end, 0)
|
|
||||||
* 1000000),
|
|
||||||
if (Now >= Activity#activity.presence_time + MinPresenceInterval)
|
if (Now >= Activity#activity.presence_time + MinPresenceInterval)
|
||||||
and (Activity#activity.presence == undefined) ->
|
and (Activity#activity.presence == undefined) ->
|
||||||
NewActivity = Activity#activity{presence_time = Now},
|
NewActivity = Activity#activity{presence_time = Now},
|
||||||
@ -1415,14 +1411,12 @@ get_max_users(StateData) ->
|
|||||||
get_service_max_users(StateData) ->
|
get_service_max_users(StateData) ->
|
||||||
gen_mod:get_module_opt(StateData#state.server_host,
|
gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, max_users,
|
mod_muc, max_users,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
?MAX_USERS_DEFAULT).
|
?MAX_USERS_DEFAULT).
|
||||||
|
|
||||||
-spec get_max_users_admin_threshold(state()) -> pos_integer().
|
-spec get_max_users_admin_threshold(state()) -> pos_integer().
|
||||||
get_max_users_admin_threshold(StateData) ->
|
get_max_users_admin_threshold(StateData) ->
|
||||||
gen_mod:get_module_opt(StateData#state.server_host,
|
gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, max_users_admin_threshold,
|
mod_muc, max_users_admin_threshold,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
5).
|
5).
|
||||||
|
|
||||||
-spec room_queue_new(binary(), shaper:shaper(), _) -> p1_queue:queue().
|
-spec room_queue_new(binary(), shaper:shaper(), _) -> p1_queue:queue().
|
||||||
@ -1430,19 +1424,15 @@ room_queue_new(ServerHost, Shaper, QueueType) ->
|
|||||||
HaveRoomShaper = Shaper /= none,
|
HaveRoomShaper = Shaper /= none,
|
||||||
HaveMessageShaper = gen_mod:get_module_opt(
|
HaveMessageShaper = gen_mod:get_module_opt(
|
||||||
ServerHost, mod_muc, user_message_shaper,
|
ServerHost, mod_muc, user_message_shaper,
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
none) /= none,
|
none) /= none,
|
||||||
HavePresenceShaper = gen_mod:get_module_opt(
|
HavePresenceShaper = gen_mod:get_module_opt(
|
||||||
ServerHost, mod_muc, user_presence_shaper,
|
ServerHost, mod_muc, user_presence_shaper,
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
none) /= none,
|
none) /= none,
|
||||||
HaveMinMessageInterval = gen_mod:get_module_opt(
|
HaveMinMessageInterval = gen_mod:get_module_opt(
|
||||||
ServerHost, mod_muc, min_message_interval,
|
ServerHost, mod_muc, min_message_interval,
|
||||||
fun(I) when is_number(I), I>=0 -> I end,
|
|
||||||
0) /= 0,
|
0) /= 0,
|
||||||
HaveMinPresenceInterval = gen_mod:get_module_opt(
|
HaveMinPresenceInterval = gen_mod:get_module_opt(
|
||||||
ServerHost, mod_muc, min_presence_interval,
|
ServerHost, mod_muc, min_presence_interval,
|
||||||
fun(I) when is_number(I), I>=0 -> I end,
|
|
||||||
0) /= 0,
|
0) /= 0,
|
||||||
if HaveRoomShaper or HaveMessageShaper or HavePresenceShaper
|
if HaveRoomShaper or HaveMessageShaper or HavePresenceShaper
|
||||||
or HaveMinMessageInterval or HaveMinPresenceInterval ->
|
or HaveMinMessageInterval or HaveMinPresenceInterval ->
|
||||||
@ -1461,12 +1451,10 @@ get_user_activity(JID, StateData) ->
|
|||||||
MessageShaper =
|
MessageShaper =
|
||||||
shaper:new(gen_mod:get_module_opt(StateData#state.server_host,
|
shaper:new(gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, user_message_shaper,
|
mod_muc, user_message_shaper,
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
none)),
|
none)),
|
||||||
PresenceShaper =
|
PresenceShaper =
|
||||||
shaper:new(gen_mod:get_module_opt(StateData#state.server_host,
|
shaper:new(gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, user_presence_shaper,
|
mod_muc, user_presence_shaper,
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
none)),
|
none)),
|
||||||
#activity{message_shaper = MessageShaper,
|
#activity{message_shaper = MessageShaper,
|
||||||
presence_shaper = PresenceShaper}
|
presence_shaper = PresenceShaper}
|
||||||
@ -1477,15 +1465,11 @@ store_user_activity(JID, UserActivity, StateData) ->
|
|||||||
MinMessageInterval =
|
MinMessageInterval =
|
||||||
trunc(gen_mod:get_module_opt(StateData#state.server_host,
|
trunc(gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, min_message_interval,
|
mod_muc, min_message_interval,
|
||||||
fun(I) when is_number(I), I>=0 -> I end,
|
0) * 1000),
|
||||||
0)
|
|
||||||
* 1000),
|
|
||||||
MinPresenceInterval =
|
MinPresenceInterval =
|
||||||
trunc(gen_mod:get_module_opt(StateData#state.server_host,
|
trunc(gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, min_presence_interval,
|
mod_muc, min_presence_interval,
|
||||||
fun(I) when is_number(I), I>=0 -> I end,
|
0) * 1000),
|
||||||
0)
|
|
||||||
* 1000),
|
|
||||||
Key = jid:tolower(JID),
|
Key = jid:tolower(JID),
|
||||||
Now = p1_time_compat:system_time(micro_seconds),
|
Now = p1_time_compat:system_time(micro_seconds),
|
||||||
Activity1 = clean_treap(StateData#state.activity,
|
Activity1 = clean_treap(StateData#state.activity,
|
||||||
@ -1788,7 +1772,6 @@ add_new_user(From, Nick, Packet, StateData) ->
|
|||||||
MaxConferences =
|
MaxConferences =
|
||||||
gen_mod:get_module_opt(StateData#state.server_host,
|
gen_mod:get_module_opt(StateData#state.server_host,
|
||||||
mod_muc, max_user_conferences,
|
mod_muc, max_user_conferences,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
10),
|
10),
|
||||||
Collision = nick_collision(From, Nick, StateData),
|
Collision = nick_collision(From, Nick, StateData),
|
||||||
IsSubscribeRequest = not is_record(Packet, presence),
|
IsSubscribeRequest = not is_record(Packet, presence),
|
||||||
@ -2061,10 +2044,10 @@ filter_history(Queue, Now, Nick,
|
|||||||
|
|
||||||
-spec is_room_overcrowded(state()) -> boolean().
|
-spec is_room_overcrowded(state()) -> boolean().
|
||||||
is_room_overcrowded(StateData) ->
|
is_room_overcrowded(StateData) ->
|
||||||
MaxUsersPresence = gen_mod:get_module_opt(StateData#state.server_host,
|
MaxUsersPresence = gen_mod:get_module_opt(
|
||||||
mod_muc, max_users_presence,
|
StateData#state.server_host,
|
||||||
fun(MUP) when is_integer(MUP) -> MUP end,
|
mod_muc, max_users_presence,
|
||||||
?DEFAULT_MAX_USERS_PRESENCE),
|
?DEFAULT_MAX_USERS_PRESENCE),
|
||||||
(?DICT):size(StateData#state.users) > MaxUsersPresence.
|
(?DICT):size(StateData#state.users) > MaxUsersPresence.
|
||||||
|
|
||||||
-spec presence_broadcast_allowed(jid(), state()) -> boolean().
|
-spec presence_broadcast_allowed(jid(), state()) -> boolean().
|
||||||
@ -3114,18 +3097,11 @@ is_allowed_room_name_desc_limits(Options, StateData) ->
|
|||||||
MaxRoomName = gen_mod:get_module_opt(
|
MaxRoomName = gen_mod:get_module_opt(
|
||||||
StateData#state.server_host,
|
StateData#state.server_host,
|
||||||
mod_muc, max_room_name,
|
mod_muc, max_room_name,
|
||||||
fun(infinity) -> infinity;
|
infinity),
|
||||||
(I) when is_integer(I),
|
|
||||||
I>0 -> I
|
|
||||||
end, infinity),
|
|
||||||
MaxRoomDesc = gen_mod:get_module_opt(
|
MaxRoomDesc = gen_mod:get_module_opt(
|
||||||
StateData#state.server_host,
|
StateData#state.server_host,
|
||||||
mod_muc, max_room_desc,
|
mod_muc, max_room_desc,
|
||||||
fun(infinity) -> infinity;
|
infinity),
|
||||||
(I) when is_integer(I),
|
|
||||||
I>0 ->
|
|
||||||
I
|
|
||||||
end, infinity),
|
|
||||||
(byte_size(RoomName) =< MaxRoomName)
|
(byte_size(RoomName) =< MaxRoomName)
|
||||||
andalso (byte_size(RoomDesc) =< MaxRoomDesc).
|
andalso (byte_size(RoomDesc) =< MaxRoomDesc).
|
||||||
|
|
||||||
@ -3151,7 +3127,6 @@ get_default_room_maxusers(RoomState) ->
|
|||||||
DefRoomOpts =
|
DefRoomOpts =
|
||||||
gen_mod:get_module_opt(RoomState#state.server_host,
|
gen_mod:get_module_opt(RoomState#state.server_host,
|
||||||
mod_muc, default_room_options,
|
mod_muc, default_room_options,
|
||||||
fun(L) when is_list(L) -> L end,
|
|
||||||
[]),
|
[]),
|
||||||
RoomState2 = set_opts(DefRoomOpts, RoomState),
|
RoomState2 = set_opts(DefRoomOpts, RoomState),
|
||||||
(RoomState2#state.config)#config.max_users.
|
(RoomState2#state.config)#config.max_users.
|
||||||
|
@ -134,14 +134,8 @@ init([LServerS, Opts]) ->
|
|||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
LServiceS = gen_mod:get_opt_host(LServerS, Opts,
|
LServiceS = gen_mod:get_opt_host(LServerS, Opts,
|
||||||
<<"multicast.@HOST@">>),
|
<<"multicast.@HOST@">>),
|
||||||
Access = gen_mod:get_opt(access, Opts,
|
Access = gen_mod:get_opt(access, Opts, all),
|
||||||
fun acl:access_rules_validator/1, all),
|
SLimits = build_service_limit_record(gen_mod:get_opt(limits, Opts, [])),
|
||||||
SLimits =
|
|
||||||
build_service_limit_record(gen_mod:get_opt(limits, Opts,
|
|
||||||
fun (A) when is_list(A) ->
|
|
||||||
A
|
|
||||||
end,
|
|
||||||
[])),
|
|
||||||
create_cache(),
|
create_cache(),
|
||||||
try_start_loop(),
|
try_start_loop(),
|
||||||
create_pool(),
|
create_pool(),
|
||||||
@ -156,14 +150,8 @@ handle_call(stop, _From, State) ->
|
|||||||
|
|
||||||
handle_cast({reload, NewOpts, NewOpts},
|
handle_cast({reload, NewOpts, NewOpts},
|
||||||
#state{lserver = LServerS, lservice = OldLServiceS} = State) ->
|
#state{lserver = LServerS, lservice = OldLServiceS} = State) ->
|
||||||
Access = gen_mod:get_opt(access, NewOpts,
|
Access = gen_mod:get_opt(access, NewOpts, all),
|
||||||
fun acl:access_rules_validator/1, all),
|
SLimits = build_service_limit_record(gen_mod:get_opt(limits, NewOpts, [])),
|
||||||
SLimits =
|
|
||||||
build_service_limit_record(gen_mod:get_opt(limits, NewOpts,
|
|
||||||
fun (A) when is_list(A) ->
|
|
||||||
A
|
|
||||||
end,
|
|
||||||
[])),
|
|
||||||
NewLServiceS = gen_mod:get_opt_host(LServerS, NewOpts,
|
NewLServiceS = gen_mod:get_opt_host(LServerS, NewOpts,
|
||||||
<<"multicast.@HOST@">>),
|
<<"multicast.@HOST@">>),
|
||||||
if NewLServiceS /= OldLServiceS ->
|
if NewLServiceS /= OldLServiceS ->
|
||||||
|
@ -129,8 +129,7 @@ init([Host, Opts]) ->
|
|||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, no_queue),
|
||||||
no_queue),
|
|
||||||
ejabberd_hooks:add(offline_message_hook, Host, ?MODULE,
|
ejabberd_hooks:add(offline_message_hook, Host, ?MODULE,
|
||||||
store_packet, 50),
|
store_packet, 50),
|
||||||
ejabberd_hooks:add(c2s_self_presence, Host, ?MODULE, c2s_self_presence, 50),
|
ejabberd_hooks:add(c2s_self_presence, Host, ?MODULE, c2s_self_presence, 50),
|
||||||
@ -157,7 +156,6 @@ init([Host, Opts]) ->
|
|||||||
?MODULE, handle_offline_query, IQDisc),
|
?MODULE, handle_offline_query, IQDisc),
|
||||||
AccessMaxOfflineMsgs =
|
AccessMaxOfflineMsgs =
|
||||||
gen_mod:get_opt(access_max_user_messages, Opts,
|
gen_mod:get_opt(access_max_user_messages, Opts,
|
||||||
fun acl:shaper_rules_validator/1,
|
|
||||||
max_user_offline_messages),
|
max_user_offline_messages),
|
||||||
{ok,
|
{ok,
|
||||||
#state{host = Host,
|
#state{host = Host,
|
||||||
@ -175,9 +173,7 @@ handle_cast({reload, NewOpts, OldOpts}, #state{host = Host} = State) ->
|
|||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_FLEX_OFFLINE,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_FLEX_OFFLINE,
|
||||||
?MODULE, handle_offline_query, IQDisc);
|
?MODULE, handle_offline_query, IQDisc);
|
||||||
@ -185,7 +181,6 @@ handle_cast({reload, NewOpts, OldOpts}, #state{host = Host} = State) ->
|
|||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(access_max_user_messages, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(access_max_user_messages, NewOpts, OldOpts,
|
||||||
fun acl:shaper_rules_validator/1,
|
|
||||||
max_user_offline_messages) of
|
max_user_offline_messages) of
|
||||||
{false, AccessMaxOfflineMsgs, _} ->
|
{false, AccessMaxOfflineMsgs, _} ->
|
||||||
{noreply,
|
{noreply,
|
||||||
@ -462,9 +457,6 @@ need_to_store(LServer, #message{type = Type} = Packet) ->
|
|||||||
none ->
|
none ->
|
||||||
case gen_mod:get_module_opt(
|
case gen_mod:get_module_opt(
|
||||||
LServer, ?MODULE, store_empty_body,
|
LServer, ?MODULE, store_empty_body,
|
||||||
fun(V) when is_boolean(V) -> V;
|
|
||||||
(unless_chat_state) -> unless_chat_state
|
|
||||||
end,
|
|
||||||
unless_chat_state) of
|
unless_chat_state) of
|
||||||
true ->
|
true ->
|
||||||
true;
|
true;
|
||||||
@ -799,7 +791,6 @@ get_queue_length(LUser, LServer) ->
|
|||||||
|
|
||||||
get_messages_subset(User, Host, MsgsAll) ->
|
get_messages_subset(User, Host, MsgsAll) ->
|
||||||
Access = gen_mod:get_module_opt(Host, ?MODULE, access_max_user_messages,
|
Access = gen_mod:get_module_opt(Host, ?MODULE, access_max_user_messages,
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
max_user_offline_messages),
|
max_user_offline_messages),
|
||||||
MaxOfflineMsgs = case get_max_user_messages(Access,
|
MaxOfflineMsgs = case get_max_user_messages(Access,
|
||||||
User, Host)
|
User, Host)
|
||||||
|
@ -95,8 +95,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
State = init_state(Host, Opts),
|
State = init_state(Host, Opts),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, no_queue),
|
||||||
no_queue),
|
|
||||||
register_iq_handlers(Host, IQDisc),
|
register_iq_handlers(Host, IQDisc),
|
||||||
case State#state.send_pings of
|
case State#state.send_pings of
|
||||||
true -> register_hooks(Host);
|
true -> register_hooks(Host);
|
||||||
@ -115,9 +114,7 @@ handle_call(_Req, _From, State) ->
|
|||||||
|
|
||||||
handle_cast({reload, Host, NewOpts, OldOpts},
|
handle_cast({reload, Host, NewOpts, OldOpts},
|
||||||
#state{timers = Timers} = OldState) ->
|
#state{timers = Timers} = OldState) ->
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} -> register_iq_handlers(Host, IQDisc);
|
{false, IQDisc, _} -> register_iq_handlers(Host, IQDisc);
|
||||||
true -> ok
|
true -> ok
|
||||||
end,
|
end,
|
||||||
@ -200,19 +197,10 @@ user_send({Packet, #{jid := JID} = C2SState}) ->
|
|||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
init_state(Host, Opts) ->
|
init_state(Host, Opts) ->
|
||||||
SendPings = gen_mod:get_opt(send_pings, Opts,
|
SendPings = gen_mod:get_opt(send_pings, Opts, ?DEFAULT_SEND_PINGS),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
PingInterval = gen_mod:get_opt(ping_interval, Opts, ?DEFAULT_PING_INTERVAL),
|
||||||
?DEFAULT_SEND_PINGS),
|
PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts),
|
||||||
PingInterval = gen_mod:get_opt(ping_interval, Opts,
|
TimeoutAction = gen_mod:get_opt(timeout_action, Opts, none),
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
?DEFAULT_PING_INTERVAL),
|
|
||||||
PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts,
|
|
||||||
fun(I) when is_integer(I), I>0 -> I * 1000 end,
|
|
||||||
undefined),
|
|
||||||
TimeoutAction = gen_mod:get_opt(timeout_action, Opts,
|
|
||||||
fun(none) -> none;
|
|
||||||
(kill) -> kill
|
|
||||||
end, none),
|
|
||||||
#state{host = Host,
|
#state{host = Host,
|
||||||
send_pings = SendPings,
|
send_pings = SendPings,
|
||||||
ping_interval = PingInterval,
|
ping_interval = PingInterval,
|
||||||
@ -284,7 +272,7 @@ mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
|
|||||||
mod_opt_type(ping_interval) ->
|
mod_opt_type(ping_interval) ->
|
||||||
fun (I) when is_integer(I), I > 0 -> I end;
|
fun (I) when is_integer(I), I > 0 -> I end;
|
||||||
mod_opt_type(ping_ack_timeout) ->
|
mod_opt_type(ping_ack_timeout) ->
|
||||||
fun (I) when is_integer(I), I > 0 -> I end;
|
fun(I) when is_integer(I), I>0 -> timer:seconds(I) end;
|
||||||
mod_opt_type(send_pings) ->
|
mod_opt_type(send_pings) ->
|
||||||
fun (B) when is_boolean(B) -> B end;
|
fun (B) when is_boolean(B) -> B end;
|
||||||
mod_opt_type(timeout_action) ->
|
mod_opt_type(timeout_action) ->
|
||||||
|
@ -79,12 +79,8 @@ check_packet(Acc, _, _, _) ->
|
|||||||
Acc.
|
Acc.
|
||||||
|
|
||||||
update(Server, JID, Dir) ->
|
update(Server, JID, Dir) ->
|
||||||
StormCount = gen_mod:get_module_opt(Server, ?MODULE, count,
|
StormCount = gen_mod:get_module_opt(Server, ?MODULE, count, 5),
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
TimeInterval = gen_mod:get_module_opt(Server, ?MODULE, interval, 60),
|
||||||
5),
|
|
||||||
TimeInterval = gen_mod:get_module_opt(Server, ?MODULE, interval,
|
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
60),
|
|
||||||
TimeStamp = p1_time_compat:system_time(seconds),
|
TimeStamp = p1_time_compat:system_time(seconds),
|
||||||
case read(Dir) of
|
case read(Dir) of
|
||||||
undefined ->
|
undefined ->
|
||||||
|
@ -60,8 +60,7 @@
|
|||||||
-callback remove_user(binary(), binary()) -> any().
|
-callback remove_user(binary(), binary()) -> any().
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
ejabberd_hooks:add(disco_local_features, Host, ?MODULE,
|
ejabberd_hooks:add(disco_local_features, Host, ?MODULE,
|
||||||
@ -107,9 +106,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
|
||||||
?MODULE, process_iq, IQDisc);
|
?MODULE, process_iq, IQDisc);
|
||||||
|
@ -49,8 +49,7 @@
|
|||||||
-callback remove_user(binary(), binary()) -> any().
|
-callback remove_user(binary(), binary()) -> any().
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
ejabberd_hooks:add(remove_user, Host, ?MODULE,
|
ejabberd_hooks:add(remove_user, Host, ?MODULE,
|
||||||
@ -72,9 +71,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
|
||||||
?MODULE, process_sm_iq, IQDisc);
|
?MODULE, process_sm_iq, IQDisc);
|
||||||
|
@ -58,9 +58,29 @@ stop(Host) ->
|
|||||||
reload(_Host, _NewOpts, _OldOpts) ->
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
mod_opt_type(roster) -> v_roster();
|
mod_opt_type(roster) ->
|
||||||
mod_opt_type(message) -> v_message();
|
fun(Props) ->
|
||||||
mod_opt_type(presence) -> v_presence();
|
lists:map(
|
||||||
|
fun({both, ACL}) -> {both, acl:access_rules_validator(ACL)};
|
||||||
|
({get, ACL}) -> {get, acl:access_rules_validator(ACL)};
|
||||||
|
({set, ACL}) -> {set, acl:access_rules_validator(ACL)}
|
||||||
|
end, Props)
|
||||||
|
end;
|
||||||
|
mod_opt_type(message) ->
|
||||||
|
fun(Props) ->
|
||||||
|
lists:map(
|
||||||
|
fun({outgoing, ACL}) -> {outgoing, acl:access_rules_validator(ACL)}
|
||||||
|
end, Props)
|
||||||
|
end;
|
||||||
|
mod_opt_type(presence) ->
|
||||||
|
fun(Props) ->
|
||||||
|
lists:map(
|
||||||
|
fun({managed_entity, ACL}) ->
|
||||||
|
{managed_entity, acl:access_rules_validator(ACL)};
|
||||||
|
({roster, ACL}) ->
|
||||||
|
{roster, acl:access_rules_validator(ACL)}
|
||||||
|
end, Props)
|
||||||
|
end;
|
||||||
mod_opt_type(_) ->
|
mod_opt_type(_) ->
|
||||||
[roster, message, presence].
|
[roster, message, presence].
|
||||||
|
|
||||||
@ -302,8 +322,7 @@ forward_message(#message{to = To} = Msg) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
get_roster_permission(ServerHost, Host) ->
|
get_roster_permission(ServerHost, Host) ->
|
||||||
Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, roster,
|
Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, roster, []),
|
||||||
v_roster(), []),
|
|
||||||
case match_rule(ServerHost, Host, Perms, both) of
|
case match_rule(ServerHost, Host, Perms, both) of
|
||||||
allow ->
|
allow ->
|
||||||
both;
|
both;
|
||||||
@ -318,16 +337,14 @@ get_roster_permission(ServerHost, Host) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
get_message_permission(ServerHost, Host) ->
|
get_message_permission(ServerHost, Host) ->
|
||||||
Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, message,
|
Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, message, []),
|
||||||
v_message(), []),
|
|
||||||
case match_rule(ServerHost, Host, Perms, outgoing) of
|
case match_rule(ServerHost, Host, Perms, outgoing) of
|
||||||
allow -> outgoing;
|
allow -> outgoing;
|
||||||
deny -> none
|
deny -> none
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_presence_permission(ServerHost, Host) ->
|
get_presence_permission(ServerHost, Host) ->
|
||||||
Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, presence,
|
Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, presence, []),
|
||||||
v_presence(), []),
|
|
||||||
case match_rule(ServerHost, Host, Perms, roster) of
|
case match_rule(ServerHost, Host, Perms, roster) of
|
||||||
allow ->
|
allow ->
|
||||||
roster;
|
roster;
|
||||||
@ -341,29 +358,3 @@ get_presence_permission(ServerHost, Host) ->
|
|||||||
match_rule(ServerHost, Host, Perms, Type) ->
|
match_rule(ServerHost, Host, Perms, Type) ->
|
||||||
Access = proplists:get_value(Type, Perms, none),
|
Access = proplists:get_value(Type, Perms, none),
|
||||||
acl:match_rule(ServerHost, Access, jid:make(Host)).
|
acl:match_rule(ServerHost, Access, jid:make(Host)).
|
||||||
|
|
||||||
v_roster() ->
|
|
||||||
fun(Props) ->
|
|
||||||
lists:map(
|
|
||||||
fun({both, ACL}) -> {both, acl:access_rules_validator(ACL)};
|
|
||||||
({get, ACL}) -> {get, acl:access_rules_validator(ACL)};
|
|
||||||
({set, ACL}) -> {set, acl:access_rules_validator(ACL)}
|
|
||||||
end, Props)
|
|
||||||
end.
|
|
||||||
|
|
||||||
v_message() ->
|
|
||||||
fun(Props) ->
|
|
||||||
lists:map(
|
|
||||||
fun({outgoing, ACL}) -> {outgoing, acl:access_rules_validator(ACL)}
|
|
||||||
end, Props)
|
|
||||||
end.
|
|
||||||
|
|
||||||
v_presence() ->
|
|
||||||
fun(Props) ->
|
|
||||||
lists:map(
|
|
||||||
fun({managed_entity, ACL}) ->
|
|
||||||
{managed_entity, acl:access_rules_validator(ACL)};
|
|
||||||
({roster, ACL}) ->
|
|
||||||
{roster, acl:access_rules_validator(ACL)}
|
|
||||||
end, Props)
|
|
||||||
end.
|
|
||||||
|
@ -50,14 +50,21 @@
|
|||||||
ok | {error, limit | conflict | notfound | term()}.
|
ok | {error, limit | conflict | notfound | term()}.
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
case mod_proxy65_service:add_listener(Host, Opts) of
|
{ListenOpts, ModOpts} = lists:partition(
|
||||||
|
fun({auth_type, _}) -> true;
|
||||||
|
({recbuf, _}) -> true;
|
||||||
|
({sndbuf, _}) -> true;
|
||||||
|
({shaper, _}) -> true;
|
||||||
|
(_) -> false
|
||||||
|
end, Opts),
|
||||||
|
case mod_proxy65_service:add_listener(Host, ListenOpts) of
|
||||||
{error, _} = Err ->
|
{error, _} = Err ->
|
||||||
Err;
|
Err;
|
||||||
_ ->
|
_ ->
|
||||||
Mod = gen_mod:ram_db_mod(global, ?MODULE),
|
Mod = gen_mod:ram_db_mod(global, ?MODULE),
|
||||||
Mod:init(),
|
Mod:init(),
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]},
|
ChildSpec = {Proc, {?MODULE, start_link, [Host, ModOpts]},
|
||||||
transient, infinity, supervisor, [?MODULE]},
|
transient, infinity, supervisor, [?MODULE]},
|
||||||
supervisor:start_child(ejabberd_gen_mod_sup, ChildSpec)
|
supervisor:start_child(ejabberd_gen_mod_sup, ChildSpec)
|
||||||
end.
|
end.
|
||||||
@ -103,15 +110,6 @@ init([Host, Opts]) ->
|
|||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
mod_opt_type(auth_type) ->
|
|
||||||
fun (plain) -> plain;
|
|
||||||
(anonymous) -> anonymous
|
|
||||||
end;
|
|
||||||
mod_opt_type(recbuf) ->
|
|
||||||
fun (I) when is_integer(I), I > 0 -> I end;
|
|
||||||
mod_opt_type(shaper) -> fun acl:shaper_rules_validator/1;
|
|
||||||
mod_opt_type(sndbuf) ->
|
|
||||||
fun (I) when is_integer(I), I > 0 -> I end;
|
|
||||||
mod_opt_type(access) -> fun acl:access_rules_validator/1;
|
mod_opt_type(access) -> fun acl:access_rules_validator/1;
|
||||||
mod_opt_type(host) -> fun iolist_to_binary/1;
|
mod_opt_type(host) -> fun iolist_to_binary/1;
|
||||||
mod_opt_type(hostname) -> fun iolist_to_binary/1;
|
mod_opt_type(hostname) -> fun iolist_to_binary/1;
|
||||||
@ -130,7 +128,11 @@ mod_opt_type(max_connections) ->
|
|||||||
end;
|
end;
|
||||||
mod_opt_type(ram_db_type) ->
|
mod_opt_type(ram_db_type) ->
|
||||||
fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
|
||||||
mod_opt_type(_) ->
|
mod_opt_type(Opt) ->
|
||||||
[auth_type, recbuf, shaper, sndbuf,
|
case mod_proxy65_stream:listen_opt_type(Opt) of
|
||||||
access, host, hostname, ip, name, port,
|
Opts when is_list(Opts) ->
|
||||||
max_connections, ram_db_type].
|
[access, host, hostname, ip, name, port,
|
||||||
|
max_connections, ram_db_type] ++ Opts;
|
||||||
|
Fun ->
|
||||||
|
Fun
|
||||||
|
end.
|
||||||
|
@ -60,8 +60,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
|
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>),
|
MyHost = gen_mod:get_opt_host(Host, Opts, <<"proxy.@HOST@">>),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO,
|
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO,
|
||||||
?MODULE, process_disco_info, IQDisc),
|
?MODULE, process_disco_info, IQDisc),
|
||||||
@ -92,12 +91,8 @@ handle_call(_Request, _From, State) ->
|
|||||||
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
|
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
|
||||||
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"proxy.@HOST@">>),
|
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"proxy.@HOST@">>),
|
||||||
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"proxy.@HOST@">>),
|
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"proxy.@HOST@">>),
|
||||||
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts,
|
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, one_queue),
|
||||||
fun gen_iq_handler:check_type/1,
|
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, one_queue),
|
||||||
one_queue),
|
|
||||||
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts,
|
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue),
|
|
||||||
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) ->
|
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_INFO,
|
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_INFO,
|
||||||
?MODULE, process_disco_info, NewIQDisc),
|
?MODULE, process_disco_info, NewIQDisc),
|
||||||
@ -132,7 +127,7 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
|||||||
%%%------------------------
|
%%%------------------------
|
||||||
|
|
||||||
add_listener(Host, Opts) ->
|
add_listener(Host, Opts) ->
|
||||||
NewOpts = [Host | Opts],
|
NewOpts = [{server_host, Host} | Opts],
|
||||||
ejabberd_listener:add_listener(get_port_ip(Host),
|
ejabberd_listener:add_listener(get_port_ip(Host),
|
||||||
mod_proxy65_stream, NewOpts).
|
mod_proxy65_stream, NewOpts).
|
||||||
|
|
||||||
@ -150,7 +145,6 @@ process_disco_info(#iq{type = set, lang = Lang} = IQ) ->
|
|||||||
process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) ->
|
process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) ->
|
||||||
Host = ejabberd_router:host_of_route(To#jid.lserver),
|
Host = ejabberd_router:host_of_route(To#jid.lserver),
|
||||||
Name = gen_mod:get_module_opt(Host, mod_proxy65, name,
|
Name = gen_mod:get_module_opt(Host, mod_proxy65, name,
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"SOCKS5 Bytestreams">>),
|
<<"SOCKS5 Bytestreams">>),
|
||||||
Info = ejabberd_hooks:run_fold(disco_info, Host,
|
Info = ejabberd_hooks:run_fold(disco_info, Host,
|
||||||
[], [Host, ?MODULE, <<"">>, <<"">>]),
|
[], [Host, ?MODULE, <<"">>, <<"">>]),
|
||||||
@ -184,9 +178,7 @@ process_vcard(#iq{type = get, lang = Lang} = IQ) ->
|
|||||||
process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) ->
|
process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) ->
|
||||||
Host = To#jid.lserver,
|
Host = To#jid.lserver,
|
||||||
ServerHost = ejabberd_router:host_of_route(Host),
|
ServerHost = ejabberd_router:host_of_route(Host),
|
||||||
ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access,
|
ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, all),
|
||||||
fun acl:access_rules_validator/1,
|
|
||||||
all),
|
|
||||||
case acl:match_rule(ServerHost, ACL, JID) of
|
case acl:match_rule(ServerHost, ACL, JID) of
|
||||||
allow ->
|
allow ->
|
||||||
StreamHost = get_streamhost(Host, ServerHost),
|
StreamHost = get_streamhost(Host, ServerHost),
|
||||||
@ -209,9 +201,7 @@ process_bytestreams(#iq{type = set, lang = Lang, from = InitiatorJID, to = To,
|
|||||||
sub_els = [#bytestreams{activate = TargetJID,
|
sub_els = [#bytestreams{activate = TargetJID,
|
||||||
sid = SID}]} = IQ) ->
|
sid = SID}]} = IQ) ->
|
||||||
ServerHost = ejabberd_router:host_of_route(To#jid.lserver),
|
ServerHost = ejabberd_router:host_of_route(To#jid.lserver),
|
||||||
ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access,
|
ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, all),
|
||||||
fun acl:access_rules_validator/1,
|
|
||||||
all),
|
|
||||||
case acl:match_rule(ServerHost, ACL, InitiatorJID) of
|
case acl:match_rule(ServerHost, ACL, InitiatorJID) of
|
||||||
allow ->
|
allow ->
|
||||||
Node = ejabberd_cluster:get_node_by_id(To#jid.lresource),
|
Node = ejabberd_cluster:get_node_by_id(To#jid.lresource),
|
||||||
@ -264,7 +254,6 @@ transform_module_options(Opts) ->
|
|||||||
get_streamhost(Host, ServerHost) ->
|
get_streamhost(Host, ServerHost) ->
|
||||||
{Port, IP} = get_port_ip(ServerHost),
|
{Port, IP} = get_port_ip(ServerHost),
|
||||||
HostName = gen_mod:get_module_opt(ServerHost, mod_proxy65, hostname,
|
HostName = gen_mod:get_module_opt(ServerHost, mod_proxy65, hostname,
|
||||||
fun iolist_to_binary/1,
|
|
||||||
misc:ip_to_list(IP)),
|
misc:ip_to_list(IP)),
|
||||||
Resource = ejabberd_cluster:node_id(),
|
Resource = ejabberd_cluster:node_id(),
|
||||||
#streamhost{jid = jid:make(<<"">>, Host, Resource),
|
#streamhost{jid = jid:make(<<"">>, Host, Resource),
|
||||||
@ -273,18 +262,8 @@ get_streamhost(Host, ServerHost) ->
|
|||||||
|
|
||||||
-spec get_port_ip(binary()) -> {pos_integer(), inet:ip_address()}.
|
-spec get_port_ip(binary()) -> {pos_integer(), inet:ip_address()}.
|
||||||
get_port_ip(Host) ->
|
get_port_ip(Host) ->
|
||||||
Port = gen_mod:get_module_opt(Host, mod_proxy65, port,
|
Port = gen_mod:get_module_opt(Host, mod_proxy65, port, 7777),
|
||||||
fun(P) when is_integer(P), P>0, P<65536 ->
|
IP = gen_mod:get_module_opt(Host, mod_proxy65, ip, get_my_ip()),
|
||||||
P
|
|
||||||
end,
|
|
||||||
7777),
|
|
||||||
IP = gen_mod:get_module_opt(Host, mod_proxy65, ip,
|
|
||||||
fun(S) ->
|
|
||||||
{ok, Addr} = inet_parse:address(
|
|
||||||
binary_to_list(
|
|
||||||
iolist_to_binary(S))),
|
|
||||||
Addr
|
|
||||||
end, get_my_ip()),
|
|
||||||
{Port, IP}.
|
{Port, IP}.
|
||||||
|
|
||||||
-spec get_my_ip() -> inet:ip_address().
|
-spec get_my_ip() -> inet:ip_address().
|
||||||
@ -296,7 +275,4 @@ get_my_ip() ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
max_connections(ServerHost) ->
|
max_connections(ServerHost) ->
|
||||||
gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections,
|
gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections, infinity).
|
||||||
fun(I) when is_integer(I), I>0 -> I;
|
|
||||||
(infinity) -> infinity
|
|
||||||
end, infinity).
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
stream_established/2]).
|
stream_established/2]).
|
||||||
|
|
||||||
-export([start/2, stop/1, start_link/3, activate/2,
|
-export([start/2, stop/1, start_link/3, activate/2,
|
||||||
relay/3, socket_type/0]).
|
relay/3, socket_type/0, listen_opt_type/1]).
|
||||||
|
|
||||||
-include("mod_proxy65.hrl").
|
-include("mod_proxy65.hrl").
|
||||||
|
|
||||||
@ -65,9 +65,10 @@ code_change(_OldVsn, StateName, StateData, _Extra) ->
|
|||||||
%%-------------------------------
|
%%-------------------------------
|
||||||
|
|
||||||
start({gen_tcp, Socket}, Opts1) ->
|
start({gen_tcp, Socket}, Opts1) ->
|
||||||
{[Host], Opts} = lists:partition(fun (O) -> is_binary(O)
|
{[{server_host, Host}], Opts} = lists:partition(
|
||||||
end,
|
fun({server_host, _}) -> true;
|
||||||
Opts1),
|
(_) -> false
|
||||||
|
end, Opts1),
|
||||||
Supervisor = gen_mod:get_module_proc(Host,
|
Supervisor = gen_mod:get_module_proc(Host,
|
||||||
ejabberd_mod_proxy65_sup),
|
ejabberd_mod_proxy65_sup),
|
||||||
supervisor:start_child(Supervisor,
|
supervisor:start_child(Supervisor,
|
||||||
@ -78,19 +79,10 @@ start_link(Socket, Host, Opts) ->
|
|||||||
|
|
||||||
init([Socket, Host, Opts]) ->
|
init([Socket, Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
AuthType = gen_mod:get_opt(auth_type, Opts,
|
AuthType = gen_mod:get_opt(auth_type, Opts, anonymous),
|
||||||
fun(plain) -> plain;
|
Shaper = gen_mod:get_opt(shaper, Opts, none),
|
||||||
(anonymous) -> anonymous
|
RecvBuf = gen_mod:get_opt(recbuf, Opts, 8192),
|
||||||
end, anonymous),
|
SendBuf = gen_mod:get_opt(sndbuf, Opts, 8192),
|
||||||
Shaper = gen_mod:get_opt(shaper, Opts,
|
|
||||||
fun acl:shaper_rules_validator/1,
|
|
||||||
none),
|
|
||||||
RecvBuf = gen_mod:get_opt(recbuf, Opts,
|
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
8192),
|
|
||||||
SendBuf = gen_mod:get_opt(sndbuf, Opts,
|
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
8192),
|
|
||||||
TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop),
|
TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop),
|
||||||
inet:setopts(Socket,
|
inet:setopts(Socket,
|
||||||
[{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]),
|
[{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]),
|
||||||
@ -290,3 +282,17 @@ find_maxrate(Shaper, JID1, JID2, Host) ->
|
|||||||
if MaxRate1 == none; MaxRate2 == none -> none;
|
if MaxRate1 == none; MaxRate2 == none -> none;
|
||||||
true -> lists:max([MaxRate1, MaxRate2])
|
true -> lists:max([MaxRate1, MaxRate2])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
listen_opt_type(server_host) ->
|
||||||
|
fun iolist_to_binary/1;
|
||||||
|
listen_opt_type(auth_type) ->
|
||||||
|
fun (plain) -> plain;
|
||||||
|
(anonymous) -> anonymous
|
||||||
|
end;
|
||||||
|
listen_opt_type(recbuf) ->
|
||||||
|
fun (I) when is_integer(I), I > 0 -> I end;
|
||||||
|
listen_opt_type(shaper) -> fun acl:shaper_rules_validator/1;
|
||||||
|
listen_opt_type(sndbuf) ->
|
||||||
|
fun (I) when is_integer(I), I > 0 -> I end;
|
||||||
|
listen_opt_type(_) ->
|
||||||
|
[auth_type, recbuf, sndbuf, shaper].
|
||||||
|
@ -244,18 +244,12 @@ init([ServerHost, Opts]) ->
|
|||||||
?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]),
|
?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]),
|
||||||
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
|
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
|
||||||
ejabberd_router:register_route(Host, ServerHost),
|
ejabberd_router:register_route(Host, ServerHost),
|
||||||
Access = gen_mod:get_opt(access_createnode, Opts,
|
Access = gen_mod:get_opt(access_createnode, Opts, all),
|
||||||
fun acl:access_rules_validator/1, all),
|
PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true),
|
||||||
PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
fun(A) when is_boolean(A) -> A end, true),
|
LastItemCache = gen_mod:get_opt(last_item_cache, Opts, false),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts,
|
MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS),
|
||||||
fun gen_iq_handler:check_type/1, one_queue),
|
MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts),
|
||||||
LastItemCache = gen_mod:get_opt(last_item_cache, Opts,
|
|
||||||
fun(A) when is_boolean(A) -> A end, false),
|
|
||||||
MaxItemsNode = gen_mod:get_opt(max_items_node, Opts,
|
|
||||||
fun(A) when is_integer(A) andalso A >= 0 -> A end, ?MAXITEMS),
|
|
||||||
MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts,
|
|
||||||
fun(A) when is_integer(A) andalso A >= 0 -> A end, undefined),
|
|
||||||
case gen_mod:db_type(ServerHost, ?MODULE) of
|
case gen_mod:db_type(ServerHost, ?MODULE) of
|
||||||
mnesia -> pubsub_index:init(Host, ServerHost, Opts);
|
mnesia -> pubsub_index:init(Host, ServerHost, Opts);
|
||||||
_ -> ok
|
_ -> ok
|
||||||
@ -263,8 +257,9 @@ init([ServerHost, Opts]) ->
|
|||||||
{Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
|
{Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
|
||||||
DefaultModule = plugin(Host, hd(Plugins)),
|
DefaultModule = plugin(Host, hd(Plugins)),
|
||||||
BaseOptions = DefaultModule:options(),
|
BaseOptions = DefaultModule:options(),
|
||||||
DefaultNodeCfg = gen_mod:get_opt(default_node_config, Opts,
|
DefaultNodeCfg = filter_node_options(
|
||||||
fun(A) when is_list(A) -> filter_node_options(A, BaseOptions) end, []),
|
gen_mod:get_opt(default_node_config, Opts, []),
|
||||||
|
BaseOptions),
|
||||||
ejabberd_mnesia:create(?MODULE, pubsub_last_item,
|
ejabberd_mnesia:create(?MODULE, pubsub_last_item,
|
||||||
[{ram_copies, [node()]},
|
[{ram_copies, [node()]},
|
||||||
{attributes, record_info(fields, pubsub_last_item)}]),
|
{attributes, record_info(fields, pubsub_last_item)}]),
|
||||||
@ -364,8 +359,7 @@ init_send_loop(ServerHost) ->
|
|||||||
|
|
||||||
depends(ServerHost, Opts) ->
|
depends(ServerHost, Opts) ->
|
||||||
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
|
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
|
||||||
Plugins = gen_mod:get_opt(plugins, Opts,
|
Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]),
|
||||||
fun(A) when is_list(A) -> A end, [?STDNODE]),
|
|
||||||
lists:flatmap(
|
lists:flatmap(
|
||||||
fun(Name) ->
|
fun(Name) ->
|
||||||
Plugin = plugin(ServerHost, Name),
|
Plugin = plugin(ServerHost, Name),
|
||||||
@ -380,15 +374,11 @@ depends(ServerHost, Opts) ->
|
|||||||
%% <em>node_plugin</em>. The 'node_' prefix is mandatory.</p>
|
%% <em>node_plugin</em>. The 'node_' prefix is mandatory.</p>
|
||||||
%% <p>See {@link node_hometree:init/1} for an example implementation.</p>
|
%% <p>See {@link node_hometree:init/1} for an example implementation.</p>
|
||||||
init_plugins(Host, ServerHost, Opts) ->
|
init_plugins(Host, ServerHost, Opts) ->
|
||||||
TreePlugin = tree(Host, gen_mod:get_opt(nodetree, Opts,
|
TreePlugin = tree(Host, gen_mod:get_opt(nodetree, Opts, ?STDTREE)),
|
||||||
fun(A) when is_binary(A) -> A end,
|
|
||||||
?STDTREE)),
|
|
||||||
?DEBUG("** tree plugin is ~p", [TreePlugin]),
|
?DEBUG("** tree plugin is ~p", [TreePlugin]),
|
||||||
TreePlugin:init(Host, ServerHost, Opts),
|
TreePlugin:init(Host, ServerHost, Opts),
|
||||||
Plugins = gen_mod:get_opt(plugins, Opts,
|
Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]),
|
||||||
fun(A) when is_list(A) -> A end, [?STDNODE]),
|
PepMapping = gen_mod:get_opt(pep_mapping, Opts, []),
|
||||||
PepMapping = gen_mod:get_opt(pep_mapping, Opts,
|
|
||||||
fun(A) when is_list(A) -> A end, []),
|
|
||||||
?DEBUG("** PEP Mapping : ~p~n", [PepMapping]),
|
?DEBUG("** PEP Mapping : ~p~n", [PepMapping]),
|
||||||
PluginsOK = lists:foldl(
|
PluginsOK = lists:foldl(
|
||||||
fun (Name, Acc) ->
|
fun (Name, Acc) ->
|
||||||
|
@ -44,8 +44,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_REGISTER, ?MODULE, process_iq, IQDisc),
|
?NS_REGISTER, ?MODULE, process_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
||||||
@ -70,9 +69,7 @@ stop(Host) ->
|
|||||||
?NS_REGISTER).
|
?NS_REGISTER).
|
||||||
|
|
||||||
reload(Host, NewOpts, OldOpts) ->
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER,
|
||||||
?MODULE, process_iq, IQDisc),
|
?MODULE, process_iq, IQDisc),
|
||||||
@ -87,9 +84,7 @@ depends(_Host, _Opts) ->
|
|||||||
|
|
||||||
-spec stream_feature_register([xmpp_element()], binary()) -> [xmpp_element()].
|
-spec stream_feature_register([xmpp_element()], binary()) -> [xmpp_element()].
|
||||||
stream_feature_register(Acc, Host) ->
|
stream_feature_register(Acc, Host) ->
|
||||||
AF = gen_mod:get_module_opt(Host, ?MODULE, access_from,
|
AF = gen_mod:get_module_opt(Host, ?MODULE, access_from, all),
|
||||||
fun(A) -> A end,
|
|
||||||
all),
|
|
||||||
case (AF /= none) of
|
case (AF /= none) of
|
||||||
true ->
|
true ->
|
||||||
[#feature_register{}|Acc];
|
[#feature_register{}|Acc];
|
||||||
@ -120,15 +115,12 @@ process_iq(#iq{from = From} = IQ) ->
|
|||||||
process_iq(#iq{from = From, to = To} = IQ, Source) ->
|
process_iq(#iq{from = From, to = To} = IQ, Source) ->
|
||||||
IsCaptchaEnabled =
|
IsCaptchaEnabled =
|
||||||
case gen_mod:get_module_opt(To#jid.lserver, ?MODULE,
|
case gen_mod:get_module_opt(To#jid.lserver, ?MODULE,
|
||||||
captcha_protected,
|
captcha_protected, false) of
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false) of
|
|
||||||
true -> true;
|
true -> true;
|
||||||
false -> false
|
false -> false
|
||||||
end,
|
end,
|
||||||
Server = To#jid.lserver,
|
Server = To#jid.lserver,
|
||||||
Access = gen_mod:get_module_opt(Server, ?MODULE, access,
|
Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
|
||||||
fun(A) -> A end, all),
|
|
||||||
AllowRemove = allow == acl:match_rule(Server, Access, From),
|
AllowRemove = allow == acl:match_rule(Server, Access, From),
|
||||||
process_iq(IQ, Source, IsCaptchaEnabled, AllowRemove).
|
process_iq(IQ, Source, IsCaptchaEnabled, AllowRemove).
|
||||||
|
|
||||||
@ -315,9 +307,7 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
|
|||||||
false -> {error, xmpp:err_bad_request(<<"Malformed username">>, Lang)};
|
false -> {error, xmpp:err_bad_request(<<"Malformed username">>, Lang)};
|
||||||
_ ->
|
_ ->
|
||||||
JID = jid:make(User, Server),
|
JID = jid:make(User, Server),
|
||||||
Access = gen_mod:get_module_opt(Server, ?MODULE, access,
|
Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
|
||||||
fun(A) -> A end,
|
|
||||||
all),
|
|
||||||
IPAccess = get_ip_access(Server),
|
IPAccess = get_ip_access(Server),
|
||||||
case {acl:match_rule(Server, Access, JID),
|
case {acl:match_rule(Server, Access, JID),
|
||||||
check_ip_access(SourceRaw, IPAccess)}
|
check_ip_access(SourceRaw, IPAccess)}
|
||||||
@ -379,15 +369,7 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
|
|||||||
send_welcome_message(JID) ->
|
send_welcome_message(JID) ->
|
||||||
Host = JID#jid.lserver,
|
Host = JID#jid.lserver,
|
||||||
case gen_mod:get_module_opt(Host, ?MODULE, welcome_message,
|
case gen_mod:get_module_opt(Host, ?MODULE, welcome_message,
|
||||||
fun(Opts) ->
|
{<<"">>, <<"">>}) of
|
||||||
S = proplists:get_value(
|
|
||||||
subject, Opts, <<>>),
|
|
||||||
B = proplists:get_value(
|
|
||||||
body, Opts, <<>>),
|
|
||||||
{iolist_to_binary(S),
|
|
||||||
iolist_to_binary(B)}
|
|
||||||
end, {<<"">>, <<"">>})
|
|
||||||
of
|
|
||||||
{<<"">>, <<"">>} -> ok;
|
{<<"">>, <<"">>} -> ok;
|
||||||
{Subj, Body} ->
|
{Subj, Body} ->
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
@ -400,11 +382,7 @@ send_welcome_message(JID) ->
|
|||||||
|
|
||||||
send_registration_notifications(Mod, UJID, Source) ->
|
send_registration_notifications(Mod, UJID, Source) ->
|
||||||
Host = UJID#jid.lserver,
|
Host = UJID#jid.lserver,
|
||||||
case gen_mod:get_module_opt(
|
case gen_mod:get_module_opt(Host, Mod, registration_watchers, []) of
|
||||||
Host, Mod, registration_watchers,
|
|
||||||
fun(Ss) ->
|
|
||||||
[jid:decode(iolist_to_binary(S)) || S <- Ss]
|
|
||||||
end, []) of
|
|
||||||
[] -> ok;
|
[] -> ok;
|
||||||
JIDs when is_list(JIDs) ->
|
JIDs when is_list(JIDs) ->
|
||||||
Body =
|
Body =
|
||||||
@ -428,9 +406,7 @@ check_from(#jid{user = <<"">>, server = <<"">>},
|
|||||||
_Server) ->
|
_Server) ->
|
||||||
allow;
|
allow;
|
||||||
check_from(JID, Server) ->
|
check_from(JID, Server) ->
|
||||||
Access = gen_mod:get_module_opt(Server, ?MODULE, access_from,
|
Access = gen_mod:get_module_opt(Server, ?MODULE, access_from, none),
|
||||||
fun(A) -> A end,
|
|
||||||
none),
|
|
||||||
acl:match_rule(Server, Access, JID).
|
acl:match_rule(Server, Access, JID).
|
||||||
|
|
||||||
check_timeout(undefined) -> true;
|
check_timeout(undefined) -> true;
|
||||||
@ -532,9 +508,7 @@ is_strong_password(Server, Password) ->
|
|||||||
|
|
||||||
is_strong_password2(Server, Password) ->
|
is_strong_password2(Server, Password) ->
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
case gen_mod:get_module_opt(LServer, ?MODULE, password_strength,
|
case gen_mod:get_module_opt(LServer, ?MODULE, password_strength, 0) of
|
||||||
fun(N) when is_number(N), N>=0 -> N end,
|
|
||||||
0) of
|
|
||||||
0 ->
|
0 ->
|
||||||
true;
|
true;
|
||||||
Entropy ->
|
Entropy ->
|
||||||
@ -598,9 +572,7 @@ may_remove_resource({_, _, _} = From) ->
|
|||||||
may_remove_resource(From) -> From.
|
may_remove_resource(From) -> From.
|
||||||
|
|
||||||
get_ip_access(Host) ->
|
get_ip_access(Host) ->
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, ip_access,
|
gen_mod:get_module_opt(Host, ?MODULE, ip_access, all).
|
||||||
fun(A) when is_atom(A) -> A end,
|
|
||||||
all).
|
|
||||||
|
|
||||||
check_ip_access({User, Server, Resource}, IPAccess) ->
|
check_ip_access({User, Server, Resource}, IPAccess) ->
|
||||||
case ejabberd_sm:get_user_ip(User, Server, Resource) of
|
case ejabberd_sm:get_user_ip(User, Server, Resource) of
|
||||||
|
@ -496,9 +496,7 @@ form_del_get(Host, Lang) ->
|
|||||||
%% {error, not_allowed} |
|
%% {error, not_allowed} |
|
||||||
%% {error, invalid_jid}
|
%% {error, invalid_jid}
|
||||||
register_account(Username, Host, Password) ->
|
register_account(Username, Host, Password) ->
|
||||||
Access = gen_mod:get_module_opt(Host, mod_register, access,
|
Access = gen_mod:get_module_opt(Host, mod_register, access, all),
|
||||||
fun(A) -> A end,
|
|
||||||
all),
|
|
||||||
case jid:make(Username, Host) of
|
case jid:make(Username, Host) of
|
||||||
error -> {error, invalid_jid};
|
error -> {error, invalid_jid};
|
||||||
JID ->
|
JID ->
|
||||||
|
@ -84,8 +84,7 @@
|
|||||||
{subscription(), [binary()]}.
|
{subscription(), [binary()]}.
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
ejabberd_hooks:add(roster_get, Host, ?MODULE,
|
ejabberd_hooks:add(roster_get, Host, ?MODULE,
|
||||||
@ -147,9 +146,7 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
true ->
|
true ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
|
||||||
?MODULE, process_iq, IQDisc);
|
?MODULE, process_iq, IQDisc);
|
||||||
@ -188,8 +185,7 @@ process_local_iq(#iq{type = set, from = From, lang = Lang,
|
|||||||
xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
|
xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang));
|
||||||
false ->
|
false ->
|
||||||
#jid{server = Server} = From,
|
#jid{server = Server} = From,
|
||||||
Access = gen_mod:get_module_opt(Server, ?MODULE,
|
Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
|
||||||
access, fun(A) -> A end, all),
|
|
||||||
case acl:match_rule(Server, Access, From) of
|
case acl:match_rule(Server, Access, From) of
|
||||||
deny ->
|
deny ->
|
||||||
Txt = <<"Denied by ACL">>,
|
Txt = <<"Denied by ACL">>,
|
||||||
@ -222,14 +218,10 @@ roster_hash(Items) ->
|
|||||||
<- Items]))).
|
<- Items]))).
|
||||||
|
|
||||||
roster_versioning_enabled(Host) ->
|
roster_versioning_enabled(Host) ->
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, versioning,
|
gen_mod:get_module_opt(Host, ?MODULE, versioning, false).
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false).
|
|
||||||
|
|
||||||
roster_version_on_db(Host) ->
|
roster_version_on_db(Host) ->
|
||||||
gen_mod:get_module_opt(Host, ?MODULE, store_current_id,
|
gen_mod:get_module_opt(Host, ?MODULE, store_current_id, false).
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false).
|
|
||||||
|
|
||||||
%% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled.
|
%% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled.
|
||||||
-spec get_versioning_feature([xmpp_element()], binary()) -> [xmpp_element()].
|
-spec get_versioning_feature([xmpp_element()], binary()) -> [xmpp_element()].
|
||||||
|
@ -68,8 +68,7 @@ log_user_receive({Packet, C2SState}) ->
|
|||||||
|
|
||||||
-spec log_packet(stanza(), binary()) -> ok.
|
-spec log_packet(stanza(), binary()) -> ok.
|
||||||
log_packet(Packet, Host) ->
|
log_packet(Packet, Host) ->
|
||||||
Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers,
|
Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []),
|
||||||
mod_opt_type(loggers), []),
|
|
||||||
ForwardedMsg = #message{from = jid:make(Host),
|
ForwardedMsg = #message{from = jid:make(Host),
|
||||||
id = randoms:get_string(),
|
id = randoms:get_string(),
|
||||||
sub_els = [#forwarded{
|
sub_els = [#forwarded{
|
||||||
|
@ -468,44 +468,18 @@ get_user_part_re(String, Pattern) ->
|
|||||||
parse_options(Host, Opts) ->
|
parse_options(Host, Opts) ->
|
||||||
Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?MODULE)),
|
Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?MODULE)),
|
||||||
Cfg = eldap_utils:get_config(Host, Opts),
|
Cfg = eldap_utils:get_config(Host, Opts),
|
||||||
GroupAttr = gen_mod:get_opt(ldap_groupattr, Opts,
|
GroupAttr = gen_mod:get_opt(ldap_groupattr, Opts, <<"cn">>),
|
||||||
fun iolist_to_binary/1,
|
GroupDesc = gen_mod:get_opt(ldap_groupdesc, Opts, GroupAttr),
|
||||||
<<"cn">>),
|
UserDesc = gen_mod:get_opt(ldap_userdesc, Opts, <<"cn">>),
|
||||||
GroupDesc = gen_mod:get_opt(ldap_groupdesc, Opts,
|
UserUID = gen_mod:get_opt(ldap_useruid, Opts, <<"cn">>),
|
||||||
fun iolist_to_binary/1,
|
UIDAttr = gen_mod:get_opt(ldap_memberattr, Opts, <<"memberUid">>),
|
||||||
GroupAttr),
|
UIDAttrFormat = gen_mod:get_opt(ldap_memberattr_format, Opts, <<"%u">>),
|
||||||
UserDesc = gen_mod:get_opt(ldap_userdesc, Opts,
|
UIDAttrFormatRe = gen_mod:get_opt(ldap_memberattr_format_re, Opts, <<"">>),
|
||||||
fun iolist_to_binary/1,
|
AuthCheck = gen_mod:get_opt(ldap_auth_check, Opts, true),
|
||||||
<<"cn">>),
|
ConfigFilter = gen_mod:get_opt({ldap_filter, Host}, Opts, <<"">>),
|
||||||
UserUID = gen_mod:get_opt(ldap_useruid, Opts,
|
ConfigUserFilter = gen_mod:get_opt({ldap_ufilter, Host}, Opts, <<"">>),
|
||||||
fun iolist_to_binary/1,
|
ConfigGroupFilter = gen_mod:get_opt({ldap_gfilter, Host}, Opts, <<"">>),
|
||||||
<<"cn">>),
|
RosterFilter = gen_mod:get_opt({ldap_rfilter, Host}, Opts, <<"">>),
|
||||||
UIDAttr = gen_mod:get_opt(ldap_memberattr, Opts,
|
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"memberUid">>),
|
|
||||||
UIDAttrFormat = gen_mod:get_opt(ldap_memberattr_format, Opts,
|
|
||||||
fun iolist_to_binary/1,
|
|
||||||
<<"%u">>),
|
|
||||||
UIDAttrFormatRe = gen_mod:get_opt(ldap_memberattr_format_re, Opts,
|
|
||||||
fun(S) ->
|
|
||||||
Re = iolist_to_binary(S),
|
|
||||||
{ok, MP} = re:compile(Re),
|
|
||||||
MP
|
|
||||||
end, <<"">>),
|
|
||||||
AuthCheck = gen_mod:get_opt(ldap_auth_check, Opts,
|
|
||||||
fun(on) -> true;
|
|
||||||
(off) -> false;
|
|
||||||
(false) -> false;
|
|
||||||
(true) -> true
|
|
||||||
end, true),
|
|
||||||
ConfigFilter = gen_mod:get_opt({ldap_filter, Host}, Opts,
|
|
||||||
fun eldap_utils:check_filter/1, <<"">>),
|
|
||||||
ConfigUserFilter = gen_mod:get_opt({ldap_ufilter, Host}, Opts,
|
|
||||||
fun eldap_utils:check_filter/1, <<"">>),
|
|
||||||
ConfigGroupFilter = gen_mod:get_opt({ldap_gfilter, Host}, Opts,
|
|
||||||
fun eldap_utils:check_filter/1, <<"">>),
|
|
||||||
RosterFilter = gen_mod:get_opt({ldap_rfilter, Host}, Opts,
|
|
||||||
fun eldap_utils:check_filter/1, <<"">>),
|
|
||||||
SubFilter = <<"(&(", UIDAttr/binary, "=",
|
SubFilter = <<"(&(", UIDAttr/binary, "=",
|
||||||
UIDAttrFormat/binary, ")(", GroupAttr/binary, "=%g))">>,
|
UIDAttrFormat/binary, ")(", GroupAttr/binary, "=%g))">>,
|
||||||
UserSubFilter = case ConfigUserFilter of
|
UserSubFilter = case ConfigUserFilter of
|
||||||
@ -566,18 +540,14 @@ init_cache(Host, Opts) ->
|
|||||||
UseCache.
|
UseCache.
|
||||||
|
|
||||||
use_cache(Host, Opts) ->
|
use_cache(Host, Opts) ->
|
||||||
gen_mod:get_opt(use_cache, Opts, mod_opt_type(use_cache),
|
gen_mod:get_opt(use_cache, Opts, ejabberd_config:use_cache(Host)).
|
||||||
ejabberd_config:use_cache(Host)).
|
|
||||||
|
|
||||||
cache_opts(Host, Opts) ->
|
cache_opts(Host, Opts) ->
|
||||||
MaxSize = gen_mod:get_opt(cache_size, Opts,
|
MaxSize = gen_mod:get_opt(cache_size, Opts,
|
||||||
mod_opt_type(cache_size),
|
|
||||||
ejabberd_config:cache_size(Host)),
|
ejabberd_config:cache_size(Host)),
|
||||||
CacheMissed = gen_mod:get_opt(cache_missed, Opts,
|
CacheMissed = gen_mod:get_opt(cache_missed, Opts,
|
||||||
mod_opt_type(cache_missed),
|
|
||||||
ejabberd_config:cache_missed(Host)),
|
ejabberd_config:cache_missed(Host)),
|
||||||
LifeTime = case gen_mod:get_opt(cache_life_time, Opts,
|
LifeTime = case gen_mod:get_opt(cache_life_time, Opts,
|
||||||
mod_opt_type(cache_life_time),
|
|
||||||
ejabberd_config:cache_life_time(Host)) of
|
ejabberd_config:cache_life_time(Host)) of
|
||||||
infinity -> infinity;
|
infinity -> infinity;
|
||||||
I -> timer:seconds(I)
|
I -> timer:seconds(I)
|
||||||
|
@ -39,8 +39,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_0,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_0,
|
||||||
@ -57,9 +56,7 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC_1).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC_1).
|
||||||
|
|
||||||
reload(Host, NewOpts, OldOpts) ->
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
|
@ -313,11 +313,7 @@ is_request_within_dialog(#sip{hdrs = Hdrs}) ->
|
|||||||
esip:has_param(<<"tag">>, Params).
|
esip:has_param(<<"tag">>, Params).
|
||||||
|
|
||||||
need_record_route(LServer) ->
|
need_record_route(LServer) ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(LServer, mod_sip, always_record_route, true).
|
||||||
LServer, mod_sip, always_record_route,
|
|
||||||
fun(true) -> true;
|
|
||||||
(false) -> false
|
|
||||||
end, true).
|
|
||||||
|
|
||||||
make_sign(TS, Hdrs) ->
|
make_sign(TS, Hdrs) ->
|
||||||
{_, #uri{user = FUser, host = FServer}, FParams} = esip:get_hdr('from', Hdrs),
|
{_, #uri{user = FUser, host = FServer}, FParams} = esip:get_hdr('from', Hdrs),
|
||||||
@ -344,41 +340,17 @@ is_signed_by_me(TS_Sign, Hdrs) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
get_configured_vias(LServer) ->
|
get_configured_vias(LServer) ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(LServer, mod_sip, via, []).
|
||||||
LServer, mod_sip, via,
|
|
||||||
fun(L) ->
|
|
||||||
lists:map(
|
|
||||||
fun(Opts) ->
|
|
||||||
Type = proplists:get_value(type, Opts),
|
|
||||||
Host = proplists:get_value(host, Opts),
|
|
||||||
Port = proplists:get_value(port, Opts),
|
|
||||||
true = (Type == tcp) or (Type == tls) or (Type == udp),
|
|
||||||
true = is_binary(Host) and (Host /= <<"">>),
|
|
||||||
true = (is_integer(Port)
|
|
||||||
and (Port > 0) and (Port < 65536))
|
|
||||||
or (Port == undefined),
|
|
||||||
{Type, {Host, Port}}
|
|
||||||
end, L)
|
|
||||||
end, []).
|
|
||||||
|
|
||||||
get_configured_record_route(LServer) ->
|
get_configured_record_route(LServer) ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(
|
||||||
LServer, mod_sip, record_route,
|
LServer, mod_sip, record_route,
|
||||||
fun(IOList) ->
|
#uri{host = LServer, params = [{<<"lr">>, <<"">>}]}).
|
||||||
S = iolist_to_binary(IOList),
|
|
||||||
#uri{} = esip:decode_uri(S)
|
|
||||||
end, #uri{host = LServer, params = [{<<"lr">>, <<"">>}]}).
|
|
||||||
|
|
||||||
get_configured_routes(LServer) ->
|
get_configured_routes(LServer) ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(
|
||||||
LServer, mod_sip, routes,
|
LServer, mod_sip, routes,
|
||||||
fun(L) ->
|
[#uri{host = LServer, params = [{<<"lr">>, <<"">>}]}]).
|
||||||
lists:map(
|
|
||||||
fun(IOList) ->
|
|
||||||
S = iolist_to_binary(IOList),
|
|
||||||
#uri{} = esip:decode_uri(S)
|
|
||||||
end, L)
|
|
||||||
end, [#uri{host = LServer, params = [{<<"lr">>, <<"">>}]}]).
|
|
||||||
|
|
||||||
mark_transaction_as_complete(TrID, State) ->
|
mark_transaction_as_complete(TrID, State) ->
|
||||||
NewTrIDs = lists:delete(TrID, State#state.tr_ids),
|
NewTrIDs = lists:delete(TrID, State#state.tr_ids),
|
||||||
|
@ -494,12 +494,10 @@ get_flow_timeout(LServer, #sip_socket{type = Type}) ->
|
|||||||
udp ->
|
udp ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(
|
||||||
LServer, mod_sip, flow_timeout_udp,
|
LServer, mod_sip, flow_timeout_udp,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
?FLOW_TIMEOUT_UDP);
|
?FLOW_TIMEOUT_UDP);
|
||||||
_ ->
|
_ ->
|
||||||
gen_mod:get_module_opt(
|
gen_mod:get_module_opt(
|
||||||
LServer, mod_sip, flow_timeout_tcp,
|
LServer, mod_sip, flow_timeout_tcp,
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
?FLOW_TIMEOUT_TCP)
|
?FLOW_TIMEOUT_TCP)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
|
||||||
?MODULE, process_iq, IQDisc).
|
?MODULE, process_iq, IQDisc).
|
||||||
|
|
||||||
|
@ -673,58 +673,36 @@ bounce_message_queue() ->
|
|||||||
%%% Configuration processing
|
%%% Configuration processing
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
get_max_ack_queue(Host, Opts) ->
|
get_max_ack_queue(Host, Opts) ->
|
||||||
VFun = mod_opt_type(max_ack_queue),
|
gen_mod:get_module_opt(Host, ?MODULE, max_ack_queue,
|
||||||
case gen_mod:get_module_opt(Host, ?MODULE, max_ack_queue, VFun) of
|
gen_mod:get_opt(max_ack_queue, Opts, 1000)).
|
||||||
undefined -> gen_mod:get_opt(max_ack_queue, Opts, VFun, 1000);
|
|
||||||
Limit -> Limit
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_resume_timeout(Host, Opts) ->
|
get_resume_timeout(Host, Opts) ->
|
||||||
VFun = mod_opt_type(resume_timeout),
|
gen_mod:get_module_opt(Host, ?MODULE, resume_timeout,
|
||||||
case gen_mod:get_module_opt(Host, ?MODULE, resume_timeout, VFun) of
|
gen_mod:get_opt(resume_timeout, Opts, 300)).
|
||||||
undefined -> gen_mod:get_opt(resume_timeout, Opts, VFun, 300);
|
|
||||||
Timeout -> Timeout
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_max_resume_timeout(Host, Opts, ResumeTimeout) ->
|
get_max_resume_timeout(Host, Opts, ResumeTimeout) ->
|
||||||
VFun = mod_opt_type(max_resume_timeout),
|
case gen_mod:get_module_opt(Host, ?MODULE, max_resume_timeout,
|
||||||
case gen_mod:get_module_opt(Host, ?MODULE, max_resume_timeout, VFun) of
|
gen_mod:get_opt(max_resume_timeout, Opts)) of
|
||||||
undefined ->
|
undefined -> ResumeTimeout;
|
||||||
case gen_mod:get_opt(max_resume_timeout, Opts, VFun) of
|
|
||||||
undefined -> ResumeTimeout;
|
|
||||||
Max when Max >= ResumeTimeout -> Max;
|
|
||||||
_ -> ResumeTimeout
|
|
||||||
end;
|
|
||||||
Max when Max >= ResumeTimeout -> Max;
|
Max when Max >= ResumeTimeout -> Max;
|
||||||
_ -> ResumeTimeout
|
_ -> ResumeTimeout
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_ack_timeout(Host, Opts) ->
|
get_ack_timeout(Host, Opts) ->
|
||||||
VFun = mod_opt_type(ack_timeout),
|
case gen_mod:get_module_opt(Host, ?MODULE, ack_timeout,
|
||||||
T = case gen_mod:get_module_opt(Host, ?MODULE, ack_timeout, VFun) of
|
gen_mod:get_opt(ack_timeout, Opts, 60)) of
|
||||||
undefined -> gen_mod:get_opt(ack_timeout, Opts, VFun, 60);
|
|
||||||
AckTimeout -> AckTimeout
|
|
||||||
end,
|
|
||||||
case T of
|
|
||||||
infinity -> infinity;
|
infinity -> infinity;
|
||||||
_ -> timer:seconds(T)
|
T -> timer:seconds(T)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_resend_on_timeout(Host, Opts) ->
|
get_resend_on_timeout(Host, Opts) ->
|
||||||
VFun = mod_opt_type(resend_on_timeout),
|
gen_mod:get_module_opt(Host, ?MODULE, resend_on_timeout,
|
||||||
case gen_mod:get_module_opt(Host, ?MODULE, resend_on_timeout, VFun) of
|
gen_mod:get_opt(resend_on_timeout, Opts, false)).
|
||||||
undefined -> gen_mod:get_opt(resend_on_timeout, Opts, VFun, false);
|
|
||||||
Resend -> Resend
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_queue_type(Host, Opts) ->
|
get_queue_type(Host, Opts) ->
|
||||||
VFun = mod_opt_type(queue_type),
|
case gen_mod:get_module_opt(Host, ?MODULE, queue_type,
|
||||||
case gen_mod:get_module_opt(Host, ?MODULE, queue_type, VFun) of
|
gen_mod:get_opt(queue_type, Opts)) of
|
||||||
undefined ->
|
undefined -> ejabberd_config:default_queue_type(Host);
|
||||||
case gen_mod:get_opt(queue_type, Opts, VFun) of
|
|
||||||
undefined -> ejabberd_config:default_queue_type(Host);
|
|
||||||
Type -> Type
|
|
||||||
end;
|
|
||||||
Type -> Type
|
Type -> Type
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -744,6 +722,8 @@ mod_opt_type(resend_on_timeout) ->
|
|||||||
fun(B) when is_boolean(B) -> B;
|
fun(B) when is_boolean(B) -> B;
|
||||||
(if_offline) -> if_offline
|
(if_offline) -> if_offline
|
||||||
end;
|
end;
|
||||||
|
mod_opt_type(stream_management) ->
|
||||||
|
fun(B) when is_boolean(B) -> B end;
|
||||||
mod_opt_type(queue_type) ->
|
mod_opt_type(queue_type) ->
|
||||||
fun(ram) -> ram; (file) -> file end;
|
fun(ram) -> ram; (file) -> file end;
|
||||||
mod_opt_type(_) ->
|
mod_opt_type(_) ->
|
||||||
|
@ -41,8 +41,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_TIME, ?MODULE, process_local_iq, IQDisc).
|
?NS_TIME, ?MODULE, process_local_iq, IQDisc).
|
||||||
|
|
||||||
@ -51,9 +50,7 @@ stop(Host) ->
|
|||||||
?NS_TIME).
|
?NS_TIME).
|
||||||
|
|
||||||
reload(Host, NewOpts, OldOpts) ->
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME,
|
||||||
?MODULE, process_local_iq, IQDisc);
|
?MODULE, process_local_iq, IQDisc);
|
||||||
|
@ -82,8 +82,7 @@ init([Host, Opts]) ->
|
|||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
ejabberd_hooks:add(remove_user, Host, ?MODULE,
|
ejabberd_hooks:add(remove_user, Host, ?MODULE,
|
||||||
remove_user, 50),
|
remove_user, 50),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_VCARD, ?MODULE, process_local_iq, IQDisc),
|
?NS_VCARD, ?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
||||||
@ -91,9 +90,7 @@ init([Host, Opts]) ->
|
|||||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
|
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE,
|
||||||
get_sm_features, 50),
|
get_sm_features, 50),
|
||||||
MyHost = gen_mod:get_opt_host(Host, Opts, <<"vjud.@HOST@">>),
|
MyHost = gen_mod:get_opt_host(Host, Opts, <<"vjud.@HOST@">>),
|
||||||
Search = gen_mod:get_opt(search, Opts,
|
Search = gen_mod:get_opt(search, Opts, false),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false),
|
|
||||||
if Search ->
|
if Search ->
|
||||||
ejabberd_hooks:add(
|
ejabberd_hooks:add(
|
||||||
disco_local_items, MyHost, ?MODULE, disco_items, 100),
|
disco_local_items, MyHost, ?MODULE, disco_items, 100),
|
||||||
@ -433,14 +430,8 @@ search(LServer, XFields) ->
|
|||||||
Data = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- XFields],
|
Data = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- XFields],
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all,
|
AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all,
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
false),
|
false),
|
||||||
MaxMatch = gen_mod:get_module_opt(LServer, ?MODULE, matches,
|
MaxMatch = gen_mod:get_module_opt(LServer, ?MODULE, matches, ?JUD_MATCHES),
|
||||||
fun(infinity) -> infinity;
|
|
||||||
(I) when is_integer(I),
|
|
||||||
I>0 ->
|
|
||||||
I
|
|
||||||
end, ?JUD_MATCHES),
|
|
||||||
Mod:search(LServer, Data, AllowReturnAll, MaxMatch).
|
Mod:search(LServer, Data, AllowReturnAll, MaxMatch).
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -355,31 +355,15 @@ default_search_reported() ->
|
|||||||
parse_options(Host, Opts) ->
|
parse_options(Host, Opts) ->
|
||||||
MyHost = gen_mod:get_opt_host(Host, Opts,
|
MyHost = gen_mod:get_opt_host(Host, Opts,
|
||||||
<<"vjud.@HOST@">>),
|
<<"vjud.@HOST@">>),
|
||||||
Search = gen_mod:get_opt(search, Opts,
|
Search = gen_mod:get_opt(search, Opts, false),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
Matches = gen_mod:get_opt(matches, Opts, 30),
|
||||||
false),
|
|
||||||
Matches = gen_mod:get_opt(matches, Opts,
|
|
||||||
fun(infinity) -> 0;
|
|
||||||
(I) when is_integer(I), I>0 -> I
|
|
||||||
end, 30),
|
|
||||||
Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?PROCNAME)),
|
Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?PROCNAME)),
|
||||||
Cfg = eldap_utils:get_config(Host, Opts),
|
Cfg = eldap_utils:get_config(Host, Opts),
|
||||||
UIDsTemp = gen_mod:get_opt(
|
UIDsTemp = gen_mod:get_opt({ldap_uids, Host}, Opts,
|
||||||
{ldap_uids, Host}, Opts,
|
[{<<"uid">>, <<"%u">>}]),
|
||||||
fun(Us) ->
|
|
||||||
lists:map(
|
|
||||||
fun({U, P}) ->
|
|
||||||
{iolist_to_binary(U),
|
|
||||||
iolist_to_binary(P)};
|
|
||||||
({U}) ->
|
|
||||||
{iolist_to_binary(U)}
|
|
||||||
end, Us)
|
|
||||||
end, [{<<"uid">>, <<"%u">>}]),
|
|
||||||
UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp),
|
UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp),
|
||||||
SubFilter = eldap_utils:generate_subfilter(UIDs),
|
SubFilter = eldap_utils:generate_subfilter(UIDs),
|
||||||
UserFilter = case gen_mod:get_opt(
|
UserFilter = case gen_mod:get_opt({ldap_filter, Host}, Opts, <<"">>) of
|
||||||
{ldap_filter, Host}, Opts,
|
|
||||||
fun eldap_utils:check_filter/1, <<"">>) of
|
|
||||||
<<"">> ->
|
<<"">> ->
|
||||||
SubFilter;
|
SubFilter;
|
||||||
F ->
|
F ->
|
||||||
@ -388,28 +372,11 @@ parse_options(Host, Opts) ->
|
|||||||
{ok, SearchFilter} =
|
{ok, SearchFilter} =
|
||||||
eldap_filter:parse(eldap_filter:do_sub(UserFilter,
|
eldap_filter:parse(eldap_filter:do_sub(UserFilter,
|
||||||
[{<<"%u">>, <<"*">>}])),
|
[{<<"%u">>, <<"*">>}])),
|
||||||
VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts,
|
VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts, default_vcard_map()),
|
||||||
fun(Ls) ->
|
|
||||||
lists:map(
|
|
||||||
fun({S, [{P, L}]}) ->
|
|
||||||
{iolist_to_binary(S),
|
|
||||||
iolist_to_binary(P),
|
|
||||||
[iolist_to_binary(E)
|
|
||||||
|| E <- L]}
|
|
||||||
end, Ls)
|
|
||||||
end, default_vcard_map()),
|
|
||||||
SearchFields = gen_mod:get_opt(ldap_search_fields, Opts,
|
SearchFields = gen_mod:get_opt(ldap_search_fields, Opts,
|
||||||
fun(Ls) ->
|
default_search_fields()),
|
||||||
[{iolist_to_binary(S),
|
|
||||||
iolist_to_binary(P)}
|
|
||||||
|| {S, P} <- Ls]
|
|
||||||
end, default_search_fields()),
|
|
||||||
SearchReported = gen_mod:get_opt(ldap_search_reported, Opts,
|
SearchReported = gen_mod:get_opt(ldap_search_reported, Opts,
|
||||||
fun(Ls) ->
|
default_search_reported()),
|
||||||
[{iolist_to_binary(S),
|
|
||||||
iolist_to_binary(P)}
|
|
||||||
|| {S, P} <- Ls]
|
|
||||||
end, default_search_reported()),
|
|
||||||
UIDAttrs = [UAttr || {UAttr, _} <- UIDs],
|
UIDAttrs = [UAttr || {UAttr, _} <- UIDs],
|
||||||
VCardMapAttrs = lists:usort(lists:append([A
|
VCardMapAttrs = lists:usort(lists:append([A
|
||||||
|| {_, _, A} <- VCardMap])
|
|| {_, _, A} <- VCardMap])
|
||||||
|
@ -197,9 +197,7 @@ filter_fields([{SVar, [Val]} | Ds], Match, LServer)
|
|||||||
<<"user">> ->
|
<<"user">> ->
|
||||||
case gen_mod:get_module_opt(LServer, ?MODULE,
|
case gen_mod:get_module_opt(LServer, ?MODULE,
|
||||||
search_all_hosts,
|
search_all_hosts,
|
||||||
fun(B) when is_boolean(B) ->
|
true) of
|
||||||
B
|
|
||||||
end, true) of
|
|
||||||
true -> Match#vcard_search{luser = make_val(LVal)};
|
true -> Match#vcard_search{luser = make_val(LVal)};
|
||||||
false ->
|
false ->
|
||||||
Host = find_my_host(LServer),
|
Host = find_my_host(LServer),
|
||||||
|
@ -40,8 +40,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
?NS_VERSION, ?MODULE, process_local_iq,
|
?NS_VERSION, ?MODULE, process_local_iq,
|
||||||
IQDisc).
|
IQDisc).
|
||||||
@ -51,9 +50,7 @@ stop(Host) ->
|
|||||||
?NS_VERSION).
|
?NS_VERSION).
|
||||||
|
|
||||||
reload(Host, NewOpts, OldOpts) ->
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, one_queue) of
|
||||||
fun gen_iq_handler:check_type/1,
|
|
||||||
one_queue) of
|
|
||||||
{false, IQDisc, _} ->
|
{false, IQDisc, _} ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION,
|
||||||
?MODULE, process_local_iq, IQDisc);
|
?MODULE, process_local_iq, IQDisc);
|
||||||
@ -66,9 +63,7 @@ process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
|
|||||||
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
||||||
process_local_iq(#iq{type = get, to = To} = IQ) ->
|
process_local_iq(#iq{type = get, to = To} = IQ) ->
|
||||||
Host = To#jid.lserver,
|
Host = To#jid.lserver,
|
||||||
OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os,
|
OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, true) of
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
true) of
|
|
||||||
true -> get_os();
|
true -> get_os();
|
||||||
false -> undefined
|
false -> undefined
|
||||||
end,
|
end,
|
||||||
|
@ -32,8 +32,7 @@
|
|||||||
%%% API
|
%%% API
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
start(Host, Opts) ->
|
start(Host, Opts) ->
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||||
one_queue),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_EVENT,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_EVENT,
|
||||||
?MODULE, process_iq, IQDisc).
|
?MODULE, process_iq, IQDisc).
|
||||||
|
|
||||||
|
@ -441,9 +441,7 @@ history_master(Config) ->
|
|||||||
MyNick = ?config(nick, Config),
|
MyNick = ?config(nick, Config),
|
||||||
MyNickJID = jid:replace_resource(Room, MyNick),
|
MyNickJID = jid:replace_resource(Room, MyNick),
|
||||||
PeerNickJID = peer_muc_jid(Config),
|
PeerNickJID = peer_muc_jid(Config),
|
||||||
Size = gen_mod:get_module_opt(ServerHost, mod_muc, history_size,
|
Size = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, 20),
|
||||||
fun(I) when is_integer(I), I>=0 -> I end,
|
|
||||||
20),
|
|
||||||
ok = join_new(Config),
|
ok = join_new(Config),
|
||||||
ct:comment("Putting ~p+1 messages in the history", [Size]),
|
ct:comment("Putting ~p+1 messages in the history", [Size]),
|
||||||
%% Only Size messages will be stored
|
%% Only Size messages will be stored
|
||||||
@ -471,9 +469,7 @@ history_slave(Config) ->
|
|||||||
PeerNick = ?config(peer_nick, Config),
|
PeerNick = ?config(peer_nick, Config),
|
||||||
PeerNickJID = jid:replace_resource(Room, PeerNick),
|
PeerNickJID = jid:replace_resource(Room, PeerNick),
|
||||||
ServerHost = ?config(server_host, Config),
|
ServerHost = ?config(server_host, Config),
|
||||||
Size = gen_mod:get_module_opt(ServerHost, mod_muc, history_size,
|
Size = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, 20),
|
||||||
fun(I) when is_integer(I), I>=0 -> I end,
|
|
||||||
20),
|
|
||||||
ct:comment("Waiting for 'join' command from the master"),
|
ct:comment("Waiting for 'join' command from the master"),
|
||||||
join = get_event(Config),
|
join = get_event(Config),
|
||||||
{History, _, _} = join(Config),
|
{History, _, _} = join(Config),
|
||||||
|
Loading…
Reference in New Issue
Block a user