mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-26 16:26:24 +01:00
Improve some type specs
This commit is contained in:
parent
4ff8d7918a
commit
522a186a38
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
-define(TDICT, dict:dict()).
|
-define(TDICT, dict:dict()).
|
||||||
-define(TGB_TREE, gb_trees:tree()).
|
-define(TGB_TREE, gb_trees:tree()).
|
||||||
-define(TGB_SET, gb_set:set()).
|
-define(TGB_SET, gb_sets:set()).
|
||||||
-define(TQUEUE, queue:queue()).
|
-define(TQUEUE, queue:queue()).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
@ -178,8 +178,8 @@
|
|||||||
-record(private, {xml_els = [] :: [fxml:xmlel()]}).
|
-record(private, {xml_els = [] :: [fxml:xmlel()]}).
|
||||||
-type private() :: #private{}.
|
-type private() :: #private{}.
|
||||||
|
|
||||||
-record(db_verify, {from :: jid:jid(),
|
-record(db_verify, {from = <<>> :: binary(),
|
||||||
to :: jid:jid(),
|
to = <<>> :: binary(),
|
||||||
id = <<>> :: binary(),
|
id = <<>> :: binary(),
|
||||||
type :: 'error' | 'invalid' | 'valid',
|
type :: 'error' | 'invalid' | 'valid',
|
||||||
key = <<>> :: binary(),
|
key = <<>> :: binary(),
|
||||||
@ -361,7 +361,7 @@
|
|||||||
-record(caps, {node = <<>> :: binary(),
|
-record(caps, {node = <<>> :: binary(),
|
||||||
version = <<>> :: binary(),
|
version = <<>> :: binary(),
|
||||||
hash = <<>> :: binary(),
|
hash = <<>> :: binary(),
|
||||||
exts = [] :: binary() | []}).
|
exts = [] :: [binary()]}).
|
||||||
-type caps() :: #caps{}.
|
-type caps() :: #caps{}.
|
||||||
|
|
||||||
-record(muc, {history :: #muc_history{},
|
-record(muc, {history :: #muc_history{},
|
||||||
@ -428,8 +428,8 @@
|
|||||||
userid :: binary()}).
|
userid :: binary()}).
|
||||||
-type vcard_email() :: #vcard_email{}.
|
-type vcard_email() :: #vcard_email{}.
|
||||||
|
|
||||||
-record(db_result, {from :: jid:jid(),
|
-record(db_result, {from = <<>> :: binary(),
|
||||||
to :: jid:jid(),
|
to = <<>> :: binary(),
|
||||||
type :: 'error' | 'invalid' | 'valid',
|
type :: 'error' | 'invalid' | 'valid',
|
||||||
key = <<>> :: binary(),
|
key = <<>> :: binary(),
|
||||||
sub_els = [] :: [xmpp_element() | fxml:xmlel()]}).
|
sub_els = [] :: [xmpp_element() | fxml:xmlel()]}).
|
||||||
|
@ -139,6 +139,7 @@ remove_connection(SID, LUser, LServer) ->
|
|||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
%% Register connection
|
%% Register connection
|
||||||
|
-spec register_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
|
||||||
register_connection(SID,
|
register_connection(SID,
|
||||||
#jid{luser = LUser, lserver = LServer}, Info) ->
|
#jid{luser = LUser, lserver = LServer}, Info) ->
|
||||||
AuthModule = proplists:get_value(auth_module, Info, undefined),
|
AuthModule = proplists:get_value(auth_module, Info, undefined),
|
||||||
@ -155,6 +156,7 @@ register_connection(SID,
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% Remove an anonymous user from the anonymous users table
|
%% Remove an anonymous user from the anonymous users table
|
||||||
|
-spec unregister_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> any().
|
||||||
unregister_connection(SID,
|
unregister_connection(SID,
|
||||||
#jid{luser = LUser, lserver = LServer}, _) ->
|
#jid{luser = LUser, lserver = LServer}, _) ->
|
||||||
purge_hook(anonymous_user_exist(LUser, LServer), LUser,
|
purge_hook(anonymous_user_exist(LUser, LServer), LUser,
|
||||||
|
@ -125,6 +125,7 @@
|
|||||||
-type state() :: #state{}.
|
-type state() :: #state{}.
|
||||||
-type fsm_stop() :: {stop, normal, state()}.
|
-type fsm_stop() :: {stop, normal, state()}.
|
||||||
-type fsm_next() :: {next_state, state_name(), state(), non_neg_integer()}.
|
-type fsm_next() :: {next_state, state_name(), state(), non_neg_integer()}.
|
||||||
|
-type fsm_reply() :: {reply, any(), state_name(), state(), non_neg_integer()}.
|
||||||
-type fsm_transition() :: fsm_stop() | fsm_next().
|
-type fsm_transition() :: fsm_stop() | fsm_next().
|
||||||
-export_type([state/0]).
|
-export_type([state/0]).
|
||||||
|
|
||||||
@ -184,9 +185,9 @@ get_presence(FsmRef) ->
|
|||||||
|
|
||||||
-spec get_aux_field(any(), state()) -> {ok, any()} | error.
|
-spec get_aux_field(any(), state()) -> {ok, any()} | error.
|
||||||
get_aux_field(Key, #state{aux_fields = Opts}) ->
|
get_aux_field(Key, #state{aux_fields = Opts}) ->
|
||||||
case lists:keysearch(Key, 1, Opts) of
|
case lists:keyfind(Key, 1, Opts) of
|
||||||
{value, {_, Val}} -> {ok, Val};
|
{_, Val} -> {ok, Val};
|
||||||
_ -> error
|
false -> error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec set_aux_field(any(), any(), state()) -> state().
|
-spec set_aux_field(any(), any(), state()) -> state().
|
||||||
@ -525,7 +526,7 @@ wait_for_auth(#iq{type = get,
|
|||||||
Auth = #legacy_auth{username = Username, password = <<>>, resource = <<>>},
|
Auth = #legacy_auth{username = Username, password = <<>>, resource = <<>>},
|
||||||
Res = case ejabberd_auth:plain_password_required(StateData#state.server) of
|
Res = case ejabberd_auth:plain_password_required(StateData#state.server) of
|
||||||
false ->
|
false ->
|
||||||
xmpp:make_iq_result(IQ, Auth#legacy_auth{digest = none});
|
xmpp:make_iq_result(IQ, Auth#legacy_auth{digest = <<>>});
|
||||||
true ->
|
true ->
|
||||||
xmpp:make_iq_result(IQ, Auth)
|
xmpp:make_iq_result(IQ, Auth)
|
||||||
end,
|
end,
|
||||||
@ -1067,7 +1068,6 @@ session_established2(Pkt, StateData) ->
|
|||||||
J -> J
|
J -> J
|
||||||
end,
|
end,
|
||||||
Lang = case xmpp:get_lang(Pkt) of
|
Lang = case xmpp:get_lang(Pkt) of
|
||||||
undefined -> StateData#state.lang;
|
|
||||||
<<"">> -> StateData#state.lang;
|
<<"">> -> StateData#state.lang;
|
||||||
L -> L
|
L -> L
|
||||||
end,
|
end,
|
||||||
@ -1252,7 +1252,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) when ?is_stanza(Pac
|
|||||||
process_presence_probe(From, To, NewStateData),
|
process_presence_probe(From, To, NewStateData),
|
||||||
{false, NewStateData};
|
{false, NewStateData};
|
||||||
error ->
|
error ->
|
||||||
NewA = remove_element(jid:tolower(From), State#state.pres_a),
|
NewA = ?SETS:del_element(jid:tolower(From), State#state.pres_a),
|
||||||
{true, State#state{pres_a = NewA}};
|
{true, State#state{pres_a = NewA}};
|
||||||
subscribe ->
|
subscribe ->
|
||||||
SRes = is_privacy_allow(State, From, To, Packet, in),
|
SRes = is_privacy_allow(State, From, To, Packet, in),
|
||||||
@ -1666,6 +1666,7 @@ get_conn_type(StateData) ->
|
|||||||
websocket -> websocket
|
websocket -> websocket
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec process_presence_probe(jid(), jid(), state()) -> ok.
|
||||||
process_presence_probe(From, To, StateData) ->
|
process_presence_probe(From, To, StateData) ->
|
||||||
LFrom = jid:tolower(From),
|
LFrom = jid:tolower(From),
|
||||||
LBFrom = setelement(3, LFrom, <<"">>),
|
LBFrom = setelement(3, LFrom, <<"">>),
|
||||||
@ -1702,6 +1703,7 @@ process_presence_probe(From, To, StateData) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% User updates his presence (non-directed presence packet)
|
%% User updates his presence (non-directed presence packet)
|
||||||
|
-spec presence_update(jid(), presence(), state()) -> state().
|
||||||
presence_update(From, Packet, StateData) ->
|
presence_update(From, Packet, StateData) ->
|
||||||
#presence{type = Type} = Packet,
|
#presence{type = Type} = Packet,
|
||||||
case Type of
|
case Type of
|
||||||
@ -1761,6 +1763,7 @@ presence_update(From, Packet, StateData) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% User sends a directed presence packet
|
%% User sends a directed presence packet
|
||||||
|
-spec presence_track(jid(), jid(), presence(), state()) -> state().
|
||||||
presence_track(From, To, Packet, StateData) ->
|
presence_track(From, To, Packet, StateData) ->
|
||||||
#presence{type = Type} = Packet,
|
#presence{type = Type} = Packet,
|
||||||
LTo = jid:tolower(To),
|
LTo = jid:tolower(To),
|
||||||
@ -1768,7 +1771,7 @@ presence_track(From, To, Packet, StateData) ->
|
|||||||
Server = StateData#state.server,
|
Server = StateData#state.server,
|
||||||
case Type of
|
case Type of
|
||||||
unavailable ->
|
unavailable ->
|
||||||
A = remove_element(LTo, StateData#state.pres_a),
|
A = ?SETS:del_element(LTo, StateData#state.pres_a),
|
||||||
check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet);
|
check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet);
|
||||||
subscribe ->
|
subscribe ->
|
||||||
try_roster_subscribe(subscribe, User, Server, From, To, Packet, StateData);
|
try_roster_subscribe(subscribe, User, Server, From, To, Packet, StateData);
|
||||||
@ -1793,6 +1796,7 @@ presence_track(From, To, Packet, StateData) ->
|
|||||||
check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet)
|
check_privacy_route(From, StateData#state{pres_a = A}, From, To, Packet)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec check_privacy_route(jid(), state(), jid(), jid(), stanza()) -> state().
|
||||||
check_privacy_route(From, StateData, FromRoute, To,
|
check_privacy_route(From, StateData, FromRoute, To,
|
||||||
Packet) ->
|
Packet) ->
|
||||||
case privacy_check_packet(StateData, From, To, Packet,
|
case privacy_check_packet(StateData, From, To, Packet,
|
||||||
@ -1812,6 +1816,7 @@ check_privacy_route(From, StateData, FromRoute, To,
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% Check if privacy rules allow this delivery
|
%% Check if privacy rules allow this delivery
|
||||||
|
-spec privacy_check_packet(state(), jid(), jid(), stanza(), in | out) -> allow | deny.
|
||||||
privacy_check_packet(StateData, From, To, Packet,
|
privacy_check_packet(StateData, From, To, Packet,
|
||||||
Dir) ->
|
Dir) ->
|
||||||
ejabberd_hooks:run_fold(privacy_check_packet,
|
ejabberd_hooks:run_fold(privacy_check_packet,
|
||||||
@ -1820,11 +1825,14 @@ privacy_check_packet(StateData, From, To, Packet,
|
|||||||
StateData#state.privacy_list, {From, To, Packet},
|
StateData#state.privacy_list, {From, To, Packet},
|
||||||
Dir]).
|
Dir]).
|
||||||
|
|
||||||
|
-spec is_privacy_allow(state(), jid(), jid(), stanza(), in | out) -> boolean().
|
||||||
is_privacy_allow(StateData, From, To, Packet, Dir) ->
|
is_privacy_allow(StateData, From, To, Packet, Dir) ->
|
||||||
allow ==
|
allow ==
|
||||||
privacy_check_packet(StateData, From, To, Packet, Dir).
|
privacy_check_packet(StateData, From, To, Packet, Dir).
|
||||||
|
|
||||||
%%% Check ACL before allowing to send a subscription stanza
|
%%% Check ACL before allowing to send a subscription stanza
|
||||||
|
-spec try_roster_subscribe(subscribe | unsubscribe, binary(), binary(),
|
||||||
|
jid(), jid(), presence(), state()) -> state().
|
||||||
try_roster_subscribe(Type, User, Server, From, To, Packet, StateData) ->
|
try_roster_subscribe(Type, User, Server, From, To, Packet, StateData) ->
|
||||||
JID1 = jid:make(User, Server, <<"">>),
|
JID1 = jid:make(User, Server, <<"">>),
|
||||||
Access = gen_mod:get_module_opt(Server, mod_roster, access, fun(A) when is_atom(A) -> A end, all),
|
Access = gen_mod:get_module_opt(Server, mod_roster, access, fun(A) when is_atom(A) -> A end, all),
|
||||||
@ -1841,21 +1849,24 @@ try_roster_subscribe(Type, User, Server, From, To, Packet, StateData) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% Send presence when disconnecting
|
%% Send presence when disconnecting
|
||||||
|
-spec presence_broadcast(state(), jid(), ?SETS:set(), presence()) -> ok.
|
||||||
presence_broadcast(StateData, From, JIDSet, Packet) ->
|
presence_broadcast(StateData, From, JIDSet, Packet) ->
|
||||||
JIDs = ?SETS:to_list(JIDSet),
|
JIDs = ?SETS:to_list(JIDSet),
|
||||||
JIDs2 = format_and_check_privacy(From, StateData, Packet, JIDs, out),
|
JIDs2 = format_and_check_privacy(From, StateData, Packet, JIDs, out),
|
||||||
Server = StateData#state.server,
|
Server = StateData#state.server,
|
||||||
send_multiple(From, Server, JIDs2, Packet).
|
send_multiple(From, Server, JIDs2, Packet).
|
||||||
|
|
||||||
|
-spec presence_broadcast_to_trusted(
|
||||||
|
state(), jid(), ?SETS:set(), ?SETS:set(), presence()) -> ok.
|
||||||
%% Send presence when updating presence
|
%% Send presence when updating presence
|
||||||
presence_broadcast_to_trusted(StateData, From, Trusted, JIDSet, Packet) ->
|
presence_broadcast_to_trusted(StateData, From, Trusted, JIDSet, Packet) ->
|
||||||
JIDs = ?SETS:to_list(JIDSet),
|
JIDs = ?SETS:to_list(?SETS:intersection(Trusted, JIDSet)),
|
||||||
JIDs_trusted = [JID || JID <- JIDs, ?SETS:is_element(JID, Trusted)],
|
JIDs2 = format_and_check_privacy(From, StateData, Packet, JIDs, out),
|
||||||
JIDs2 = format_and_check_privacy(From, StateData, Packet, JIDs_trusted, out),
|
|
||||||
Server = StateData#state.server,
|
Server = StateData#state.server,
|
||||||
send_multiple(From, Server, JIDs2, Packet).
|
send_multiple(From, Server, JIDs2, Packet).
|
||||||
|
|
||||||
%% Send presence when connecting
|
%% Send presence when connecting
|
||||||
|
-spec presence_broadcast_first(jid(), state(), presence()) -> state().
|
||||||
presence_broadcast_first(From, StateData, Packet) ->
|
presence_broadcast_first(From, StateData, Packet) ->
|
||||||
JIDsProbe =
|
JIDsProbe =
|
||||||
?SETS:fold(
|
?SETS:fold(
|
||||||
@ -1877,6 +1888,8 @@ presence_broadcast_first(From, StateData, Packet) ->
|
|||||||
send_multiple(From, Server, JIDs2, Packet),
|
send_multiple(From, Server, JIDs2, Packet),
|
||||||
StateData#state{pres_a = As}.
|
StateData#state{pres_a = As}.
|
||||||
|
|
||||||
|
-spec format_and_check_privacy(
|
||||||
|
jid(), state(), stanza(), [ljid()], in | out) -> [jid()].
|
||||||
format_and_check_privacy(From, StateData, Packet, JIDs, Dir) ->
|
format_and_check_privacy(From, StateData, Packet, JIDs, Dir) ->
|
||||||
FJIDs = [jid:make(JID) || JID <- JIDs],
|
FJIDs = [jid:make(JID) || JID <- JIDs],
|
||||||
lists:filter(
|
lists:filter(
|
||||||
@ -1895,15 +1908,11 @@ format_and_check_privacy(From, StateData, Packet, JIDs, Dir) ->
|
|||||||
end,
|
end,
|
||||||
FJIDs).
|
FJIDs).
|
||||||
|
|
||||||
|
-spec send_multiple(jid(), binary(), [jid()], stanza()) -> ok.
|
||||||
send_multiple(From, Server, JIDs, Packet) ->
|
send_multiple(From, Server, JIDs, Packet) ->
|
||||||
ejabberd_router_multicast:route_multicast(From, Server, JIDs, Packet).
|
ejabberd_router_multicast:route_multicast(From, Server, JIDs, Packet).
|
||||||
|
|
||||||
remove_element(E, Set) ->
|
-spec roster_change(jid(), both | from | none | remove | to, state()) -> state().
|
||||||
case (?SETS):is_element(E, Set) of
|
|
||||||
true -> (?SETS):del_element(E, Set);
|
|
||||||
_ -> Set
|
|
||||||
end.
|
|
||||||
|
|
||||||
roster_change(IJID, ISubscription, StateData) ->
|
roster_change(IJID, ISubscription, StateData) ->
|
||||||
LIJID = jid:tolower(IJID),
|
LIJID = jid:tolower(IJID),
|
||||||
IsFrom = (ISubscription == both) or (ISubscription == from),
|
IsFrom = (ISubscription == both) or (ISubscription == from),
|
||||||
@ -1911,11 +1920,11 @@ roster_change(IJID, ISubscription, StateData) ->
|
|||||||
OldIsFrom = (?SETS):is_element(LIJID, StateData#state.pres_f),
|
OldIsFrom = (?SETS):is_element(LIJID, StateData#state.pres_f),
|
||||||
FSet = if
|
FSet = if
|
||||||
IsFrom -> (?SETS):add_element(LIJID, StateData#state.pres_f);
|
IsFrom -> (?SETS):add_element(LIJID, StateData#state.pres_f);
|
||||||
true -> remove_element(LIJID, StateData#state.pres_f)
|
true -> ?SETS:del_element(LIJID, StateData#state.pres_f)
|
||||||
end,
|
end,
|
||||||
TSet = if
|
TSet = if
|
||||||
IsTo -> (?SETS):add_element(LIJID, StateData#state.pres_t);
|
IsTo -> (?SETS):add_element(LIJID, StateData#state.pres_t);
|
||||||
true -> remove_element(LIJID, StateData#state.pres_t)
|
true -> ?SETS:del_element(LIJID, StateData#state.pres_t)
|
||||||
end,
|
end,
|
||||||
case StateData#state.pres_last of
|
case StateData#state.pres_last of
|
||||||
undefined ->
|
undefined ->
|
||||||
@ -1946,13 +1955,14 @@ roster_change(IJID, ISubscription, StateData) ->
|
|||||||
deny -> ok;
|
deny -> ok;
|
||||||
allow -> ejabberd_router:route(From, To, PU)
|
allow -> ejabberd_router:route(From, To, PU)
|
||||||
end,
|
end,
|
||||||
A = remove_element(LIJID, StateData#state.pres_a),
|
A = ?SETS:del_element(LIJID, StateData#state.pres_a),
|
||||||
StateData#state{pres_a = A, pres_f = FSet,
|
StateData#state{pres_a = A, pres_f = FSet,
|
||||||
pres_t = TSet};
|
pres_t = TSet};
|
||||||
true -> StateData#state{pres_f = FSet, pres_t = TSet}
|
true -> StateData#state{pres_f = FSet, pres_t = TSet}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec update_priority(integer(), presence(), state()) -> ok.
|
||||||
update_priority(Priority, Packet, StateData) ->
|
update_priority(Priority, Packet, StateData) ->
|
||||||
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
|
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
|
||||||
{auth_module, StateData#state.auth_module}],
|
{auth_module, StateData#state.auth_module}],
|
||||||
@ -1960,12 +1970,14 @@ update_priority(Priority, Packet, StateData) ->
|
|||||||
StateData#state.user, StateData#state.server,
|
StateData#state.user, StateData#state.server,
|
||||||
StateData#state.resource, Priority, Packet, Info).
|
StateData#state.resource, Priority, Packet, Info).
|
||||||
|
|
||||||
|
-spec get_priority_from_presence(presence()) -> integer().
|
||||||
get_priority_from_presence(#presence{priority = Prio}) ->
|
get_priority_from_presence(#presence{priority = Prio}) ->
|
||||||
case Prio of
|
case Prio of
|
||||||
undefined -> 0;
|
undefined -> 0;
|
||||||
_ -> Prio
|
_ -> Prio
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec process_privacy_iq(iq(), state()) -> state().
|
||||||
process_privacy_iq(#iq{from = From, to = To,
|
process_privacy_iq(#iq{from = From, to = To,
|
||||||
type = Type, lang = Lang} = IQ, StateData) ->
|
type = Type, lang = Lang} = IQ, StateData) ->
|
||||||
Txt = <<"No module is handling this query">>,
|
Txt = <<"No module is handling this query">>,
|
||||||
@ -2001,6 +2013,7 @@ process_privacy_iq(#iq{from = From, to = To,
|
|||||||
ejabberd_router:route(To, From, IQRes),
|
ejabberd_router:route(To, From, IQRes),
|
||||||
NewStateData.
|
NewStateData.
|
||||||
|
|
||||||
|
-spec resend_offline_messages(state()) -> ok.
|
||||||
resend_offline_messages(#state{ask_offline = true} = StateData) ->
|
resend_offline_messages(#state{ask_offline = true} = StateData) ->
|
||||||
case ejabberd_hooks:run_fold(resend_offline_messages_hook,
|
case ejabberd_hooks:run_fold(resend_offline_messages_hook,
|
||||||
StateData#state.server, [],
|
StateData#state.server, [],
|
||||||
@ -2025,6 +2038,7 @@ resend_offline_messages(#state{ask_offline = true} = StateData) ->
|
|||||||
resend_offline_messages(_StateData) ->
|
resend_offline_messages(_StateData) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec resend_subscription_requests(state()) -> state().
|
||||||
resend_subscription_requests(#state{user = User,
|
resend_subscription_requests(#state{user = User,
|
||||||
server = Server} = StateData) ->
|
server = Server} = StateData) ->
|
||||||
PendingSubscriptions =
|
PendingSubscriptions =
|
||||||
@ -2036,13 +2050,16 @@ resend_subscription_requests(#state{user = User,
|
|||||||
StateData,
|
StateData,
|
||||||
PendingSubscriptions).
|
PendingSubscriptions).
|
||||||
|
|
||||||
|
-spec get_showtag(undefined | presence()) -> binary().
|
||||||
get_showtag(undefined) -> <<"unavailable">>;
|
get_showtag(undefined) -> <<"unavailable">>;
|
||||||
get_showtag(#presence{show = undefined}) -> <<"available">>;
|
get_showtag(#presence{show = undefined}) -> <<"available">>;
|
||||||
get_showtag(#presence{show = Show}) -> atom_to_binary(Show, utf8).
|
get_showtag(#presence{show = Show}) -> atom_to_binary(Show, utf8).
|
||||||
|
|
||||||
get_statustag(#presence{status = [#text{data = Status}|_]}) -> Status;
|
-spec get_statustag(undefined | presence()) -> binary().
|
||||||
get_statustag(_) -> <<"">>.
|
get_statustag(#presence{status = Status}) -> xmpp:get_text(Status);
|
||||||
|
get_statustag(undefined) -> <<"">>.
|
||||||
|
|
||||||
|
-spec process_unauthenticated_stanza(state(), iq()) -> ok | {error, any()}.
|
||||||
process_unauthenticated_stanza(StateData, #iq{type = T, lang = L} = IQ)
|
process_unauthenticated_stanza(StateData, #iq{type = T, lang = L} = IQ)
|
||||||
when T == set; T == get ->
|
when T == set; T == get ->
|
||||||
Lang = if L == undefined; L == <<"">> -> StateData#state.lang;
|
Lang = if L == undefined; L == <<"">> -> StateData#state.lang;
|
||||||
@ -2067,6 +2084,9 @@ process_unauthenticated_stanza(_StateData, _) ->
|
|||||||
%% Drop any stanza, which isn't IQ stanza
|
%% Drop any stanza, which isn't IQ stanza
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec peerip(ejabberd_socket:sockmod(),
|
||||||
|
ejabberd_socket:socket()) ->
|
||||||
|
{inet:ip_address(), non_neg_integer()} | undefined.
|
||||||
peerip(SockMod, Socket) ->
|
peerip(SockMod, Socket) ->
|
||||||
IP = case SockMod of
|
IP = case SockMod of
|
||||||
gen_tcp -> inet:peername(Socket);
|
gen_tcp -> inet:peername(Socket);
|
||||||
@ -2124,6 +2144,7 @@ fsm_next_state(StateName, StateData) ->
|
|||||||
|
|
||||||
%% fsm_reply: Generate the reply FSM tuple with different timeout,
|
%% fsm_reply: Generate the reply FSM tuple with different timeout,
|
||||||
%% depending on the future state
|
%% depending on the future state
|
||||||
|
-spec fsm_reply(_, state_name(), state()) -> fsm_reply().
|
||||||
fsm_reply(Reply, session_established, StateData) ->
|
fsm_reply(Reply, session_established, StateData) ->
|
||||||
{reply, Reply, session_established, StateData,
|
{reply, Reply, session_established, StateData,
|
||||||
?C2S_HIBERNATE_TIMEOUT};
|
?C2S_HIBERNATE_TIMEOUT};
|
||||||
@ -2135,6 +2156,8 @@ fsm_reply(Reply, StateName, StateData) ->
|
|||||||
{reply, Reply, StateName, StateData, ?C2S_OPEN_TIMEOUT}.
|
{reply, Reply, StateName, StateData, ?C2S_OPEN_TIMEOUT}.
|
||||||
|
|
||||||
%% Used by c2s blacklist plugins
|
%% Used by c2s blacklist plugins
|
||||||
|
-spec is_ip_blacklisted(undefined | {inet:ip_address(), non_neg_integer()},
|
||||||
|
binary()) -> false | {true, binary(), binary()}.
|
||||||
is_ip_blacklisted(undefined, _Lang) -> false;
|
is_ip_blacklisted(undefined, _Lang) -> false;
|
||||||
is_ip_blacklisted({IP, _Port}, Lang) ->
|
is_ip_blacklisted({IP, _Port}, Lang) ->
|
||||||
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP, Lang]).
|
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP, Lang]).
|
||||||
@ -2174,6 +2197,7 @@ fsm_limit_opts(Opts) ->
|
|||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec bounce_messages() -> ok.
|
||||||
bounce_messages() ->
|
bounce_messages() ->
|
||||||
receive
|
receive
|
||||||
{route, From, To, El} ->
|
{route, From, To, El} ->
|
||||||
@ -2181,6 +2205,7 @@ bounce_messages() ->
|
|||||||
after 0 -> ok
|
after 0 -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec process_compression_request(compress(), state_name(), state()) -> fsm_next().
|
||||||
process_compression_request(#compress{methods = []}, StateName, StateData) ->
|
process_compression_request(#compress{methods = []}, StateName, StateData) ->
|
||||||
send_element(StateData, #compress_failure{reason = 'setup-failed'}),
|
send_element(StateData, #compress_failure{reason = 'setup-failed'}),
|
||||||
fsm_next_state(StateName, StateData);
|
fsm_next_state(StateName, StateData);
|
||||||
@ -2203,6 +2228,8 @@ process_compression_request(#compress{methods = Ms}, StateName, StateData) ->
|
|||||||
%%% XEP-0191
|
%%% XEP-0191
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec route_blocking(
|
||||||
|
{block, [jid()]} | {unblock, [jid()]} | unblock_all, state()) -> state().
|
||||||
route_blocking(What, StateData) ->
|
route_blocking(What, StateData) ->
|
||||||
SubEl = case What of
|
SubEl = case What of
|
||||||
{block, JIDs} ->
|
{block, JIDs} ->
|
||||||
@ -2223,12 +2250,13 @@ route_blocking(What, StateData) ->
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% XEP-0198
|
%%% XEP-0198
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
-spec stream_mgmt_enabled(state()) -> boolean().
|
||||||
stream_mgmt_enabled(#state{mgmt_state = disabled}) ->
|
stream_mgmt_enabled(#state{mgmt_state = disabled}) ->
|
||||||
false;
|
false;
|
||||||
stream_mgmt_enabled(_StateData) ->
|
stream_mgmt_enabled(_StateData) ->
|
||||||
true.
|
true.
|
||||||
|
|
||||||
|
-spec dispatch_stream_mgmt(xmpp_element(), state()) -> state().
|
||||||
dispatch_stream_mgmt(El, #state{mgmt_state = MgmtState} = StateData)
|
dispatch_stream_mgmt(El, #state{mgmt_state = MgmtState} = StateData)
|
||||||
when MgmtState == active;
|
when MgmtState == active;
|
||||||
MgmtState == pending ->
|
MgmtState == pending ->
|
||||||
@ -2236,6 +2264,7 @@ dispatch_stream_mgmt(El, #state{mgmt_state = MgmtState} = StateData)
|
|||||||
dispatch_stream_mgmt(El, StateData) ->
|
dispatch_stream_mgmt(El, StateData) ->
|
||||||
negotiate_stream_mgmt(El, StateData).
|
negotiate_stream_mgmt(El, StateData).
|
||||||
|
|
||||||
|
-spec negotiate_stream_mgmt(xmpp_element(), state()) -> state().
|
||||||
negotiate_stream_mgmt(_El, #state{resource = <<"">>} = StateData) ->
|
negotiate_stream_mgmt(_El, #state{resource = <<"">>} = StateData) ->
|
||||||
%% XEP-0198 says: "For client-to-server connections, the client MUST NOT
|
%% XEP-0198 says: "For client-to-server connections, the client MUST NOT
|
||||||
%% attempt to enable stream management until after it has completed Resource
|
%% attempt to enable stream management until after it has completed Resource
|
||||||
@ -2272,6 +2301,7 @@ negotiate_stream_mgmt(Pkt, StateData) ->
|
|||||||
StateData
|
StateData
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec perform_stream_mgmt(xmpp_element(), state()) -> state().
|
||||||
perform_stream_mgmt(Pkt, StateData) ->
|
perform_stream_mgmt(Pkt, StateData) ->
|
||||||
case xmpp:get_ns(Pkt) of
|
case xmpp:get_ns(Pkt) of
|
||||||
Xmlns when Xmlns == StateData#state.mgmt_xmlns ->
|
Xmlns when Xmlns == StateData#state.mgmt_xmlns ->
|
||||||
@ -2298,6 +2328,7 @@ perform_stream_mgmt(Pkt, StateData) ->
|
|||||||
xmlns = StateData#state.mgmt_xmlns})
|
xmlns = StateData#state.mgmt_xmlns})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec handle_enable(state(), sm_enable()) -> state().
|
||||||
handle_enable(#state{mgmt_timeout = DefaultTimeout,
|
handle_enable(#state{mgmt_timeout = DefaultTimeout,
|
||||||
mgmt_max_timeout = MaxTimeout} = StateData,
|
mgmt_max_timeout = MaxTimeout} = StateData,
|
||||||
#sm_enable{resume = Resume, max = Max}) ->
|
#sm_enable{resume = Resume, max = Max}) ->
|
||||||
@ -2325,15 +2356,18 @@ handle_enable(#state{mgmt_timeout = DefaultTimeout,
|
|||||||
mgmt_queue = queue:new(),
|
mgmt_queue = queue:new(),
|
||||||
mgmt_timeout = Timeout * 1000}.
|
mgmt_timeout = Timeout * 1000}.
|
||||||
|
|
||||||
|
-spec handle_r(state()) -> state().
|
||||||
handle_r(StateData) ->
|
handle_r(StateData) ->
|
||||||
Res = #sm_a{xmlns = StateData#state.mgmt_xmlns,
|
Res = #sm_a{xmlns = StateData#state.mgmt_xmlns,
|
||||||
h = StateData#state.mgmt_stanzas_in},
|
h = StateData#state.mgmt_stanzas_in},
|
||||||
send_element(StateData, Res),
|
send_element(StateData, Res),
|
||||||
StateData.
|
StateData.
|
||||||
|
|
||||||
|
-spec handle_a(state(), sm_a()) -> state().
|
||||||
handle_a(StateData, #sm_a{h = H}) ->
|
handle_a(StateData, #sm_a{h = H}) ->
|
||||||
check_h_attribute(StateData, H).
|
check_h_attribute(StateData, H).
|
||||||
|
|
||||||
|
-spec handle_resume(state(), sm_resume()) -> {ok, state()} | error.
|
||||||
handle_resume(StateData, #sm_resume{h = H, previd = PrevID, xmlns = Xmlns}) ->
|
handle_resume(StateData, #sm_resume{h = H, previd = PrevID, xmlns = Xmlns}) ->
|
||||||
R = case stream_mgmt_enabled(StateData) of
|
R = case stream_mgmt_enabled(StateData) of
|
||||||
true ->
|
true ->
|
||||||
@ -2379,6 +2413,7 @@ handle_resume(StateData, #sm_resume{h = H, previd = PrevID, xmlns = Xmlns}) ->
|
|||||||
error
|
error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec check_h_attribute(state(), non_neg_integer()) -> state().
|
||||||
check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H)
|
check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H)
|
||||||
when H > NumStanzasOut ->
|
when H > NumStanzasOut ->
|
||||||
?DEBUG("~s acknowledged ~B stanzas, but only ~B were sent",
|
?DEBUG("~s acknowledged ~B stanzas, but only ~B were sent",
|
||||||
@ -2389,6 +2424,7 @@ check_h_attribute(#state{mgmt_stanzas_out = NumStanzasOut} = StateData, H) ->
|
|||||||
[jid:to_string(StateData#state.jid), H, NumStanzasOut]),
|
[jid:to_string(StateData#state.jid), H, NumStanzasOut]),
|
||||||
mgmt_queue_drop(StateData, H).
|
mgmt_queue_drop(StateData, H).
|
||||||
|
|
||||||
|
-spec update_num_stanzas_in(state(), xmpp_element()) -> state().
|
||||||
update_num_stanzas_in(#state{mgmt_state = MgmtState} = StateData, El)
|
update_num_stanzas_in(#state{mgmt_state = MgmtState} = StateData, El)
|
||||||
when MgmtState == active;
|
when MgmtState == active;
|
||||||
MgmtState == pending ->
|
MgmtState == pending ->
|
||||||
@ -2404,6 +2440,7 @@ update_num_stanzas_in(#state{mgmt_state = MgmtState} = StateData, El)
|
|||||||
update_num_stanzas_in(StateData, _El) ->
|
update_num_stanzas_in(StateData, _El) ->
|
||||||
StateData.
|
StateData.
|
||||||
|
|
||||||
|
-spec send_stanza_and_ack_req(state(), stanza()) -> state().
|
||||||
send_stanza_and_ack_req(StateData, Stanza) ->
|
send_stanza_and_ack_req(StateData, Stanza) ->
|
||||||
AckReq = #sm_r{xmlns = StateData#state.mgmt_xmlns},
|
AckReq = #sm_r{xmlns = StateData#state.mgmt_xmlns},
|
||||||
case send_element(StateData, Stanza) == ok andalso
|
case send_element(StateData, Stanza) == ok andalso
|
||||||
@ -2414,6 +2451,7 @@ send_stanza_and_ack_req(StateData, Stanza) ->
|
|||||||
StateData#state{mgmt_state = pending}
|
StateData#state{mgmt_state = pending}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec mgmt_queue_add(state(), xmpp_element()) -> state().
|
||||||
mgmt_queue_add(StateData, El) ->
|
mgmt_queue_add(StateData, El) ->
|
||||||
NewNum = case StateData#state.mgmt_stanzas_out of
|
NewNum = case StateData#state.mgmt_stanzas_out of
|
||||||
4294967295 ->
|
4294967295 ->
|
||||||
@ -2426,11 +2464,13 @@ mgmt_queue_add(StateData, El) ->
|
|||||||
mgmt_stanzas_out = NewNum},
|
mgmt_stanzas_out = NewNum},
|
||||||
check_queue_length(NewState).
|
check_queue_length(NewState).
|
||||||
|
|
||||||
|
-spec mgmt_queue_drop(state(), non_neg_integer()) -> state().
|
||||||
mgmt_queue_drop(StateData, NumHandled) ->
|
mgmt_queue_drop(StateData, NumHandled) ->
|
||||||
NewQueue = jlib:queue_drop_while(fun({N, _T, _E}) -> N =< NumHandled end,
|
NewQueue = jlib:queue_drop_while(fun({N, _T, _E}) -> N =< NumHandled end,
|
||||||
StateData#state.mgmt_queue),
|
StateData#state.mgmt_queue),
|
||||||
StateData#state{mgmt_queue = NewQueue}.
|
StateData#state{mgmt_queue = NewQueue}.
|
||||||
|
|
||||||
|
-spec check_queue_length(state()) -> state().
|
||||||
check_queue_length(#state{mgmt_max_queue = Limit} = StateData)
|
check_queue_length(#state{mgmt_max_queue = Limit} = StateData)
|
||||||
when Limit == infinity;
|
when Limit == infinity;
|
||||||
Limit == exceeded ->
|
Limit == exceeded ->
|
||||||
@ -2444,6 +2484,7 @@ check_queue_length(#state{mgmt_queue = Queue,
|
|||||||
StateData
|
StateData
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec handle_unacked_stanzas(state(), fun((_, _, _, _) -> _)) -> ok.
|
||||||
handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData, F)
|
handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData, F)
|
||||||
when MgmtState == active;
|
when MgmtState == active;
|
||||||
MgmtState == pending;
|
MgmtState == pending;
|
||||||
@ -2465,6 +2506,7 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData, F)
|
|||||||
handle_unacked_stanzas(_StateData, _F) ->
|
handle_unacked_stanzas(_StateData, _F) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec handle_unacked_stanzas(state()) -> ok.
|
||||||
handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData)
|
handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData)
|
||||||
when MgmtState == active;
|
when MgmtState == active;
|
||||||
MgmtState == pending;
|
MgmtState == pending;
|
||||||
@ -2537,6 +2579,7 @@ handle_unacked_stanzas(#state{mgmt_state = MgmtState} = StateData)
|
|||||||
handle_unacked_stanzas(_StateData) ->
|
handle_unacked_stanzas(_StateData) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec is_encapsulated_forward(stanza()) -> boolean().
|
||||||
is_encapsulated_forward(#message{} = Msg) ->
|
is_encapsulated_forward(#message{} = Msg) ->
|
||||||
xmpp:has_subtag(Msg, #forwarded{}) orelse
|
xmpp:has_subtag(Msg, #forwarded{}) orelse
|
||||||
xmpp:has_subtag(Msg, #carbons_sent{}) orelse
|
xmpp:has_subtag(Msg, #carbons_sent{}) orelse
|
||||||
@ -2544,6 +2587,9 @@ is_encapsulated_forward(#message{} = Msg) ->
|
|||||||
is_encapsulated_forward(_El) ->
|
is_encapsulated_forward(_El) ->
|
||||||
false.
|
false.
|
||||||
|
|
||||||
|
-spec inherit_session_state(state(), binary()) -> {ok, state()} |
|
||||||
|
{error, binary()} |
|
||||||
|
{error, binary(), non_neg_integer()}.
|
||||||
inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
|
inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
|
||||||
case jlib:base64_to_term(ResumeID) of
|
case jlib:base64_to_term(ResumeID) of
|
||||||
{term, {R, Time}} ->
|
{term, {R, Time}} ->
|
||||||
@ -2604,13 +2650,16 @@ inherit_session_state(#state{user = U, server = S} = StateData, ResumeID) ->
|
|||||||
{error, <<"Invalid 'previd' value">>}
|
{error, <<"Invalid 'previd' value">>}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec resume_session({integer(), pid()}) -> any().
|
||||||
resume_session({Time, PID}) ->
|
resume_session({Time, PID}) ->
|
||||||
(?GEN_FSM):sync_send_all_state_event(PID, {resume_session, Time}, 5000).
|
(?GEN_FSM):sync_send_all_state_event(PID, {resume_session, Time}, 5000).
|
||||||
|
|
||||||
|
-spec make_resume_id(state()) -> binary().
|
||||||
make_resume_id(StateData) ->
|
make_resume_id(StateData) ->
|
||||||
{Time, _} = StateData#state.sid,
|
{Time, _} = StateData#state.sid,
|
||||||
jlib:term_to_base64({StateData#state.resource, Time}).
|
jlib:term_to_base64({StateData#state.resource, Time}).
|
||||||
|
|
||||||
|
-spec add_resent_delay_info(state(), stanza(), erlang:timestamp()) -> stanza().
|
||||||
add_resent_delay_info(_State, #iq{} = El, _Time) ->
|
add_resent_delay_info(_State, #iq{} = El, _Time) ->
|
||||||
El;
|
El;
|
||||||
add_resent_delay_info(#state{server = From}, El, Time) ->
|
add_resent_delay_info(#state{server = From}, El, Time) ->
|
||||||
@ -2619,7 +2668,7 @@ add_resent_delay_info(#state{server = From}, El, Time) ->
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% XEP-0352
|
%%% XEP-0352
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
-spec csi_filter_stanza(state(), stanza()) -> state().
|
||||||
csi_filter_stanza(#state{csi_state = CsiState, server = Server} = StateData,
|
csi_filter_stanza(#state{csi_state = CsiState, server = Server} = StateData,
|
||||||
Stanza) ->
|
Stanza) ->
|
||||||
{StateData1, Stanzas} = ejabberd_hooks:run_fold(csi_filter_stanza, Server,
|
{StateData1, Stanzas} = ejabberd_hooks:run_fold(csi_filter_stanza, Server,
|
||||||
@ -2631,6 +2680,7 @@ csi_filter_stanza(#state{csi_state = CsiState, server = Server} = StateData,
|
|||||||
Stanzas),
|
Stanzas),
|
||||||
StateData2#state{csi_state = CsiState}.
|
StateData2#state{csi_state = CsiState}.
|
||||||
|
|
||||||
|
-spec csi_flush_queue(state()) -> state().
|
||||||
csi_flush_queue(#state{csi_state = CsiState, server = Server} = StateData) ->
|
csi_flush_queue(#state{csi_state = CsiState, server = Server} = StateData) ->
|
||||||
{StateData1, Stanzas} = ejabberd_hooks:run_fold(csi_flush_queue, Server,
|
{StateData1, Stanzas} = ejabberd_hooks:run_fold(csi_flush_queue, Server,
|
||||||
{StateData, []}, [Server]),
|
{StateData, []}, [Server]),
|
||||||
@ -2646,6 +2696,7 @@ csi_flush_queue(#state{csi_state = CsiState, server = Server} = StateData) ->
|
|||||||
|
|
||||||
%% Try to reduce the heap footprint of the four presence sets
|
%% Try to reduce the heap footprint of the four presence sets
|
||||||
%% by ensuring that we re-use strings and Jids wherever possible.
|
%% by ensuring that we re-use strings and Jids wherever possible.
|
||||||
|
-spec pack(state()) -> state().
|
||||||
pack(S = #state{pres_a = A, pres_f = F,
|
pack(S = #state{pres_a = A, pres_f = F,
|
||||||
pres_t = T}) ->
|
pres_t = T}) ->
|
||||||
{NewA, Pack2} = pack_jid_set(A, gb_trees:empty()),
|
{NewA, Pack2} = pack_jid_set(A, gb_trees:empty()),
|
||||||
@ -2682,6 +2733,7 @@ pack_string(String, Pack) ->
|
|||||||
transform_listen_option(Opt, Opts) ->
|
transform_listen_option(Opt, Opts) ->
|
||||||
[Opt|Opts].
|
[Opt|Opts].
|
||||||
|
|
||||||
|
-spec identity([{atom(), binary()}]) -> binary().
|
||||||
identity(Props) ->
|
identity(Props) ->
|
||||||
case proplists:get_value(authzid, Props, <<>>) of
|
case proplists:get_value(authzid, Props, <<>>) of
|
||||||
<<>> -> proplists:get_value(username, Props, <<>>);
|
<<>> -> proplists:get_value(username, Props, <<>>);
|
||||||
|
@ -877,7 +877,7 @@ v_db(Mod, Type) ->
|
|||||||
[] -> erlang:error(badarg)
|
[] -> erlang:error(badarg)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec default_db(binary(), module()) -> atom().
|
-spec default_db(global | binary(), module()) -> atom().
|
||||||
|
|
||||||
default_db(Host, Module) ->
|
default_db(Host, Module) ->
|
||||||
case ejabberd_config:get_option(
|
case ejabberd_config:get_option(
|
||||||
|
@ -183,14 +183,13 @@ unregister_iq_handler(Host, XMLNS) ->
|
|||||||
refresh_iq_handlers() ->
|
refresh_iq_handlers() ->
|
||||||
ejabberd_local ! refresh_iq_handlers.
|
ejabberd_local ! refresh_iq_handlers.
|
||||||
|
|
||||||
-spec bounce_resource_packet(jid(), jid(), stanza()) -> stop.
|
-spec bounce_resource_packet(jid(), jid(), stanza()) -> ok.
|
||||||
bounce_resource_packet(From, To, Packet) ->
|
bounce_resource_packet(From, To, Packet) ->
|
||||||
Lang = xmpp:get_lang(Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
Txt = <<"No available resource found">>,
|
Txt = <<"No available resource found">>,
|
||||||
Err = xmpp:make_error(Packet,
|
Err = xmpp:make_error(Packet,
|
||||||
xmpp:err_item_not_found(Txt, Lang)),
|
xmpp:err_item_not_found(Txt, Lang)),
|
||||||
ejabberd_router:route(To, From, Err),
|
ejabberd_router:route(To, From, Err).
|
||||||
stop.
|
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-record(route_multicast, {domain = <<"">> :: binary(),
|
-record(route_multicast, {domain = <<"">> :: binary() | '_',
|
||||||
pid = self() :: pid()}).
|
pid = self() :: pid()}).
|
||||||
-record(state, {}).
|
-record(state, {}).
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
connections = (?DICT):new() :: ?TDICT,
|
connections = (?DICT):new() :: ?TDICT,
|
||||||
timer = make_ref() :: reference()}).
|
timer = make_ref() :: reference()}).
|
||||||
|
|
||||||
-type state_name() :: wait_for_stream | wait_for_features | stream_established.
|
-type state_name() :: wait_for_stream | wait_for_feature_request | stream_established.
|
||||||
-type state() :: #state{}.
|
-type state() :: #state{}.
|
||||||
-type fsm_next() :: {next_state, state_name(), state()}.
|
-type fsm_next() :: {next_state, state_name(), state()}.
|
||||||
-type fsm_stop() :: {stop, normal, state()}.
|
-type fsm_stop() :: {stop, normal, state()}.
|
||||||
@ -287,7 +287,8 @@ wait_for_feature_request(#starttls{},
|
|||||||
end,
|
end,
|
||||||
TLSSocket = (StateData#state.sockmod):starttls(
|
TLSSocket = (StateData#state.sockmod):starttls(
|
||||||
Socket, TLSOpts,
|
Socket, TLSOpts,
|
||||||
fxml:element_to_binary(#starttls_proceed{})),
|
fxml:element_to_binary(
|
||||||
|
xmpp:encode(#starttls_proceed{}))),
|
||||||
{next_state, wait_for_stream,
|
{next_state, wait_for_stream,
|
||||||
StateData#state{socket = TLSSocket, streamid = new_id(),
|
StateData#state{socket = TLSSocket, streamid = new_id(),
|
||||||
tls_enabled = true, tls_options = TLSOpts}};
|
tls_enabled = true, tls_options = TLSOpts}};
|
||||||
@ -342,19 +343,17 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
|||||||
stream_established(#db_result{to = To, from = From, key = Key},
|
stream_established(#db_result{to = To, from = From, key = Key},
|
||||||
StateData) ->
|
StateData) ->
|
||||||
?DEBUG("GET KEY: ~p", [{To, From, Key}]),
|
?DEBUG("GET KEY: ~p", [{To, From, Key}]),
|
||||||
LTo = To#jid.lserver,
|
case {ejabberd_s2s:allow_host(To, From),
|
||||||
LFrom = From#jid.lserver,
|
lists:member(To, ejabberd_router:dirty_get_all_domains())} of
|
||||||
case {ejabberd_s2s:allow_host(LTo, LFrom),
|
|
||||||
lists:member(LTo, ejabberd_router:dirty_get_all_domains())} of
|
|
||||||
{true, true} ->
|
{true, true} ->
|
||||||
ejabberd_s2s_out:terminate_if_waiting_delay(LTo, LFrom),
|
ejabberd_s2s_out:terminate_if_waiting_delay(To, From),
|
||||||
ejabberd_s2s_out:start(LTo, LFrom,
|
ejabberd_s2s_out:start(To, From,
|
||||||
{verify, self(), Key,
|
{verify, self(), Key,
|
||||||
StateData#state.streamid}),
|
StateData#state.streamid}),
|
||||||
Conns = (?DICT):store({LFrom, LTo},
|
Conns = (?DICT):store({From, To},
|
||||||
wait_for_verification,
|
wait_for_verification,
|
||||||
StateData#state.connections),
|
StateData#state.connections),
|
||||||
change_shaper(StateData, LTo, jid:make(LFrom)),
|
change_shaper(StateData, To, jid:make(From)),
|
||||||
{next_state, stream_established,
|
{next_state, stream_established,
|
||||||
StateData#state{connections = Conns}};
|
StateData#state{connections = Conns}};
|
||||||
{_, false} ->
|
{_, false} ->
|
||||||
@ -367,9 +366,7 @@ stream_established(#db_result{to = To, from = From, key = Key},
|
|||||||
stream_established(#db_verify{to = To, from = From, id = Id, key = Key},
|
stream_established(#db_verify{to = To, from = From, id = Id, key = Key},
|
||||||
StateData) ->
|
StateData) ->
|
||||||
?DEBUG("VERIFY KEY: ~p", [{To, From, Id, Key}]),
|
?DEBUG("VERIFY KEY: ~p", [{To, From, Id, Key}]),
|
||||||
LTo = jid:nameprep(To),
|
Type = case ejabberd_s2s:make_key({To, From}, Id) of
|
||||||
LFrom = jid:nameprep(From),
|
|
||||||
Type = case ejabberd_s2s:make_key({LTo, LFrom}, Id) of
|
|
||||||
Key -> valid;
|
Key -> valid;
|
||||||
_ -> invalid
|
_ -> invalid
|
||||||
end,
|
end,
|
||||||
@ -412,19 +409,15 @@ stream_established({valid, From, To}, StateData) ->
|
|||||||
#db_result{from = To, to = From, type = valid}),
|
#db_result{from = To, to = From, type = valid}),
|
||||||
?INFO_MSG("Accepted s2s dialback authentication for ~s (TLS=~p)",
|
?INFO_MSG("Accepted s2s dialback authentication for ~s (TLS=~p)",
|
||||||
[From, StateData#state.tls_enabled]),
|
[From, StateData#state.tls_enabled]),
|
||||||
LFrom = jid:nameprep(From),
|
|
||||||
LTo = jid:nameprep(To),
|
|
||||||
NSD = StateData#state{connections =
|
NSD = StateData#state{connections =
|
||||||
(?DICT):store({LFrom, LTo}, established,
|
(?DICT):store({From, To}, established,
|
||||||
StateData#state.connections)},
|
StateData#state.connections)},
|
||||||
{next_state, stream_established, NSD};
|
{next_state, stream_established, NSD};
|
||||||
stream_established({invalid, From, To}, StateData) ->
|
stream_established({invalid, From, To}, StateData) ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
#db_result{from = To, to = From, type = invalid}),
|
#db_result{from = To, to = From, type = invalid}),
|
||||||
LFrom = jid:nameprep(From),
|
|
||||||
LTo = jid:nameprep(To),
|
|
||||||
NSD = StateData#state{connections =
|
NSD = StateData#state{connections =
|
||||||
(?DICT):erase({LFrom, LTo},
|
(?DICT):erase({From, To},
|
||||||
StateData#state.connections)},
|
StateData#state.connections)},
|
||||||
{next_state, stream_established, NSD};
|
{next_state, stream_established, NSD};
|
||||||
stream_established({xmlstreamend, _Name}, StateData) ->
|
stream_established({xmlstreamend, _Name}, StateData) ->
|
||||||
|
@ -832,15 +832,15 @@ send_db_request(StateData) ->
|
|||||||
{StateData#state.myname, Server},
|
{StateData#state.myname, Server},
|
||||||
StateData#state.remote_streamid),
|
StateData#state.remote_streamid),
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
#db_result{from = jid:make(StateData#state.myname),
|
#db_result{from = StateData#state.myname,
|
||||||
to = jid:make(Server),
|
to = Server,
|
||||||
key = Key1})
|
key = Key1})
|
||||||
end,
|
end,
|
||||||
case StateData#state.verify of
|
case StateData#state.verify of
|
||||||
false -> ok;
|
false -> ok;
|
||||||
{_Pid, Key2, SID} ->
|
{_Pid, Key2, SID} ->
|
||||||
send_element(StateData,
|
send_element(StateData,
|
||||||
#db_verify{from = jid:make(StateData#state.myname),
|
#db_verify{from = StateData#state.myname,
|
||||||
to = StateData#state.server,
|
to = StateData#state.server,
|
||||||
id = SID,
|
id = SID,
|
||||||
key = Key2})
|
key = Key2})
|
||||||
@ -1067,7 +1067,7 @@ get_max_retry_delay() ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%% Terminate s2s_out connections that are in state wait_before_retry
|
%% Terminate s2s_out connections that are in state wait_before_retry
|
||||||
-spec terminate_if_waiting_delay(ljid(), ljid()) -> ok.
|
-spec terminate_if_waiting_delay(binary(), binary()) -> ok.
|
||||||
terminate_if_waiting_delay(From, To) ->
|
terminate_if_waiting_delay(From, To) ->
|
||||||
FromTo = {From, To},
|
FromTo = {From, To},
|
||||||
Pids = ejabberd_s2s:get_connections_pids(FromTo),
|
Pids = ejabberd_s2s:get_connections_pids(FromTo),
|
||||||
|
@ -127,7 +127,7 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
|
|||||||
try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of
|
try xmpp:decode(#xmlel{name = Name, attrs = Attrs}) of
|
||||||
#stream_start{xmlns = ?NS_COMPONENT, to = To} when is_record(To, jid) ->
|
#stream_start{xmlns = ?NS_COMPONENT, to = To} when is_record(To, jid) ->
|
||||||
Host = To#jid.lserver,
|
Host = To#jid.lserver,
|
||||||
send_header(StateData, To),
|
send_header(StateData, Host),
|
||||||
HostOpts = case dict:is_key(Host, StateData#state.host_opts) of
|
HostOpts = case dict:is_key(Host, StateData#state.host_opts) of
|
||||||
true ->
|
true ->
|
||||||
StateData#state.host_opts;
|
StateData#state.host_opts;
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% API
|
%% API
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
-export_type([sid/0]).
|
-export_type([sid/0, info/0]).
|
||||||
|
|
||||||
start() ->
|
start() ->
|
||||||
ChildSpec = {?MODULE, {?MODULE, start_link, []},
|
ChildSpec = {?MODULE, {?MODULE, start_link, []},
|
||||||
@ -168,7 +168,7 @@ check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
|
|||||||
false -> {stop, false}
|
false -> {stop, false}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec bounce_offline_message(jid(), jid(), xmlel()) -> stop.
|
-spec bounce_offline_message(jid(), jid(), message()) -> stop.
|
||||||
|
|
||||||
bounce_offline_message(From, To, Packet) ->
|
bounce_offline_message(From, To, Packet) ->
|
||||||
Lang = xmpp:get_lang(Packet),
|
Lang = xmpp:get_lang(Packet),
|
||||||
@ -234,7 +234,7 @@ get_user_info(User, Server, Resource) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
-spec set_presence(sid(), binary(), binary(), binary(),
|
-spec set_presence(sid(), binary(), binary(), binary(),
|
||||||
prio(), xmlel(), info()) -> ok.
|
prio(), presence(), info()) -> ok.
|
||||||
|
|
||||||
set_presence(SID, User, Server, Resource, Priority,
|
set_presence(SID, User, Server, Resource, Priority,
|
||||||
Presence, Info) ->
|
Presence, Info) ->
|
||||||
@ -750,7 +750,7 @@ process_iq(From, To, #iq{type = T} = Packet) when T == get; T == set ->
|
|||||||
process_iq(_From, _To, #iq{}) ->
|
process_iq(_From, _To, #iq{}) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
-spec force_update_presence({binary(), binary()}) -> any().
|
-spec force_update_presence({binary(), binary()}) -> ok.
|
||||||
|
|
||||||
force_update_presence({LUser, LServer}) ->
|
force_update_presence({LUser, LServer}) ->
|
||||||
Mod = get_sm_backend(LServer),
|
Mod = get_sm_backend(LServer),
|
||||||
|
@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
-type socket_state() :: #socket_state{}.
|
-type socket_state() :: #socket_state{}.
|
||||||
|
|
||||||
-export_type([socket_state/0, sockmod/0]).
|
-export_type([socket/0, socket_state/0, sockmod/0]).
|
||||||
|
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
|
@ -61,6 +61,7 @@ start_link() ->
|
|||||||
gen_server:start_link({local, ?MODULE}, ?MODULE, Opts,
|
gen_server:start_link({local, ?MODULE}, ?MODULE, Opts,
|
||||||
[]).
|
[]).
|
||||||
|
|
||||||
|
-spec process_command(jid(), jid(), stanza()) -> ok.
|
||||||
process_command(From, To, Packet) ->
|
process_command(From, To, Packet) ->
|
||||||
case To of
|
case To of
|
||||||
#jid{luser = <<"">>, lresource = <<"watchdog">>} ->
|
#jid{luser = <<"">>, lresource = <<"watchdog">>} ->
|
||||||
@ -75,7 +76,7 @@ process_command(From, To, Packet) ->
|
|||||||
process_flag(priority, high),
|
process_flag(priority, high),
|
||||||
process_command1(From, To, BodyText)
|
process_command1(From, To, BodyText)
|
||||||
end),
|
end),
|
||||||
stop;
|
ok;
|
||||||
false -> ok
|
false -> ok
|
||||||
end;
|
end;
|
||||||
_ -> ok
|
_ -> ok
|
||||||
|
@ -1045,17 +1045,21 @@ process_admin(Host,
|
|||||||
process_admin(Host,
|
process_admin(Host,
|
||||||
#request{lang = Lang, auth = {_, _Auth, AJID}} =
|
#request{lang = Lang, auth = {_, _Auth, AJID}} =
|
||||||
Request) ->
|
Request) ->
|
||||||
{Hook, Opts} = case Host of
|
Res = case Host of
|
||||||
global -> {webadmin_page_main, [Request]};
|
global ->
|
||||||
Host -> {webadmin_page_host, [Host, Request]}
|
ejabberd_hooks:run_fold(
|
||||||
end,
|
webadmin_page_main, Host, [], [Request]);
|
||||||
case ejabberd_hooks:run_fold(Hook, Host, [], Opts) of
|
_ ->
|
||||||
|
ejabberd_hooks:run_fold(
|
||||||
|
webadmin_page_host, Host, [], [Host, Request])
|
||||||
|
end,
|
||||||
|
case Res of
|
||||||
[] ->
|
[] ->
|
||||||
setelement(1,
|
setelement(1,
|
||||||
make_xhtml([?XC(<<"h1">>, <<"Not Found">>)], Host, Lang,
|
make_xhtml([?XC(<<"h1">>, <<"Not Found">>)], Host, Lang,
|
||||||
AJID),
|
AJID),
|
||||||
404);
|
404);
|
||||||
Res -> make_xhtml(Res, Host, Lang, AJID)
|
_ -> make_xhtml(Res, Host, Lang, AJID)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%%==================================
|
%%%==================================
|
||||||
@ -2269,16 +2273,17 @@ get_node(global, Node, [<<"update">>], Query, Lang) ->
|
|||||||
?BR,
|
?BR,
|
||||||
?INPUTT(<<"submit">>, <<"update">>, <<"Update">>)])];
|
?INPUTT(<<"submit">>, <<"update">>, <<"Update">>)])];
|
||||||
get_node(Host, Node, NPath, Query, Lang) ->
|
get_node(Host, Node, NPath, Query, Lang) ->
|
||||||
{Hook, Opts} = case Host of
|
Res = case Host of
|
||||||
global ->
|
global ->
|
||||||
{webadmin_page_node, [Node, NPath, Query, Lang]};
|
ejabberd_hooks:run_fold(webadmin_page_node, Host, [],
|
||||||
Host ->
|
[Node, NPath, Query, Lang]);
|
||||||
{webadmin_page_hostnode,
|
_ ->
|
||||||
[Host, Node, NPath, Query, Lang]}
|
ejabberd_hooks:run_fold(webadmin_page_hostnode, Host, [],
|
||||||
end,
|
[Host, Node, NPath, Query, Lang])
|
||||||
case ejabberd_hooks:run_fold(Hook, Host, [], Opts) of
|
end,
|
||||||
|
case Res of
|
||||||
[] -> [?XC(<<"h1">>, <<"Not Found">>)];
|
[] -> [?XC(<<"h1">>, <<"Not Found">>)];
|
||||||
Res -> Res
|
_ -> Res
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%%==================================
|
%%%==================================
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
-type component() :: ejabberd_sm | ejabberd_local.
|
-type component() :: ejabberd_sm | ejabberd_local.
|
||||||
-type type() :: no_queue | one_queue | pos_integer() | parallel.
|
-type type() :: no_queue | one_queue | pos_integer() | parallel.
|
||||||
-type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel.
|
-type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel.
|
||||||
|
-export_type([opts/0]).
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% API
|
%% API
|
||||||
|
@ -378,7 +378,7 @@ db_type(Host, Module) when is_atom(Module) ->
|
|||||||
undefined
|
undefined
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec db_type(binary(), opts(), module()) -> db_type().
|
-spec db_type(global | binary(), opts(), module()) -> db_type().
|
||||||
|
|
||||||
db_type(Host, Opts, Module) ->
|
db_type(Host, Opts, Module) ->
|
||||||
case catch Module:mod_opt_type(db_type) of
|
case catch Module:mod_opt_type(db_type) of
|
||||||
|
@ -173,7 +173,9 @@ get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
|
|||||||
get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc.
|
get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc.
|
||||||
|
|
||||||
%-------------------------------------------------------------------------
|
%-------------------------------------------------------------------------
|
||||||
|
-spec get_local_features({error, error()} | {result, [binary()]} | empty,
|
||||||
|
jid(), jid(), binary(), binary()) ->
|
||||||
|
{error, error()} | {result, [binary()]} | empty.
|
||||||
get_local_features(Acc, _From, _To, <<"">>, _Lang) ->
|
get_local_features(Acc, _From, _To, <<"">>, _Lang) ->
|
||||||
Feats = case Acc of
|
Feats = case Acc of
|
||||||
{result, I} -> I;
|
{result, I} -> I;
|
||||||
@ -205,16 +207,24 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.
|
|||||||
%-------------------------------------------------------------------------
|
%-------------------------------------------------------------------------
|
||||||
|
|
||||||
process_local_iq(IQ) ->
|
process_local_iq(IQ) ->
|
||||||
process_adhoc_request(IQ, adhoc_local_commands).
|
process_adhoc_request(IQ, local).
|
||||||
|
|
||||||
process_sm_iq(IQ) ->
|
process_sm_iq(IQ) ->
|
||||||
process_adhoc_request(IQ, adhoc_sm_commands).
|
process_adhoc_request(IQ, sm).
|
||||||
|
|
||||||
process_adhoc_request(#iq{from = From, to = To,
|
process_adhoc_request(#iq{from = From, to = To,
|
||||||
type = set, lang = Lang,
|
type = set, lang = Lang,
|
||||||
sub_els = [#adhoc_command{} = SubEl]} = IQ, Hook) ->
|
sub_els = [#adhoc_command{} = SubEl]} = IQ, Type) ->
|
||||||
Host = To#jid.lserver,
|
Host = To#jid.lserver,
|
||||||
case ejabberd_hooks:run_fold(Hook, Host, empty, [From, To, SubEl]) of
|
Res = case Type of
|
||||||
|
local ->
|
||||||
|
ejabberd_hooks:run_fold(adhoc_local_commands, Host, empty,
|
||||||
|
[From, To, SubEl]);
|
||||||
|
sm ->
|
||||||
|
ejabberd_hooks:run_fold(adhoc_sm_commands, Host, empty,
|
||||||
|
[From, To, SubEl])
|
||||||
|
end,
|
||||||
|
case Res of
|
||||||
ignore ->
|
ignore ->
|
||||||
ignore;
|
ignore;
|
||||||
empty ->
|
empty ->
|
||||||
@ -228,6 +238,8 @@ process_adhoc_request(#iq{from = From, to = To,
|
|||||||
process_adhoc_request(#iq{} = IQ, _Hooks) ->
|
process_adhoc_request(#iq{} = IQ, _Hooks) ->
|
||||||
xmpp:make_error(IQ, xmpp:err_bad_request()).
|
xmpp:make_error(IQ, xmpp:err_bad_request()).
|
||||||
|
|
||||||
|
-spec ping_item(empty | {error, error()} | {result, [disco_item()]},
|
||||||
|
jid(), jid(), binary()) -> {result, [disco_item()]}.
|
||||||
ping_item(Acc, _From, #jid{server = Server} = _To,
|
ping_item(Acc, _From, #jid{server = Server} = _To,
|
||||||
Lang) ->
|
Lang) ->
|
||||||
Items = case Acc of
|
Items = case Acc of
|
||||||
@ -239,6 +251,8 @@ ping_item(Acc, _From, #jid{server = Server} = _To,
|
|||||||
name = translate:translate(Lang, <<"Ping">>)}],
|
name = translate:translate(Lang, <<"Ping">>)}],
|
||||||
{result, Items ++ Nodes}.
|
{result, Items ++ Nodes}.
|
||||||
|
|
||||||
|
-spec ping_command(adhoc_command(), jid(), jid(), adhoc_command()) ->
|
||||||
|
adhoc_command() | {error, error()}.
|
||||||
ping_command(_Acc, _From, _To,
|
ping_command(_Acc, _From, _To,
|
||||||
#adhoc_command{lang = Lang, node = <<"ping">>,
|
#adhoc_command{lang = Lang, node = <<"ping">>,
|
||||||
action = Action} = Request) ->
|
action = Action} = Request) ->
|
||||||
|
@ -130,42 +130,34 @@ stop(Host) ->
|
|||||||
{wait, Proc}.
|
{wait, Proc}.
|
||||||
|
|
||||||
%% Announcing via messages to a custom resource
|
%% Announcing via messages to a custom resource
|
||||||
|
-spec announce(jid(), jid(), stanza()) -> ok.
|
||||||
announce(From, #jid{luser = <<>>} = To, #message{} = Packet) ->
|
announce(From, #jid{luser = <<>>} = To, #message{} = Packet) ->
|
||||||
Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
|
||||||
case To#jid.lresource of
|
case To#jid.lresource of
|
||||||
<<"announce/all">> ->
|
<<"announce/all">> ->
|
||||||
Proc ! {announce_all, From, To, Packet},
|
Proc ! {announce_all, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/all-hosts/all">> ->
|
<<"announce/all-hosts/all">> ->
|
||||||
Proc ! {announce_all_hosts_all, From, To, Packet},
|
Proc ! {announce_all_hosts_all, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/online">> ->
|
<<"announce/online">> ->
|
||||||
Proc ! {announce_online, From, To, Packet},
|
Proc ! {announce_online, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/all-hosts/online">> ->
|
<<"announce/all-hosts/online">> ->
|
||||||
Proc ! {announce_all_hosts_online, From, To, Packet},
|
Proc ! {announce_all_hosts_online, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/motd">> ->
|
<<"announce/motd">> ->
|
||||||
Proc ! {announce_motd, From, To, Packet},
|
Proc ! {announce_motd, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/all-hosts/motd">> ->
|
<<"announce/all-hosts/motd">> ->
|
||||||
Proc ! {announce_all_hosts_motd, From, To, Packet},
|
Proc ! {announce_all_hosts_motd, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/motd/update">> ->
|
<<"announce/motd/update">> ->
|
||||||
Proc ! {announce_motd_update, From, To, Packet},
|
Proc ! {announce_motd_update, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/all-hosts/motd/update">> ->
|
<<"announce/all-hosts/motd/update">> ->
|
||||||
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
|
Proc ! {announce_all_hosts_motd_update, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/motd/delete">> ->
|
<<"announce/motd/delete">> ->
|
||||||
Proc ! {announce_motd_delete, From, To, Packet},
|
Proc ! {announce_motd_delete, From, To, Packet};
|
||||||
stop;
|
|
||||||
<<"announce/all-hosts/motd/delete">> ->
|
<<"announce/all-hosts/motd/delete">> ->
|
||||||
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
|
Proc ! {announce_all_hosts_motd_delete, From, To, Packet};
|
||||||
stop;
|
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end;
|
end,
|
||||||
|
ok;
|
||||||
announce(_From, _To, _Packet) ->
|
announce(_From, _To, _Packet) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
@ -344,7 +336,10 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%%-------------------------------------------------------------------------
|
%%-------------------------------------------------------------------------
|
||||||
|
-spec announce_items(empty | {error, error()} | {result, [disco_item()]},
|
||||||
|
jid(), jid(), binary()) -> {error, error()} |
|
||||||
|
{result, [disco_item()]} |
|
||||||
|
empty.
|
||||||
announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) ->
|
announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) ->
|
||||||
Access1 = get_access(LServer),
|
Access1 = get_access(LServer),
|
||||||
Nodes1 = case acl:match_rule(LServer, Access1, From) of
|
Nodes1 = case acl:match_rule(LServer, Access1, From) of
|
||||||
@ -390,7 +385,8 @@ commands_result(Allow, From, To, Request) ->
|
|||||||
announce_commands(From, To, Request)
|
announce_commands(From, To, Request)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec announce_commands(adhoc_command(), jid(), jid(), adhoc_command()) ->
|
||||||
|
adhoc_command() | {error, error()}.
|
||||||
announce_commands(Acc, From, #jid{lserver = LServer} = To,
|
announce_commands(Acc, From, #jid{lserver = LServer} = To,
|
||||||
#adhoc_command{node = Node} = Request) ->
|
#adhoc_command{node = Node} = Request) ->
|
||||||
LNode = tokenize(Node),
|
LNode = tokenize(Node),
|
||||||
@ -764,6 +760,7 @@ announce_motd_delete(LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:delete_motd(LServer).
|
Mod:delete_motd(LServer).
|
||||||
|
|
||||||
|
-spec send_motd(jid()) -> ok | {atomic, any()}.
|
||||||
send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= <<>> ->
|
send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= <<>> ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
case Mod:get_motd(LServer) of
|
case Mod:get_motd(LServer) of
|
||||||
|
@ -227,16 +227,13 @@ make_userlist(Name, List) ->
|
|||||||
NeedDb = mod_privacy:is_list_needdb(List),
|
NeedDb = mod_privacy:is_list_needdb(List),
|
||||||
#userlist{name = Name, list = List, needdb = NeedDb}.
|
#userlist{name = Name, list = List, needdb = NeedDb}.
|
||||||
|
|
||||||
-spec broadcast_list_update(binary(), binary(), binary(), userlist()) ->
|
-spec broadcast_list_update(binary(), binary(), binary(), userlist()) -> ok.
|
||||||
{broadcast,
|
|
||||||
{privacy_list, userlist(), binary() | none}}.
|
|
||||||
broadcast_list_update(LUser, LServer, Name, UserList) ->
|
broadcast_list_update(LUser, LServer, Name, UserList) ->
|
||||||
ejabberd_sm:route(jid:make(LUser, LServer, <<"">>),
|
ejabberd_sm:route(jid:make(LUser, LServer, <<"">>),
|
||||||
jid:make(LUser, LServer, <<"">>),
|
jid:make(LUser, LServer, <<"">>),
|
||||||
{broadcast, {privacy_list, UserList, Name}}).
|
{broadcast, {privacy_list, UserList, Name}}).
|
||||||
|
|
||||||
-spec broadcast_blocklist_event(binary(), binary(), block_event()) ->
|
-spec broadcast_blocklist_event(binary(), binary(), block_event()) -> ok.
|
||||||
{broadcast, {blocking, block_event()}}.
|
|
||||||
broadcast_blocklist_event(LUser, LServer, Event) ->
|
broadcast_blocklist_event(LUser, LServer, Event) ->
|
||||||
JID = jid:make(LUser, LServer, <<"">>),
|
JID = jid:make(LUser, LServer, <<"">>),
|
||||||
ejabberd_sm:route(JID, JID,
|
ejabberd_sm:route(JID, JID,
|
||||||
|
@ -161,7 +161,7 @@ caps_stream_features(Acc, MyHost) ->
|
|||||||
-spec disco_features({error, error()} | {result, [binary()]} | empty,
|
-spec disco_features({error, error()} | {result, [binary()]} | empty,
|
||||||
jid(), jid(),
|
jid(), jid(),
|
||||||
binary(), binary()) ->
|
binary(), binary()) ->
|
||||||
{error, error()} | {result, [binary()]}.
|
{error, error()} | {result, [binary()]} | empty.
|
||||||
disco_features(Acc, From, To, Node, Lang) ->
|
disco_features(Acc, From, To, Node, Lang) ->
|
||||||
case is_valid_node(Node) of
|
case is_valid_node(Node) of
|
||||||
true ->
|
true ->
|
||||||
@ -185,16 +185,18 @@ disco_identity(Acc, From, To, Node, Lang) ->
|
|||||||
Acc
|
Acc
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec disco_info([xdata()], binary(), module(),
|
-spec disco_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
|
||||||
binary(), binary()) -> [xdata()].
|
([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
|
||||||
disco_info(Acc, Host, Module, Node, Lang) ->
|
disco_info(Acc, Host, Module, Node, Lang) when is_atom(Module) ->
|
||||||
case is_valid_node(Node) of
|
case is_valid_node(Node) of
|
||||||
true ->
|
true ->
|
||||||
ejabberd_hooks:run_fold(disco_info, Host, [],
|
ejabberd_hooks:run_fold(disco_info, Host, [],
|
||||||
[Host, Module, <<"">>, Lang]);
|
[Host, Module, <<"">>, Lang]);
|
||||||
false ->
|
false ->
|
||||||
Acc
|
Acc
|
||||||
end.
|
end;
|
||||||
|
disco_info(Acc, _, _, _Node, _Lang) ->
|
||||||
|
Acc.
|
||||||
|
|
||||||
-spec c2s_presence_in(ejabberd_c2s:state(), {jid(), jid(), presence()}) ->
|
-spec c2s_presence_in(ejabberd_c2s:state(), {jid(), jid(), presence()}) ->
|
||||||
ejabberd_c2s:state().
|
ejabberd_c2s:state().
|
||||||
@ -277,6 +279,7 @@ c2s_broadcast_recipients(InAcc, Host, C2SState,
|
|||||||
end;
|
end;
|
||||||
c2s_broadcast_recipients(Acc, _, _, _, _, _) -> Acc.
|
c2s_broadcast_recipients(Acc, _, _, _, _, _) -> Acc.
|
||||||
|
|
||||||
|
-spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}].
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
@ -403,13 +406,13 @@ feature_response(_IQResult, Host, From, Caps,
|
|||||||
[_SubNode | SubNodes]) ->
|
[_SubNode | SubNodes]) ->
|
||||||
feature_request(Host, From, Caps, SubNodes).
|
feature_request(Host, From, Caps, SubNodes).
|
||||||
|
|
||||||
-spec caps_read_fun(binary(), binary()) -> function().
|
-spec caps_read_fun(binary(), {binary(), binary()}) -> function().
|
||||||
caps_read_fun(Host, Node) ->
|
caps_read_fun(Host, Node) ->
|
||||||
LServer = jid:nameprep(Host),
|
LServer = jid:nameprep(Host),
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
fun() -> Mod:caps_read(LServer, Node) end.
|
fun() -> Mod:caps_read(LServer, Node) end.
|
||||||
|
|
||||||
-spec caps_write_fun(binary(), binary(), [binary()]) -> function().
|
-spec caps_write_fun(binary(), {binary(), binary()}, [binary()]) -> function().
|
||||||
caps_write_fun(Host, Node, Features) ->
|
caps_write_fun(Host, Node, Features) ->
|
||||||
LServer = jid:nameprep(Host),
|
LServer = jid:nameprep(Host),
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
@ -437,8 +440,8 @@ make_my_disco_hash(Host) ->
|
|||||||
_Err -> <<"">>
|
_Err -> <<"">>
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec make_disco_hash(disco_info(), crypto:digest_type()) -> binary().
|
-type digest_type() :: md5 | sha | sha224 | sha256 | sha384 | sha512.
|
||||||
|
-spec make_disco_hash(disco_info(), digest_type()) -> binary().
|
||||||
make_disco_hash(DiscoInfo, Algo) ->
|
make_disco_hash(DiscoInfo, Algo) ->
|
||||||
Concat = list_to_binary([concat_identities(DiscoInfo),
|
Concat = list_to_binary([concat_identities(DiscoInfo),
|
||||||
concat_features(DiscoInfo), concat_info(DiscoInfo)]),
|
concat_features(DiscoInfo), concat_info(DiscoInfo)]),
|
||||||
@ -469,19 +472,23 @@ check_hash(Caps, DiscoInfo) ->
|
|||||||
_ -> true
|
_ -> true
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec concat_features(disco_info()) -> iolist().
|
||||||
concat_features(#disco_info{features = Features}) ->
|
concat_features(#disco_info{features = Features}) ->
|
||||||
lists:usort([[Feat, $<] || Feat <- Features]).
|
lists:usort([[Feat, $<] || Feat <- Features]).
|
||||||
|
|
||||||
|
-spec concat_identities(disco_info()) -> iolist().
|
||||||
concat_identities(#disco_info{identities = Identities}) ->
|
concat_identities(#disco_info{identities = Identities}) ->
|
||||||
lists:sort(
|
lists:sort(
|
||||||
[[Cat, $/, T, $/, Lang, $/, Name, $<] ||
|
[[Cat, $/, T, $/, Lang, $/, Name, $<] ||
|
||||||
#identity{category = Cat, type = T,
|
#identity{category = Cat, type = T,
|
||||||
lang = Lang, name = Name} <- Identities]).
|
lang = Lang, name = Name} <- Identities]).
|
||||||
|
|
||||||
|
-spec concat_info(disco_info()) -> iolist().
|
||||||
concat_info(#disco_info{xdata = Xs}) ->
|
concat_info(#disco_info{xdata = Xs}) ->
|
||||||
lists:sort(
|
lists:sort(
|
||||||
[concat_xdata_fields(Fs) || #xdata{type = result, fields = Fs} <- Xs]).
|
[concat_xdata_fields(Fs) || #xdata{type = result, fields = Fs} <- Xs]).
|
||||||
|
|
||||||
|
-spec concat_xdata_fields([xdata_field()]) -> iolist().
|
||||||
concat_xdata_fields(Fields) ->
|
concat_xdata_fields(Fields) ->
|
||||||
Form = case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, Fields) of
|
Form = case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var, Fields) of
|
||||||
#xdata_field{values = Values} -> Values;
|
#xdata_field{values = Values} -> Values;
|
||||||
@ -492,10 +499,12 @@ concat_xdata_fields(Fields) ->
|
|||||||
is_binary(Var), Var /= <<"FORM_TYPE">>],
|
is_binary(Var), Var /= <<"FORM_TYPE">>],
|
||||||
[Form, $<, lists:sort(Res)].
|
[Form, $<, lists:sort(Res)].
|
||||||
|
|
||||||
|
-spec gb_trees_fold(fun((_, _, T) -> T), T, gb_trees:tree()) -> T.
|
||||||
gb_trees_fold(F, Acc, Tree) ->
|
gb_trees_fold(F, Acc, Tree) ->
|
||||||
Iter = gb_trees:iterator(Tree),
|
Iter = gb_trees:iterator(Tree),
|
||||||
gb_trees_fold_iter(F, Acc, Iter).
|
gb_trees_fold_iter(F, Acc, Iter).
|
||||||
|
|
||||||
|
-spec gb_trees_fold_iter(fun((_, _, T) -> T), T, gb_trees:iter()) -> T.
|
||||||
gb_trees_fold_iter(F, Acc, Iter) ->
|
gb_trees_fold_iter(F, Acc, Iter) ->
|
||||||
case gb_trees:next(Iter) of
|
case gb_trees:next(Iter) of
|
||||||
{Key, Val, NewIter} ->
|
{Key, Val, NewIter} ->
|
||||||
@ -504,6 +513,7 @@ gb_trees_fold_iter(F, Acc, Iter) ->
|
|||||||
_ -> Acc
|
_ -> Acc
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec now_ts() -> integer().
|
||||||
now_ts() ->
|
now_ts() ->
|
||||||
p1_time_compat:system_time(seconds).
|
p1_time_compat:system_time(seconds).
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ send_copies(JID, To, Packet, Direction)->
|
|||||||
|
|
||||||
-spec build_forward_packet(jid(), message(), jid(), jid(), direction()) -> message().
|
-spec build_forward_packet(jid(), message(), jid(), jid(), direction()) -> message().
|
||||||
build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) ->
|
build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) ->
|
||||||
Forwarded = #forwarded{sub_els = complete_packet(JID, Msg, Direction)},
|
Forwarded = #forwarded{sub_els = [complete_packet(JID, Msg, Direction)]},
|
||||||
Carbon = case Direction of
|
Carbon = case Direction of
|
||||||
sent -> #carbons_sent{forwarded = Forwarded};
|
sent -> #carbons_sent{forwarded = Forwarded};
|
||||||
received -> #carbons_received{forwarded = Forwarded}
|
received -> #carbons_received{forwarded = Forwarded}
|
||||||
|
@ -151,12 +151,13 @@ depends(_Host, _Opts) ->
|
|||||||
%% ejabberd_hooks callbacks.
|
%% ejabberd_hooks callbacks.
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
-spec filter_presence({term(), [stanza()]}, binary(), stanza())
|
-spec filter_presence({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
|
||||||
-> {term(), [stanza()]} | {stop, {term(), [stanza()]}}.
|
-> {ejabberd_c2s:state(), [stanza()]} |
|
||||||
|
{stop, {ejabberd_c2s:state(), [stanza()]}}.
|
||||||
|
|
||||||
filter_presence({C2SState, _OutStanzas} = Acc, Host,
|
filter_presence({C2SState, _OutStanzas} = Acc, Host,
|
||||||
#presence{type = Type} = Stanza) ->
|
#presence{type = Type} = Stanza) ->
|
||||||
if Type == available, Type == unavailable ->
|
if Type == available; Type == unavailable ->
|
||||||
?DEBUG("Got availability presence stanza", []),
|
?DEBUG("Got availability presence stanza", []),
|
||||||
queue_add(presence, Stanza, Host, C2SState);
|
queue_add(presence, Stanza, Host, C2SState);
|
||||||
true ->
|
true ->
|
||||||
@ -164,8 +165,9 @@ filter_presence({C2SState, _OutStanzas} = Acc, Host,
|
|||||||
end;
|
end;
|
||||||
filter_presence(Acc, _Host, _Stanza) -> Acc.
|
filter_presence(Acc, _Host, _Stanza) -> Acc.
|
||||||
|
|
||||||
-spec filter_chat_states({term(), [stanza()]}, binary(), stanza())
|
-spec filter_chat_states({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
|
||||||
-> {term(), [stanza()]} | {stop, {term(), [stanza()]}}.
|
-> {ejabberd_c2s:state(), [stanza()]} |
|
||||||
|
{stop, {ejabberd_c2s:state(), [stanza()]}}.
|
||||||
|
|
||||||
filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
|
filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
|
||||||
#message{from = From, to = To} = Stanza) ->
|
#message{from = From, to = To} = Stanza) ->
|
||||||
@ -186,8 +188,9 @@ filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
|
|||||||
end;
|
end;
|
||||||
filter_chat_states(Acc, _Host, _Stanza) -> Acc.
|
filter_chat_states(Acc, _Host, _Stanza) -> Acc.
|
||||||
|
|
||||||
-spec filter_pep({term(), [stanza()]}, binary(), stanza())
|
-spec filter_pep({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
|
||||||
-> {term(), [stanza()]} | {stop, {term(), [stanza()]}}.
|
-> {ejabberd_c2s:state(), [stanza()]} |
|
||||||
|
{stop, {ejabberd_c2s:state(), [stanza()]}}.
|
||||||
|
|
||||||
filter_pep({C2SState, _OutStanzas} = Acc, Host, #message{} = Stanza) ->
|
filter_pep({C2SState, _OutStanzas} = Acc, Host, #message{} = Stanza) ->
|
||||||
case get_pep_node(Stanza) of
|
case get_pep_node(Stanza) of
|
||||||
@ -199,14 +202,15 @@ filter_pep({C2SState, _OutStanzas} = Acc, Host, #message{} = Stanza) ->
|
|||||||
end;
|
end;
|
||||||
filter_pep(Acc, _Host, _Stanza) -> Acc.
|
filter_pep(Acc, _Host, _Stanza) -> Acc.
|
||||||
|
|
||||||
-spec filter_other({term(), [stanza()]}, binary(), stanza())
|
-spec filter_other({ejabberd_c2s:state(), [stanza()]}, binary(), stanza())
|
||||||
-> {stop, {term(), [stanza()]}}.
|
-> {stop, {ejabberd_c2s:state(), [stanza()]}}.
|
||||||
|
|
||||||
filter_other({C2SState, _OutStanzas}, Host, Stanza) ->
|
filter_other({C2SState, _OutStanzas}, Host, Stanza) ->
|
||||||
?DEBUG("Won't add stanza to CSI queue", []),
|
?DEBUG("Won't add stanza to CSI queue", []),
|
||||||
queue_take(Stanza, Host, C2SState).
|
queue_take(Stanza, Host, C2SState).
|
||||||
|
|
||||||
-spec flush_queue({term(), [stanza()]}, binary()) -> {term(), [stanza()]}.
|
-spec flush_queue({ejabberd_c2s:state(), [stanza()]}, binary())
|
||||||
|
-> {ejabberd_c2s:state(), [stanza()]}.
|
||||||
|
|
||||||
flush_queue({C2SState, _OutStanzas}, Host) ->
|
flush_queue({C2SState, _OutStanzas}, Host) ->
|
||||||
?DEBUG("Going to flush CSI queue", []),
|
?DEBUG("Going to flush CSI queue", []),
|
||||||
@ -284,7 +288,7 @@ get_pep_node(#message{from = #jid{luser = <<>>}}) ->
|
|||||||
undefined;
|
undefined;
|
||||||
get_pep_node(#message{} = Msg) ->
|
get_pep_node(#message{} = Msg) ->
|
||||||
case xmpp:get_subtag(Msg, #pubsub_event{}) of
|
case xmpp:get_subtag(Msg, #pubsub_event{}) of
|
||||||
#pubsub_event{items = [#pubsub_event_item{node = Node}]} ->
|
#pubsub_event{items = [#pubsub_event_items{node = Node}]} ->
|
||||||
Node;
|
Node;
|
||||||
_ ->
|
_ ->
|
||||||
undefined
|
undefined
|
||||||
|
@ -270,7 +270,10 @@ get_local_features(Acc, From,
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%%%-----------------------------------------------------------------------
|
%%%-----------------------------------------------------------------------
|
||||||
|
-spec adhoc_sm_items(empty | {error, error()} | {result, [disco_item()]},
|
||||||
|
jid(), jid(), binary()) -> {error, error()} |
|
||||||
|
{result, [disco_item()]} |
|
||||||
|
empty.
|
||||||
adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To,
|
adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To,
|
||||||
Lang) ->
|
Lang) ->
|
||||||
case acl:match_rule(LServer, configure, From) of
|
case acl:match_rule(LServer, configure, From) of
|
||||||
@ -322,6 +325,10 @@ get_user_resources(User, Server) ->
|
|||||||
|
|
||||||
%%%-----------------------------------------------------------------------
|
%%%-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-spec adhoc_local_items(empty | {error, error()} | {result, [disco_item()]},
|
||||||
|
jid(), jid(), binary()) -> {error, error()} |
|
||||||
|
{result, [disco_item()]} |
|
||||||
|
empty.
|
||||||
adhoc_local_items(Acc, From,
|
adhoc_local_items(Acc, From,
|
||||||
#jid{lserver = LServer, server = Server} = To, Lang) ->
|
#jid{lserver = LServer, server = Server} = To, Lang) ->
|
||||||
case acl:match_rule(LServer, configure, From) of
|
case acl:match_rule(LServer, configure, From) of
|
||||||
@ -765,6 +772,8 @@ get_stopped_nodes(_Lang) ->
|
|||||||
allow -> adhoc_local_commands(From, To, Request)
|
allow -> adhoc_local_commands(From, To, Request)
|
||||||
end).
|
end).
|
||||||
|
|
||||||
|
-spec adhoc_local_commands(adhoc_command(), jid(), jid(), adhoc_command()) ->
|
||||||
|
adhoc_command() | {error, error()}.
|
||||||
adhoc_local_commands(Acc, From,
|
adhoc_local_commands(Acc, From,
|
||||||
#jid{lserver = LServer} = To,
|
#jid{lserver = LServer} = To,
|
||||||
#adhoc_command{node = Node, lang = Lang} = Request) ->
|
#adhoc_command{node = Node, lang = Lang} = Request) ->
|
||||||
@ -1672,8 +1681,7 @@ set_form(_From, _Host, _, _Lang, _XData) ->
|
|||||||
get_value(Field, XData) -> hd(get_values(Field, XData)).
|
get_value(Field, XData) -> hd(get_values(Field, XData)).
|
||||||
|
|
||||||
get_values(Field, XData) ->
|
get_values(Field, XData) ->
|
||||||
[_|_] = Values = xmpp_util:get_xdata_values(Field, XData),
|
xmpp_util:get_xdata_values(Field, XData).
|
||||||
Values.
|
|
||||||
|
|
||||||
search_running_node(SNode) ->
|
search_running_node(SNode) ->
|
||||||
search_running_node(SNode,
|
search_running_node(SNode,
|
||||||
@ -1723,7 +1731,7 @@ get_last_info(User, Server) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
-spec adhoc_sm_commands(adhoc_command(), jid(), jid(), adhoc_command()) -> adhoc_command().
|
||||||
adhoc_sm_commands(_Acc, From,
|
adhoc_sm_commands(_Acc, From,
|
||||||
#jid{user = User, server = Server, lserver = LServer},
|
#jid{user = User, server = Server, lserver = LServer},
|
||||||
#adhoc_command{lang = Lang, node = <<"config">>,
|
#adhoc_command{lang = Lang, node = <<"config">>,
|
||||||
|
@ -424,8 +424,9 @@ transform_module_options(Opts) ->
|
|||||||
|
|
||||||
%%% Support for: XEP-0157 Contact Addresses for XMPP Services
|
%%% Support for: XEP-0157 Contact Addresses for XMPP Services
|
||||||
|
|
||||||
-spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()].
|
-spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
|
||||||
get_info(_A, Host, Mod, Node, _Lang) when Node == <<"">> ->
|
([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
|
||||||
|
get_info(_A, Host, Mod, Node, _Lang) when is_atom(Mod), Node == <<"">> ->
|
||||||
Module = case Mod of
|
Module = case Mod of
|
||||||
undefined -> ?MODULE;
|
undefined -> ?MODULE;
|
||||||
_ -> Mod
|
_ -> Mod
|
||||||
|
@ -52,6 +52,8 @@ start_link(Host, Opts) ->
|
|||||||
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||||
gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
|
gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
|
||||||
|
|
||||||
|
-spec c2s_auth_result(boolean(), binary(), binary(),
|
||||||
|
{inet:ip_address(), non_neg_integer()}) -> ok.
|
||||||
c2s_auth_result(false, _User, LServer, {Addr, _Port}) ->
|
c2s_auth_result(false, _User, LServer, {Addr, _Port}) ->
|
||||||
case is_whitelisted(LServer, Addr) of
|
case is_whitelisted(LServer, Addr) of
|
||||||
true ->
|
true ->
|
||||||
@ -71,11 +73,15 @@ c2s_auth_result(false, _User, LServer, {Addr, _Port}) ->
|
|||||||
ets:insert(failed_auth, {Addr, N+1, UnbanTS, MaxFailures});
|
ets:insert(failed_auth, {Addr, N+1, UnbanTS, MaxFailures});
|
||||||
[] ->
|
[] ->
|
||||||
ets:insert(failed_auth, {Addr, 1, UnbanTS, MaxFailures})
|
ets:insert(failed_auth, {Addr, 1, UnbanTS, MaxFailures})
|
||||||
end
|
end,
|
||||||
|
ok
|
||||||
end;
|
end;
|
||||||
c2s_auth_result(true, _User, _Server, _AddrPort) ->
|
c2s_auth_result(true, _User, _Server, _AddrPort) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec check_bl_c2s({true, binary(), binary()} | false,
|
||||||
|
{inet:ip_address(), non_neg_integer()},
|
||||||
|
binary()) -> {stop, {true, binary(), binary()}} | false.
|
||||||
check_bl_c2s(_Acc, Addr, Lang) ->
|
check_bl_c2s(_Acc, Addr, Lang) ->
|
||||||
case ets:lookup(failed_auth, Addr) of
|
case ets:lookup(failed_auth, Addr) of
|
||||||
[{Addr, N, TS, MaxFailures}] when N >= MaxFailures ->
|
[{Addr, N, TS, MaxFailures}] when N >= MaxFailures ->
|
||||||
|
@ -553,8 +553,8 @@ process_iq(From, #iq{type = get, lang = Lang,
|
|||||||
{slot_timed_out,
|
{slot_timed_out,
|
||||||
Slot}),
|
Slot}),
|
||||||
NewState = add_slot(Slot, Size, Timer, State),
|
NewState = add_slot(Slot, Size, Timer, State),
|
||||||
Slot = mk_slot(Slot, State, XMLNS),
|
NewSlot = mk_slot(Slot, State, XMLNS),
|
||||||
{xmpp:make_iq_result(IQ, Slot), NewState};
|
{xmpp:make_iq_result(IQ, NewSlot), NewState};
|
||||||
{ok, PutURL, GetURL} ->
|
{ok, PutURL, GetURL} ->
|
||||||
Slot = mk_slot(PutURL, GetURL, XMLNS),
|
Slot = mk_slot(PutURL, GetURL, XMLNS),
|
||||||
xmpp:make_iq_result(IQ, Slot);
|
xmpp:make_iq_result(IQ, Slot);
|
||||||
@ -668,11 +668,14 @@ del_slot(Slot, #state{slots = Slots} = State) ->
|
|||||||
NewSlots = maps:remove(Slot, Slots),
|
NewSlots = maps:remove(Slot, Slots),
|
||||||
State#state{slots = NewSlots}.
|
State#state{slots = NewSlots}.
|
||||||
|
|
||||||
-spec mk_slot(slot() | binary(), state() | binary(), binary()) -> xmlel().
|
-spec mk_slot(slot(), state(), binary()) -> upload_slot();
|
||||||
|
(binary(), binary(), binary()) -> upload_slot().
|
||||||
|
|
||||||
mk_slot(Slot, #state{put_url = PutPrefix, get_url = GetPrefix}, XMLNS) ->
|
mk_slot(Slot, #state{put_url = PutPrefix, get_url = GetPrefix}, XMLNS) ->
|
||||||
PutURL = str:join([PutPrefix | Slot], <<$/>>),
|
PutURL = str:join([PutPrefix | Slot], <<$/>>),
|
||||||
GetURL = str:join([GetPrefix | Slot], <<$/>>),
|
GetURL = str:join([GetPrefix | Slot], <<$/>>),
|
||||||
|
mk_slot(PutURL, GetURL, XMLNS);
|
||||||
|
mk_slot(PutURL, GetURL, XMLNS) ->
|
||||||
#upload_slot{get = GetURL, put = PutURL, xmlns = XMLNS}.
|
#upload_slot{get = GetURL, put = PutURL, xmlns = XMLNS}.
|
||||||
|
|
||||||
-spec make_user_string(jid(), sha1 | node) -> binary().
|
-spec make_user_string(jid(), sha1 | node) -> binary().
|
||||||
|
@ -109,6 +109,10 @@ update_bl_c2s() ->
|
|||||||
%% Return: false: IP not blacklisted
|
%% Return: false: IP not blacklisted
|
||||||
%% true: IP is blacklisted
|
%% true: IP is blacklisted
|
||||||
%% IPV4 IP tuple:
|
%% IPV4 IP tuple:
|
||||||
|
-spec is_ip_in_c2s_blacklist(
|
||||||
|
{true, binary(), binary()} | false,
|
||||||
|
{inet:ip_address(), non_neg_integer()},
|
||||||
|
binary()) -> {stop, {true, binary(), binary()}} | false.
|
||||||
is_ip_in_c2s_blacklist(_Val, IP, Lang) when is_tuple(IP) ->
|
is_ip_in_c2s_blacklist(_Val, IP, Lang) when is_tuple(IP) ->
|
||||||
BinaryIP = jlib:ip_to_list(IP),
|
BinaryIP = jlib:ip_to_list(IP),
|
||||||
case ets:lookup(bl_c2s, BinaryIP) of
|
case ets:lookup(bl_c2s, BinaryIP) of
|
||||||
|
@ -66,10 +66,8 @@
|
|||||||
|
|
||||||
-callback init(binary(), gen_mod:opts()) -> any().
|
-callback init(binary(), gen_mod:opts()) -> any().
|
||||||
-callback import(binary(), #irc_custom{}) -> ok | pass.
|
-callback import(binary(), #irc_custom{}) -> ok | pass.
|
||||||
-callback get_data(binary(), binary(), {binary(), binary()}) ->
|
-callback get_data(binary(), binary(), jid()) -> error | empty | irc_data().
|
||||||
error | empty | irc_data().
|
-callback set_data(binary(), binary(), jid(), irc_data()) -> {atomic, any()}.
|
||||||
-callback set_data(binary(), binary(), {binary(), binary()}, irc_data()) ->
|
|
||||||
{atomic, any()}.
|
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% API
|
%% API
|
||||||
|
@ -584,12 +584,12 @@ handle_info({ircstring, <<$:, String/binary>>},
|
|||||||
[From, <<"MODE">>, <<$#, Chan/binary>>, <<"+o">>, Nick
|
[From, <<"MODE">>, <<$#, Chan/binary>>, <<"+o">>, Nick
|
||||||
| _] ->
|
| _] ->
|
||||||
process_mode_o(StateData, Chan, From, Nick,
|
process_mode_o(StateData, Chan, From, Nick,
|
||||||
<<"admin">>, <<"moderator">>),
|
admin, moderator),
|
||||||
StateData;
|
StateData;
|
||||||
[From, <<"MODE">>, <<$#, Chan/binary>>, <<"-o">>, Nick
|
[From, <<"MODE">>, <<$#, Chan/binary>>, <<"-o">>, Nick
|
||||||
| _] ->
|
| _] ->
|
||||||
process_mode_o(StateData, Chan, From, Nick,
|
process_mode_o(StateData, Chan, From, Nick,
|
||||||
<<"member">>, <<"participant">>),
|
member, participant),
|
||||||
StateData;
|
StateData;
|
||||||
[From, <<"KICK">>, <<$#, Chan/binary>>, Nick | _] ->
|
[From, <<"KICK">>, <<$#, Chan/binary>>, Nick | _] ->
|
||||||
process_kick(StateData, Chan, From, Nick, String),
|
process_kick(StateData, Chan, From, Nick, String),
|
||||||
@ -756,16 +756,16 @@ process_channel_list_user(StateData, Chan, User) ->
|
|||||||
end,
|
end,
|
||||||
{User2, Affiliation, Role} = case User1 of
|
{User2, Affiliation, Role} = case User1 of
|
||||||
<<$@, U2/binary>> ->
|
<<$@, U2/binary>> ->
|
||||||
{U2, <<"admin">>, <<"moderator">>};
|
{U2, admin, moderator};
|
||||||
<<$+, U2/binary>> ->
|
<<$+, U2/binary>> ->
|
||||||
{U2, <<"member">>, <<"participant">>};
|
{U2, member, participant};
|
||||||
<<$%, U2/binary>> ->
|
<<$%, U2/binary>> ->
|
||||||
{U2, <<"admin">>, <<"moderator">>};
|
{U2, admin, moderator};
|
||||||
<<$&, U2/binary>> ->
|
<<$&, U2/binary>> ->
|
||||||
{U2, <<"admin">>, <<"moderator">>};
|
{U2, admin, moderator};
|
||||||
<<$~, U2/binary>> ->
|
<<$~, U2/binary>> ->
|
||||||
{U2, <<"admin">>, <<"moderator">>};
|
{U2, admin, moderator};
|
||||||
_ -> {User1, <<"member">>, <<"participant">>}
|
_ -> {User1, member, participant}
|
||||||
end,
|
end,
|
||||||
ejabberd_router:route(
|
ejabberd_router:route(
|
||||||
jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
|
jid:make(iolist_to_binary([Chan, <<"%">>, StateData#state.server]),
|
||||||
@ -1157,8 +1157,6 @@ remove_element(E, Set) ->
|
|||||||
iq_admin(StateData, Channel, From, To,
|
iq_admin(StateData, Channel, From, To,
|
||||||
#iq{type = Type, sub_els = [SubEl]} = IQ) ->
|
#iq{type = Type, sub_els = [SubEl]} = IQ) ->
|
||||||
try process_iq_admin(StateData, Channel, Type, SubEl) of
|
try process_iq_admin(StateData, Channel, Type, SubEl) of
|
||||||
ignore ->
|
|
||||||
ignore;
|
|
||||||
{result, Result} ->
|
{result, Result} ->
|
||||||
ejabberd_router:route(To, From, xmpp:make_iq_result(IQ, Result));
|
ejabberd_router:route(To, From, xmpp:make_iq_result(IQ, Result));
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
|
@ -175,17 +175,21 @@ stop(Host) ->
|
|||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> ok.
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:remove_user(LUser, LServer).
|
Mod:remove_user(LUser, LServer),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
-spec remove_room(binary(), binary(), binary()) -> ok.
|
||||||
remove_room(LServer, Name, Host) ->
|
remove_room(LServer, Name, Host) ->
|
||||||
LName = jid:nodeprep(Name),
|
LName = jid:nodeprep(Name),
|
||||||
LHost = jid:nameprep(Host),
|
LHost = jid:nameprep(Host),
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:remove_room(LServer, LName, LHost).
|
Mod:remove_room(LServer, LName, LHost),
|
||||||
|
ok.
|
||||||
|
|
||||||
get_room_config(X, RoomState, _From, Lang) ->
|
get_room_config(X, RoomState, _From, Lang) ->
|
||||||
Config = RoomState#state.config,
|
Config = RoomState#state.config,
|
||||||
@ -621,9 +625,7 @@ should_archive_muc(#message{type = groupchat,
|
|||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
true
|
true
|
||||||
end;
|
end
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end;
|
end;
|
||||||
should_archive_muc(_) ->
|
should_archive_muc(_) ->
|
||||||
false.
|
false.
|
||||||
|
@ -31,13 +31,7 @@
|
|||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("jid.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-define(HOOKS, [offline_message_hook,
|
|
||||||
sm_register_connection_hook, sm_remove_connection_hook,
|
|
||||||
user_send_packet, user_receive_packet,
|
|
||||||
s2s_send_packet, s2s_receive_packet,
|
|
||||||
remove_user, register_user]).
|
|
||||||
|
|
||||||
-export([start/2, stop/1, send_metrics/4, opt_type/1, mod_opt_type/1,
|
-export([start/2, stop/1, send_metrics/4, opt_type/1, mod_opt_type/1,
|
||||||
depends/2]).
|
depends/2]).
|
||||||
@ -53,12 +47,26 @@
|
|||||||
%%====================================================================
|
%%====================================================================
|
||||||
|
|
||||||
start(Host, _Opts) ->
|
start(Host, _Opts) ->
|
||||||
[ejabberd_hooks:add(Hook, Host, ?MODULE, Hook, 20)
|
ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, offline_message_hook, 20),
|
||||||
|| Hook <- ?HOOKS].
|
ejabberd_hooks:add(sm_register_connection_hook, Host, ?MODULE, sm_register_connection_hook, 20),
|
||||||
|
ejabberd_hooks:add(sm_remove_connection_hook, Host, ?MODULE, sm_remove_connection_hook, 20),
|
||||||
|
ejabberd_hooks:add(user_send_packet, Host, ?MODULE, user_send_packet, 20),
|
||||||
|
ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, user_receive_packet, 20),
|
||||||
|
ejabberd_hooks:add(s2s_send_packet, Host, ?MODULE, s2s_send_packet, 20),
|
||||||
|
ejabberd_hooks:add(s2s_receive_packet, Host, ?MODULE, s2s_receive_packet, 20),
|
||||||
|
ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 20),
|
||||||
|
ejabberd_hooks:add(register_user, Host, ?MODULE, register_user, 20).
|
||||||
|
|
||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
[ejabberd_hooks:delete(Hook, Host, ?MODULE, Hook, 20)
|
ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, offline_message_hook, 20),
|
||||||
|| Hook <- ?HOOKS].
|
ejabberd_hooks:delete(sm_register_connection_hook, Host, ?MODULE, sm_register_connection_hook, 20),
|
||||||
|
ejabberd_hooks:delete(sm_remove_connection_hook, Host, ?MODULE, sm_remove_connection_hook, 20),
|
||||||
|
ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, user_send_packet, 20),
|
||||||
|
ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE, user_receive_packet, 20),
|
||||||
|
ejabberd_hooks:delete(s2s_send_packet, Host, ?MODULE, s2s_send_packet, 20),
|
||||||
|
ejabberd_hooks:delete(s2s_receive_packet, Host, ?MODULE, s2s_receive_packet, 20),
|
||||||
|
ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 20),
|
||||||
|
ejabberd_hooks:delete(register_user, Host, ?MODULE, register_user, 20).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
@ -66,12 +74,15 @@ depends(_Host, _Opts) ->
|
|||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% Hooks handlers
|
%% Hooks handlers
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
|
-spec offline_message_hook(jid(), jid(), message()) -> any().
|
||||||
offline_message_hook(_From, #jid{lserver=LServer}, _Packet) ->
|
offline_message_hook(_From, #jid{lserver=LServer}, _Packet) ->
|
||||||
push(LServer, offline_message).
|
push(LServer, offline_message).
|
||||||
|
|
||||||
|
-spec sm_register_connection_hook(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> any().
|
||||||
sm_register_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
|
sm_register_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
|
||||||
push(LServer, sm_register_connection).
|
push(LServer, sm_register_connection).
|
||||||
|
|
||||||
|
-spec sm_remove_connection_hook(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> any().
|
||||||
sm_remove_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
|
sm_remove_connection_hook(_SID, #jid{lserver=LServer}, _Info) ->
|
||||||
push(LServer, sm_remove_connection).
|
push(LServer, sm_remove_connection).
|
||||||
|
|
||||||
@ -82,13 +93,19 @@ user_receive_packet(Packet, _C2SState, _JID, _From, #jid{lserver=LServer}) ->
|
|||||||
push(LServer, user_receive_packet),
|
push(LServer, user_receive_packet),
|
||||||
Packet.
|
Packet.
|
||||||
|
|
||||||
|
-spec s2s_send_packet(jid(), jid(), stanza()) -> any().
|
||||||
s2s_send_packet(#jid{lserver=LServer}, _To, _Packet) ->
|
s2s_send_packet(#jid{lserver=LServer}, _To, _Packet) ->
|
||||||
push(LServer, s2s_send_packet).
|
push(LServer, s2s_send_packet).
|
||||||
|
|
||||||
|
-spec s2s_receive_packet(jid(), jid(), stanza()) -> any().
|
||||||
s2s_receive_packet(_From, #jid{lserver=LServer}, _Packet) ->
|
s2s_receive_packet(_From, #jid{lserver=LServer}, _Packet) ->
|
||||||
push(LServer, s2s_receive_packet).
|
push(LServer, s2s_receive_packet).
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> any().
|
||||||
remove_user(_User, Server) ->
|
remove_user(_User, Server) ->
|
||||||
push(jid:nameprep(Server), remove_user).
|
push(jid:nameprep(Server), remove_user).
|
||||||
|
|
||||||
|
-spec register_user(binary(), binary()) -> any().
|
||||||
register_user(_User, Server) ->
|
register_user(_User, Server) ->
|
||||||
push(jid:nameprep(Server), register_user).
|
push(jid:nameprep(Server), register_user).
|
||||||
|
|
||||||
|
@ -52,6 +52,8 @@ stop(Host) ->
|
|||||||
supervisor:delete_child(ejabberd_sup, Proc),
|
supervisor:delete_child(ejabberd_sup, Proc),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec disco_features({error, error()} | {result, [binary()]} | empty,
|
||||||
|
jid(), jid(), binary(), binary()) -> {result, [binary()]}.
|
||||||
disco_features(_Acc, _From, _To, _Node, _Lang) ->
|
disco_features(_Acc, _From, _To, _Node, _Lang) ->
|
||||||
{result, [?NS_MIX_0]}.
|
{result, [?NS_MIX_0]}.
|
||||||
|
|
||||||
@ -69,6 +71,8 @@ disco_identity(Acc, _From, _To, _Node, _Lang) ->
|
|||||||
Acc ++ [#identity{category = <<"conference">>,
|
Acc ++ [#identity{category = <<"conference">>,
|
||||||
type = <<"mix">>}].
|
type = <<"mix">>}].
|
||||||
|
|
||||||
|
-spec disco_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
|
||||||
|
([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
|
||||||
disco_info(_Acc, _From, To, _Node, _Lang) when is_atom(To) ->
|
disco_info(_Acc, _From, To, _Node, _Lang) when is_atom(To) ->
|
||||||
[#xdata{type = result,
|
[#xdata{type = result,
|
||||||
fields = [#xdata_field{var = <<"FORM_TYPE">>,
|
fields = [#xdata_field{var = <<"FORM_TYPE">>,
|
||||||
|
@ -3317,28 +3317,34 @@ set_config(#xdata{fields = Fields}, StateData, Lang) ->
|
|||||||
Err -> Err
|
Err -> Err
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
get_config_opt_name(Pos) ->
|
||||||
|
Fs = [config|record_info(fields, config)],
|
||||||
|
lists:nth(Pos, Fs).
|
||||||
|
|
||||||
-define(SET_BOOL_XOPT(Opt, Val),
|
-define(SET_BOOL_XOPT(Opt, Val),
|
||||||
case Val of
|
case Val of
|
||||||
<<"0">> ->
|
<<"0">> ->
|
||||||
set_xoption(Opts, Config#config{Opt = false}, ServerHost, Lang);
|
set_xoption(Opts, setelement(Opt, Config, false), ServerHost, Lang);
|
||||||
<<"false">> ->
|
<<"false">> ->
|
||||||
set_xoption(Opts, Config#config{Opt = false}, ServerHost, Lang);
|
set_xoption(Opts, setelement(Opt, Config, false), ServerHost, Lang);
|
||||||
<<"1">> -> set_xoption(Opts, Config#config{Opt = true}, ServerHost, Lang);
|
<<"1">> -> set_xoption(Opts, setelement(Opt, Config, true), ServerHost, Lang);
|
||||||
<<"true">> ->
|
<<"true">> ->
|
||||||
set_xoption(Opts, Config#config{Opt = true}, ServerHost, Lang);
|
set_xoption(Opts, setelement(Opt, Config, true), ServerHost, Lang);
|
||||||
_ ->
|
_ ->
|
||||||
Txt = <<"Value of '~s' should be boolean">>,
|
Txt = <<"Value of '~s' should be boolean">>,
|
||||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
OptName = get_config_opt_name(Opt),
|
||||||
|
ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])),
|
||||||
{error, xmpp:err_bad_request(ErrTxt, Lang)}
|
{error, xmpp:err_bad_request(ErrTxt, Lang)}
|
||||||
end).
|
end).
|
||||||
|
|
||||||
-define(SET_NAT_XOPT(Opt, Val),
|
-define(SET_NAT_XOPT(Opt, Val),
|
||||||
case catch binary_to_integer(Val) of
|
case catch binary_to_integer(Val) of
|
||||||
I when is_integer(I), I > 0 ->
|
I when is_integer(I), I > 0 ->
|
||||||
set_xoption(Opts, Config#config{Opt = I}, ServerHost, Lang);
|
set_xoption(Opts, setelement(Opt, Config, I), ServerHost, Lang);
|
||||||
_ ->
|
_ ->
|
||||||
Txt = <<"Value of '~s' should be integer">>,
|
Txt = <<"Value of '~s' should be integer">>,
|
||||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
OptName = get_config_opt_name(Opt),
|
||||||
|
ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])),
|
||||||
{error, xmpp:err_bad_request(ErrTxt, Lang)}
|
{error, xmpp:err_bad_request(ErrTxt, Lang)}
|
||||||
end).
|
end).
|
||||||
|
|
||||||
@ -3349,10 +3355,11 @@ set_config(#xdata{fields = Fields}, StateData, Lang) ->
|
|||||||
[Val] -> Val;
|
[Val] -> Val;
|
||||||
_ when is_atom(Vals) -> Vals
|
_ when is_atom(Vals) -> Vals
|
||||||
end,
|
end,
|
||||||
set_xoption(Opts, Config#config{Opt = V}, ServerHost, Lang)
|
set_xoption(Opts, setelement(Opt, Config, V), ServerHost, Lang)
|
||||||
catch _:_ ->
|
catch _:_ ->
|
||||||
Txt = <<"Incorrect value of option '~s'">>,
|
Txt = <<"Incorrect value of option '~s'">>,
|
||||||
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
|
OptName = get_config_opt_name(Opt),
|
||||||
|
ErrTxt = iolist_to_binary(io_lib:format(Txt, [OptName])),
|
||||||
{error, xmpp:err_bad_request(ErrTxt, Lang)}
|
{error, xmpp:err_bad_request(ErrTxt, Lang)}
|
||||||
end).
|
end).
|
||||||
|
|
||||||
@ -3366,7 +3373,7 @@ set_config(#xdata{fields = Fields}, StateData, Lang) ->
|
|||||||
(_, Set1) -> Set1
|
(_, Set1) -> Set1
|
||||||
end,
|
end,
|
||||||
(?SETS):empty(), Vals),
|
(?SETS):empty(), Vals),
|
||||||
set_xoption(Opts, Config#config{Opt = Set}, ServerHost, Lang)
|
set_xoption(Opts, setelement(Opt, Config, Set), ServerHost, Lang)
|
||||||
end).
|
end).
|
||||||
|
|
||||||
-spec set_xoption([{binary(), [binary()]}], #config{},
|
-spec set_xoption([{binary(), [binary()]}], #config{},
|
||||||
@ -3375,35 +3382,35 @@ set_xoption([], Config, _ServerHost, _Lang) -> Config;
|
|||||||
set_xoption([{<<"muc#roomconfig_roomname">>, Vals}
|
set_xoption([{<<"muc#roomconfig_roomname">>, Vals}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_STRING_XOPT(title, Vals);
|
?SET_STRING_XOPT(#config.title, Vals);
|
||||||
set_xoption([{<<"muc#roomconfig_roomdesc">>, Vals}
|
set_xoption([{<<"muc#roomconfig_roomdesc">>, Vals}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_STRING_XOPT(description, Vals);
|
?SET_STRING_XOPT(#config.description, Vals);
|
||||||
set_xoption([{<<"muc#roomconfig_changesubject">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_changesubject">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_change_subj, Val);
|
?SET_BOOL_XOPT(#config.allow_change_subj, Val);
|
||||||
set_xoption([{<<"allow_query_users">>, [Val]} | Opts],
|
set_xoption([{<<"allow_query_users">>, [Val]} | Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_query_users, Val);
|
?SET_BOOL_XOPT(#config.allow_query_users, Val);
|
||||||
set_xoption([{<<"allow_private_messages">>, [Val]}
|
set_xoption([{<<"allow_private_messages">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_private_messages, Val);
|
?SET_BOOL_XOPT(#config.allow_private_messages, Val);
|
||||||
set_xoption([{<<"allow_private_messages_from_visitors">>,
|
set_xoption([{<<"allow_private_messages_from_visitors">>,
|
||||||
[Val]}
|
[Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
case Val of
|
case Val of
|
||||||
<<"anyone">> ->
|
<<"anyone">> ->
|
||||||
?SET_STRING_XOPT(allow_private_messages_from_visitors,
|
?SET_STRING_XOPT(#config.allow_private_messages_from_visitors,
|
||||||
anyone);
|
anyone);
|
||||||
<<"moderators">> ->
|
<<"moderators">> ->
|
||||||
?SET_STRING_XOPT(allow_private_messages_from_visitors,
|
?SET_STRING_XOPT(#config.allow_private_messages_from_visitors,
|
||||||
moderators);
|
moderators);
|
||||||
<<"nobody">> ->
|
<<"nobody">> ->
|
||||||
?SET_STRING_XOPT(allow_private_messages_from_visitors,
|
?SET_STRING_XOPT(#config.allow_private_messages_from_visitors,
|
||||||
nobody);
|
nobody);
|
||||||
_ ->
|
_ ->
|
||||||
Txt = <<"Value of 'allow_private_messages_from_visitors' "
|
Txt = <<"Value of 'allow_private_messages_from_visitors' "
|
||||||
@ -3414,58 +3421,58 @@ set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>,
|
|||||||
[Val]}
|
[Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_visitor_status, Val);
|
?SET_BOOL_XOPT(#config.allow_visitor_status, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_allowvisitornickchange">>,
|
set_xoption([{<<"muc#roomconfig_allowvisitornickchange">>,
|
||||||
[Val]}
|
[Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_visitor_nickchange, Val);
|
?SET_BOOL_XOPT(#config.allow_visitor_nickchange, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_publicroom">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_publicroom">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(public, Val);
|
?SET_BOOL_XOPT(#config.public, Val);
|
||||||
set_xoption([{<<"public_list">>, [Val]} | Opts],
|
set_xoption([{<<"public_list">>, [Val]} | Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(public_list, Val);
|
?SET_BOOL_XOPT(#config.public_list, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_persistentroom">>,
|
set_xoption([{<<"muc#roomconfig_persistentroom">>,
|
||||||
[Val]}
|
[Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(persistent, Val);
|
?SET_BOOL_XOPT(#config.persistent, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_moderatedroom">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_moderatedroom">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(moderated, Val);
|
?SET_BOOL_XOPT(#config.moderated, Val);
|
||||||
set_xoption([{<<"members_by_default">>, [Val]} | Opts],
|
set_xoption([{<<"members_by_default">>, [Val]} | Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(members_by_default, Val);
|
?SET_BOOL_XOPT(#config.members_by_default, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_membersonly">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_membersonly">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(members_only, Val);
|
?SET_BOOL_XOPT(#config.members_only, Val);
|
||||||
set_xoption([{<<"captcha_protected">>, [Val]} | Opts],
|
set_xoption([{<<"captcha_protected">>, [Val]} | Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(captcha_protected, Val);
|
?SET_BOOL_XOPT(#config.captcha_protected, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_allowinvites">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_allowinvites">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_user_invites, Val);
|
?SET_BOOL_XOPT(#config.allow_user_invites, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_allow_subscription">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_allow_subscription">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_subscription, Val);
|
?SET_BOOL_XOPT(#config.allow_subscription, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_passwordprotectedroom">>,
|
set_xoption([{<<"muc#roomconfig_passwordprotectedroom">>,
|
||||||
[Val]}
|
[Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(password_protected, Val);
|
?SET_BOOL_XOPT(#config.password_protected, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_roomsecret">>, Vals}
|
set_xoption([{<<"muc#roomconfig_roomsecret">>, Vals}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_STRING_XOPT(password, Vals);
|
?SET_STRING_XOPT(#config.password, Vals);
|
||||||
set_xoption([{<<"anonymous">>, [Val]} | Opts],
|
set_xoption([{<<"anonymous">>, [Val]} | Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(anonymous, Val);
|
?SET_BOOL_XOPT(#config.anonymous, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts],
|
set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
Roles =
|
Roles =
|
||||||
@ -3496,21 +3503,21 @@ set_xoption([{<<"muc#roomconfig_allowvoicerequests">>,
|
|||||||
[Val]}
|
[Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(allow_voice_requests, Val);
|
?SET_BOOL_XOPT(#config.allow_voice_requests, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_voicerequestmininterval">>,
|
set_xoption([{<<"muc#roomconfig_voicerequestmininterval">>,
|
||||||
[Val]}
|
[Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_NAT_XOPT(voice_request_min_interval, Val);
|
?SET_NAT_XOPT(#config.voice_request_min_interval, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_whois">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_whois">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
case Val of
|
case Val of
|
||||||
<<"moderators">> ->
|
<<"moderators">> ->
|
||||||
?SET_BOOL_XOPT(anonymous,
|
?SET_BOOL_XOPT(#config.anonymous,
|
||||||
(iolist_to_binary(integer_to_list(1))));
|
(iolist_to_binary(integer_to_list(1))));
|
||||||
<<"anyone">> ->
|
<<"anyone">> ->
|
||||||
?SET_BOOL_XOPT(anonymous,
|
?SET_BOOL_XOPT(#config.anonymous,
|
||||||
(iolist_to_binary(integer_to_list(0))));
|
(iolist_to_binary(integer_to_list(0))));
|
||||||
_ ->
|
_ ->
|
||||||
Txt = <<"Value of 'muc#roomconfig_whois' should be "
|
Txt = <<"Value of 'muc#roomconfig_whois' should be "
|
||||||
@ -3521,19 +3528,19 @@ set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]}
|
|||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
case Val of
|
case Val of
|
||||||
<<"none">> -> ?SET_STRING_XOPT(max_users, none);
|
<<"none">> -> ?SET_STRING_XOPT(#config.max_users, none);
|
||||||
_ -> ?SET_NAT_XOPT(max_users, Val)
|
_ -> ?SET_NAT_XOPT(#config.max_users, Val)
|
||||||
end;
|
end;
|
||||||
set_xoption([{<<"muc#roomconfig_enablelogging">>, [Val]}
|
set_xoption([{<<"muc#roomconfig_enablelogging">>, [Val]}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
?SET_BOOL_XOPT(logging, Val);
|
?SET_BOOL_XOPT(#config.logging, Val);
|
||||||
set_xoption([{<<"muc#roomconfig_captcha_whitelist">>,
|
set_xoption([{<<"muc#roomconfig_captcha_whitelist">>,
|
||||||
Vals}
|
Vals}
|
||||||
| Opts],
|
| Opts],
|
||||||
Config, ServerHost, Lang) ->
|
Config, ServerHost, Lang) ->
|
||||||
JIDs = [jid:from_string(Val) || Val <- Vals],
|
JIDs = [jid:from_string(Val) || Val <- Vals],
|
||||||
?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs);
|
?SET_JIDMULTI_XOPT(#config.captcha_whitelist, JIDs);
|
||||||
set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config, ServerHost, Lang) ->
|
set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config, ServerHost, Lang) ->
|
||||||
set_xoption(Opts, Config, ServerHost, Lang);
|
set_xoption(Opts, Config, ServerHost, Lang);
|
||||||
set_xoption([{Opt, Vals} | Opts], Config, ServerHost, Lang) ->
|
set_xoption([{Opt, Vals} | Opts], Config, ServerHost, Lang) ->
|
||||||
@ -3752,7 +3759,8 @@ set_opts([{Opt, Val} | Opts], StateData) ->
|
|||||||
end,
|
end,
|
||||||
set_opts(Opts, NSD).
|
set_opts(Opts, NSD).
|
||||||
|
|
||||||
-define(MAKE_CONFIG_OPT(Opt), {Opt, Config#config.Opt}).
|
-define(MAKE_CONFIG_OPT(Opt),
|
||||||
|
{get_config_opt_name(Opt), element(Opt, Config)}).
|
||||||
|
|
||||||
-spec make_opts(state()) -> [{atom(), any()}].
|
-spec make_opts(state()) -> [{atom(), any()}].
|
||||||
make_opts(StateData) ->
|
make_opts(StateData) ->
|
||||||
@ -3764,27 +3772,27 @@ make_opts(StateData) ->
|
|||||||
(_, _, Acc) ->
|
(_, _, Acc) ->
|
||||||
Acc
|
Acc
|
||||||
end, [], StateData#state.users),
|
end, [], StateData#state.users),
|
||||||
[?MAKE_CONFIG_OPT(title), ?MAKE_CONFIG_OPT(description),
|
[?MAKE_CONFIG_OPT(#config.title), ?MAKE_CONFIG_OPT(#config.description),
|
||||||
?MAKE_CONFIG_OPT(allow_change_subj),
|
?MAKE_CONFIG_OPT(#config.allow_change_subj),
|
||||||
?MAKE_CONFIG_OPT(allow_query_users),
|
?MAKE_CONFIG_OPT(#config.allow_query_users),
|
||||||
?MAKE_CONFIG_OPT(allow_private_messages),
|
?MAKE_CONFIG_OPT(#config.allow_private_messages),
|
||||||
?MAKE_CONFIG_OPT(allow_private_messages_from_visitors),
|
?MAKE_CONFIG_OPT(#config.allow_private_messages_from_visitors),
|
||||||
?MAKE_CONFIG_OPT(allow_visitor_status),
|
?MAKE_CONFIG_OPT(#config.allow_visitor_status),
|
||||||
?MAKE_CONFIG_OPT(allow_visitor_nickchange),
|
?MAKE_CONFIG_OPT(#config.allow_visitor_nickchange),
|
||||||
?MAKE_CONFIG_OPT(public), ?MAKE_CONFIG_OPT(public_list),
|
?MAKE_CONFIG_OPT(#config.public), ?MAKE_CONFIG_OPT(#config.public_list),
|
||||||
?MAKE_CONFIG_OPT(persistent),
|
?MAKE_CONFIG_OPT(#config.persistent),
|
||||||
?MAKE_CONFIG_OPT(moderated),
|
?MAKE_CONFIG_OPT(#config.moderated),
|
||||||
?MAKE_CONFIG_OPT(members_by_default),
|
?MAKE_CONFIG_OPT(#config.members_by_default),
|
||||||
?MAKE_CONFIG_OPT(members_only),
|
?MAKE_CONFIG_OPT(#config.members_only),
|
||||||
?MAKE_CONFIG_OPT(allow_user_invites),
|
?MAKE_CONFIG_OPT(#config.allow_user_invites),
|
||||||
?MAKE_CONFIG_OPT(password_protected),
|
?MAKE_CONFIG_OPT(#config.password_protected),
|
||||||
?MAKE_CONFIG_OPT(captcha_protected),
|
?MAKE_CONFIG_OPT(#config.captcha_protected),
|
||||||
?MAKE_CONFIG_OPT(password), ?MAKE_CONFIG_OPT(anonymous),
|
?MAKE_CONFIG_OPT(#config.password), ?MAKE_CONFIG_OPT(#config.anonymous),
|
||||||
?MAKE_CONFIG_OPT(logging), ?MAKE_CONFIG_OPT(max_users),
|
?MAKE_CONFIG_OPT(#config.logging), ?MAKE_CONFIG_OPT(#config.max_users),
|
||||||
?MAKE_CONFIG_OPT(allow_voice_requests),
|
?MAKE_CONFIG_OPT(#config.allow_voice_requests),
|
||||||
?MAKE_CONFIG_OPT(mam),
|
?MAKE_CONFIG_OPT(#config.mam),
|
||||||
?MAKE_CONFIG_OPT(voice_request_min_interval),
|
?MAKE_CONFIG_OPT(#config.voice_request_min_interval),
|
||||||
?MAKE_CONFIG_OPT(vcard),
|
?MAKE_CONFIG_OPT(#config.vcard),
|
||||||
{captcha_whitelist,
|
{captcha_whitelist,
|
||||||
(?SETS):to_list((StateData#state.config)#config.captcha_whitelist)},
|
(?SETS):to_list((StateData#state.config)#config.captcha_whitelist)},
|
||||||
{affiliations,
|
{affiliations,
|
||||||
|
@ -297,7 +297,8 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID,
|
|||||||
get_sm_items(Acc, _From, _To, _Node, _Lang) ->
|
get_sm_items(Acc, _From, _To, _Node, _Lang) ->
|
||||||
Acc.
|
Acc.
|
||||||
|
|
||||||
-spec get_info([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
|
-spec get_info([xdata()], binary(), module(), binary(), binary()) -> [xdata()];
|
||||||
|
([xdata()], jid(), jid(), binary(), binary()) -> [xdata()].
|
||||||
get_info(_Acc, #jid{luser = U, lserver = S, lresource = R},
|
get_info(_Acc, #jid{luser = U, lserver = S, lresource = R},
|
||||||
#jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) ->
|
#jid{luser = U, lserver = S}, ?NS_FLEX_OFFLINE, _Lang) ->
|
||||||
N = jlib:integer_to_binary(count_offline_messages(U, S)),
|
N = jlib:integer_to_binary(count_offline_messages(U, S)),
|
||||||
@ -570,11 +571,13 @@ remove_old_messages(Days, Server) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:remove_old_messages(Days, LServer).
|
Mod:remove_old_messages(Days, LServer).
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> ok.
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:remove_user(LUser, LServer).
|
Mod:remove_user(LUser, LServer),
|
||||||
|
ok.
|
||||||
|
|
||||||
%% Helper functions:
|
%% Helper functions:
|
||||||
|
|
||||||
|
@ -207,11 +207,11 @@ iq_ping(#iq{lang = Lang} = IQ) ->
|
|||||||
Txt = <<"Ping query is incorrect">>,
|
Txt = <<"Ping query is incorrect">>,
|
||||||
xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)).
|
xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)).
|
||||||
|
|
||||||
-spec user_online(ejabberd_sm:sid(), jid(), any()) -> ok.
|
-spec user_online(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
|
||||||
user_online(_SID, JID, _Info) ->
|
user_online(_SID, JID, _Info) ->
|
||||||
start_ping(JID#jid.lserver, JID).
|
start_ping(JID#jid.lserver, JID).
|
||||||
|
|
||||||
-spec user_offline(ejabberd_sm:sid(), jid(), any()) -> ok.
|
-spec user_offline(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
|
||||||
user_offline(_SID, JID, _Info) ->
|
user_offline(_SID, JID, _Info) ->
|
||||||
stop_ping(JID#jid.lserver, JID).
|
stop_ping(JID#jid.lserver, JID).
|
||||||
|
|
||||||
|
@ -515,6 +515,7 @@ is_type_match(Type, Value, JID, Subscription, Groups) ->
|
|||||||
group -> lists:member(Value, Groups)
|
group -> lists:member(Value, Groups)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> any().
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
|
@ -117,6 +117,7 @@ get_data(LUser, LServer) ->
|
|||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:get_all_data(LUser, LServer).
|
Mod:get_all_data(LUser, LServer).
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> any().
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
|
@ -660,6 +660,7 @@ disco_items(Host, Node, From) ->
|
|||||||
%% presence hooks handling functions
|
%% presence hooks handling functions
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
-spec caps_add(jid(), jid(), [binary()]) -> ok.
|
||||||
caps_add(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features)
|
caps_add(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features)
|
||||||
when Host =/= S ->
|
when Host =/= S ->
|
||||||
%% When a remote contact goes online while the local user is offline, the
|
%% When a remote contact goes online while the local user is offline, the
|
||||||
@ -675,9 +676,11 @@ caps_add(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID
|
|||||||
caps_add(_From, _To, _Feature) ->
|
caps_add(_From, _To, _Feature) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec caps_update(jid(), jid(), [binary()]) -> ok.
|
||||||
caps_update(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features) ->
|
caps_update(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features) ->
|
||||||
presence(Host, {presence, U, S, [R], JID}).
|
presence(Host, {presence, U, S, [R], JID}).
|
||||||
|
|
||||||
|
-spec presence_probe(jid(), jid(), pid()) -> ok.
|
||||||
presence_probe(#jid{luser = U, lserver = S, lresource = R} = JID, JID, Pid) ->
|
presence_probe(#jid{luser = U, lserver = S, lresource = R} = JID, JID, Pid) ->
|
||||||
presence(S, {presence, JID, Pid}),
|
presence(S, {presence, JID, Pid}),
|
||||||
presence(S, {presence, U, S, [R], JID});
|
presence(S, {presence, U, S, [R], JID});
|
||||||
@ -697,12 +700,16 @@ presence(ServerHost, Presence) ->
|
|||||||
undefined -> init_send_loop(ServerHost);
|
undefined -> init_send_loop(ServerHost);
|
||||||
Pid -> {Pid, undefined}
|
Pid -> {Pid, undefined}
|
||||||
end,
|
end,
|
||||||
SendLoop ! Presence.
|
SendLoop ! Presence,
|
||||||
|
ok.
|
||||||
|
|
||||||
%% -------
|
%% -------
|
||||||
%% subscription hooks handling functions
|
%% subscription hooks handling functions
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
-spec out_subscription(
|
||||||
|
binary(), binary(), jid(),
|
||||||
|
subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
|
||||||
out_subscription(User, Server, JID, subscribed) ->
|
out_subscription(User, Server, JID, subscribed) ->
|
||||||
Owner = jid:make(User, Server, <<>>),
|
Owner = jid:make(User, Server, <<>>),
|
||||||
{PUser, PServer, PResource} = jid:tolower(JID),
|
{PUser, PServer, PResource} = jid:tolower(JID),
|
||||||
@ -763,6 +770,7 @@ unsubscribe_user(Host, Entity, Owner) ->
|
|||||||
%% user remove hook handling function
|
%% user remove hook handling function
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> ok.
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
@ -802,7 +810,8 @@ remove_user(User, Server) ->
|
|||||||
Affs)
|
Affs)
|
||||||
end,
|
end,
|
||||||
plugins(Host))
|
plugins(Host))
|
||||||
end).
|
end),
|
||||||
|
ok.
|
||||||
|
|
||||||
handle_call(server_host, _From, State) ->
|
handle_call(server_host, _From, State) ->
|
||||||
{reply, State#state.server_host, State};
|
{reply, State#state.server_host, State};
|
||||||
@ -4224,11 +4233,12 @@ extended_headers(Jids) ->
|
|||||||
attrs = [{<<"type">>, <<"replyto">>}, {<<"jid">>, Jid}]}
|
attrs = [{<<"type">>, <<"replyto">>}, {<<"jid">>, Jid}]}
|
||||||
|| Jid <- Jids].
|
|| Jid <- Jids].
|
||||||
|
|
||||||
|
-spec on_user_offline(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
|
||||||
on_user_offline(_, JID, _) ->
|
on_user_offline(_, JID, _) ->
|
||||||
{User, Server, Resource} = jid:tolower(JID),
|
{User, Server, Resource} = jid:tolower(JID),
|
||||||
case user_resources(User, Server) of
|
case user_resources(User, Server) of
|
||||||
[] -> purge_offline({User, Server, Resource});
|
[] -> purge_offline({User, Server, Resource});
|
||||||
_ -> true
|
_ -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
purge_offline(LJID) ->
|
purge_offline(LJID) ->
|
||||||
|
@ -74,6 +74,7 @@ stop(Host) ->
|
|||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
-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,
|
||||||
fun(A) -> A end,
|
fun(A) -> A end,
|
||||||
@ -85,6 +86,9 @@ stream_feature_register(Acc, Host) ->
|
|||||||
Acc
|
Acc
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec unauthenticated_iq_register(empty | iq(), binary(), iq(),
|
||||||
|
{inet:ip_address(), non_neg_integer()}) ->
|
||||||
|
empty | iq().
|
||||||
unauthenticated_iq_register(_Acc, Server,
|
unauthenticated_iq_register(_Acc, Server,
|
||||||
#iq{sub_els = [#register{}]} = IQ, IP) ->
|
#iq{sub_els = [#register{}]} = IQ, IP) ->
|
||||||
Address = case IP of
|
Address = case IP of
|
||||||
|
@ -452,6 +452,9 @@ in_subscription(_, User, Server, JID, Type, Reason) ->
|
|||||||
process_subscription(in, User, Server, JID, Type,
|
process_subscription(in, User, Server, JID, Type,
|
||||||
Reason).
|
Reason).
|
||||||
|
|
||||||
|
-spec out_subscription(
|
||||||
|
binary(), binary(), jid(),
|
||||||
|
subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
|
||||||
out_subscription(User, Server, JID, Type) ->
|
out_subscription(User, Server, JID, Type) ->
|
||||||
process_subscription(out, User, Server, JID, Type, <<"">>).
|
process_subscription(out, User, Server, JID, Type, <<"">>).
|
||||||
|
|
||||||
@ -643,12 +646,14 @@ in_auto_reply(from, out, unsubscribe) -> unsubscribed;
|
|||||||
in_auto_reply(both, none, unsubscribe) -> unsubscribed;
|
in_auto_reply(both, none, unsubscribe) -> unsubscribed;
|
||||||
in_auto_reply(_, _, _) -> none.
|
in_auto_reply(_, _, _) -> none.
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> ok.
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
LServer = jid:nameprep(Server),
|
LServer = jid:nameprep(Server),
|
||||||
send_unsubscription_to_rosteritems(LUser, LServer),
|
send_unsubscription_to_rosteritems(LUser, LServer),
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
Mod:remove_user(LUser, LServer).
|
Mod:remove_user(LUser, LServer),
|
||||||
|
ok.
|
||||||
|
|
||||||
%% For each contact with Subscription:
|
%% For each contact with Subscription:
|
||||||
%% Both or From, send a "unsubscribed" presence stanza;
|
%% Both or From, send a "unsubscribed" presence stanza;
|
||||||
|
@ -336,6 +336,9 @@ in_subscription(Acc, User, Server, JID, Type,
|
|||||||
_Reason) ->
|
_Reason) ->
|
||||||
process_subscription(in, User, Server, JID, Type, Acc).
|
process_subscription(in, User, Server, JID, Type, Acc).
|
||||||
|
|
||||||
|
-spec out_subscription(
|
||||||
|
binary(), binary(), jid(),
|
||||||
|
subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
|
||||||
out_subscription(UserFrom, ServerFrom, JIDTo,
|
out_subscription(UserFrom, ServerFrom, JIDTo,
|
||||||
unsubscribed) ->
|
unsubscribed) ->
|
||||||
#jid{luser = UserTo, lserver = ServerTo} = JIDTo,
|
#jid{luser = UserTo, lserver = ServerTo} = JIDTo,
|
||||||
@ -629,12 +632,15 @@ broadcast_members_to_user(LUser, LServer, Group, Host, Subscription) ->
|
|||||||
broadcast_subscription(U, S, {LUser, LServer, <<"">>}, Subscription)
|
broadcast_subscription(U, S, {LUser, LServer, <<"">>}, Subscription)
|
||||||
end, Members).
|
end, Members).
|
||||||
|
|
||||||
|
-spec register_user(binary(), binary()) -> ok.
|
||||||
register_user(User, Server) ->
|
register_user(User, Server) ->
|
||||||
Groups = get_user_groups({User, Server}),
|
Groups = get_user_groups({User, Server}),
|
||||||
[push_user_to_displayed(User, Server, Group, Server,
|
[push_user_to_displayed(User, Server, Group, Server,
|
||||||
both, displayed_to_groups(Group, Server))
|
both, displayed_to_groups(Group, Server))
|
||||||
|| Group <- Groups].
|
|| Group <- Groups],
|
||||||
|
ok.
|
||||||
|
|
||||||
|
-spec remove_user(binary(), binary()) -> ok.
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
push_user_to_members(User, Server, remove).
|
push_user_to_members(User, Server, remove).
|
||||||
|
|
||||||
@ -724,6 +730,7 @@ push_roster_item(User, Server, ContactU, ContactS,
|
|||||||
groups = [GroupName]},
|
groups = [GroupName]},
|
||||||
push_item(User, Server, Item).
|
push_item(User, Server, Item).
|
||||||
|
|
||||||
|
-spec user_available(jid()) -> ok.
|
||||||
user_available(New) ->
|
user_available(New) ->
|
||||||
LUser = New#jid.luser,
|
LUser = New#jid.luser,
|
||||||
LServer = New#jid.lserver,
|
LServer = New#jid.lserver,
|
||||||
@ -747,6 +754,7 @@ user_available(New) ->
|
|||||||
_ -> ok
|
_ -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec unset_presence(binary(), binary(), binary(), binary()) -> ok.
|
||||||
unset_presence(LUser, LServer, Resource, Status) ->
|
unset_presence(LUser, LServer, Resource, Status) ->
|
||||||
Resources = ejabberd_sm:get_user_resources(LUser,
|
Resources = ejabberd_sm:get_user_resources(LUser,
|
||||||
LServer),
|
LServer),
|
||||||
|
@ -191,6 +191,9 @@ in_subscription(Acc, User, Server, JID, Type,
|
|||||||
_Reason) ->
|
_Reason) ->
|
||||||
process_subscription(in, User, Server, JID, Type, Acc).
|
process_subscription(in, User, Server, JID, Type, Acc).
|
||||||
|
|
||||||
|
-spec out_subscription(
|
||||||
|
binary(), binary(), jid(),
|
||||||
|
subscribed | unsubscribed | subscribe | unsubscribe) -> boolean().
|
||||||
out_subscription(User, Server, JID, Type) ->
|
out_subscription(User, Server, JID, Type) ->
|
||||||
process_subscription(out, User, Server, JID, Type,
|
process_subscription(out, User, Server, JID, Type,
|
||||||
false).
|
false).
|
||||||
|
@ -51,11 +51,12 @@ depends(_Host, _Opts) ->
|
|||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% Hooks
|
%% Hooks
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
|
-spec update_presence(presence(), binary(), binary()) -> presence().
|
||||||
update_presence(#presence{type = undefined} = Packet, User, Host) ->
|
update_presence(#presence{type = undefined} = Packet, User, Host) ->
|
||||||
presence_with_xupdate(Packet, User, Host);
|
presence_with_xupdate(Packet, User, Host);
|
||||||
update_presence(Packet, _User, _Host) -> Packet.
|
update_presence(Packet, _User, _Host) -> Packet.
|
||||||
|
|
||||||
|
-spec vcard_set(binary(), binary(), xmlel()) -> ok.
|
||||||
vcard_set(LUser, LServer, VCARD) ->
|
vcard_set(LUser, LServer, VCARD) ->
|
||||||
US = {LUser, LServer},
|
US = {LUser, LServer},
|
||||||
case fxml:get_path_s(VCARD,
|
case fxml:get_path_s(VCARD,
|
||||||
|
@ -57,6 +57,7 @@ terminate(Host, ServerHost) ->
|
|||||||
?MODULE, user_offline, 75),
|
?MODULE, user_offline, 75),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec user_offline(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> _.
|
||||||
user_offline(_SID, #jid{luser=LUser,lserver=LServer}, _Info) ->
|
user_offline(_SID, #jid{luser=LUser,lserver=LServer}, _Info) ->
|
||||||
mod_pubsub:remove_user(LUser, LServer).
|
mod_pubsub:remove_user(LUser, LServer).
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ get_type(#message{type = T}) -> T;
|
|||||||
get_type(#presence{type = T}) -> T;
|
get_type(#presence{type = T}) -> T;
|
||||||
get_type(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"type">>, Attrs).
|
get_type(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"type">>, Attrs).
|
||||||
|
|
||||||
-spec get_lang(iq() | message() | presence()) -> binary().
|
-spec get_lang(iq() | message() | presence() | xmlel()) -> binary().
|
||||||
get_lang(#iq{lang = L}) -> L;
|
get_lang(#iq{lang = L}) -> L;
|
||||||
get_lang(#message{lang = L}) -> L;
|
get_lang(#message{lang = L}) -> L;
|
||||||
get_lang(#presence{lang = L}) -> L;
|
get_lang(#presence{lang = L}) -> L;
|
||||||
|
@ -3483,6 +3483,12 @@ dec_bool(<<"0">>) -> false;
|
|||||||
dec_bool(<<"true">>) -> true;
|
dec_bool(<<"true">>) -> true;
|
||||||
dec_bool(<<"1">>) -> true.
|
dec_bool(<<"1">>) -> true.
|
||||||
|
|
||||||
|
nameprep(S) ->
|
||||||
|
case jid:nameprep(S) of
|
||||||
|
error -> erlang:error(badarg);
|
||||||
|
S1 -> S1
|
||||||
|
end.
|
||||||
|
|
||||||
resourceprep(R) ->
|
resourceprep(R) ->
|
||||||
case jid:resourceprep(R) of
|
case jid:resourceprep(R) of
|
||||||
error -> erlang:error(badarg);
|
error -> erlang:error(badarg);
|
||||||
@ -4887,7 +4893,7 @@ decode_db_verify_attr_from(__TopXMLNS, undefined) ->
|
|||||||
{missing_attr, <<"from">>, <<"db:verify">>,
|
{missing_attr, <<"from">>, <<"db:verify">>,
|
||||||
__TopXMLNS}});
|
__TopXMLNS}});
|
||||||
decode_db_verify_attr_from(__TopXMLNS, _val) ->
|
decode_db_verify_attr_from(__TopXMLNS, _val) ->
|
||||||
case catch dec_jid(_val) of
|
case catch nameprep(_val) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
erlang:error({xmpp_codec,
|
erlang:error({xmpp_codec,
|
||||||
{bad_attr_value, <<"from">>, <<"db:verify">>,
|
{bad_attr_value, <<"from">>, <<"db:verify">>,
|
||||||
@ -4896,13 +4902,13 @@ decode_db_verify_attr_from(__TopXMLNS, _val) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
encode_db_verify_attr_from(_val, _acc) ->
|
encode_db_verify_attr_from(_val, _acc) ->
|
||||||
[{<<"from">>, enc_jid(_val)} | _acc].
|
[{<<"from">>, nameprep(_val)} | _acc].
|
||||||
|
|
||||||
decode_db_verify_attr_to(__TopXMLNS, undefined) ->
|
decode_db_verify_attr_to(__TopXMLNS, undefined) ->
|
||||||
erlang:error({xmpp_codec,
|
erlang:error({xmpp_codec,
|
||||||
{missing_attr, <<"to">>, <<"db:verify">>, __TopXMLNS}});
|
{missing_attr, <<"to">>, <<"db:verify">>, __TopXMLNS}});
|
||||||
decode_db_verify_attr_to(__TopXMLNS, _val) ->
|
decode_db_verify_attr_to(__TopXMLNS, _val) ->
|
||||||
case catch dec_jid(_val) of
|
case catch nameprep(_val) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
erlang:error({xmpp_codec,
|
erlang:error({xmpp_codec,
|
||||||
{bad_attr_value, <<"to">>, <<"db:verify">>,
|
{bad_attr_value, <<"to">>, <<"db:verify">>,
|
||||||
@ -4911,7 +4917,7 @@ decode_db_verify_attr_to(__TopXMLNS, _val) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
encode_db_verify_attr_to(_val, _acc) ->
|
encode_db_verify_attr_to(_val, _acc) ->
|
||||||
[{<<"to">>, enc_jid(_val)} | _acc].
|
[{<<"to">>, nameprep(_val)} | _acc].
|
||||||
|
|
||||||
decode_db_verify_attr_id(__TopXMLNS, undefined) ->
|
decode_db_verify_attr_id(__TopXMLNS, undefined) ->
|
||||||
erlang:error({xmpp_codec,
|
erlang:error({xmpp_codec,
|
||||||
@ -5014,7 +5020,7 @@ decode_db_result_attr_from(__TopXMLNS, undefined) ->
|
|||||||
{missing_attr, <<"from">>, <<"db:result">>,
|
{missing_attr, <<"from">>, <<"db:result">>,
|
||||||
__TopXMLNS}});
|
__TopXMLNS}});
|
||||||
decode_db_result_attr_from(__TopXMLNS, _val) ->
|
decode_db_result_attr_from(__TopXMLNS, _val) ->
|
||||||
case catch dec_jid(_val) of
|
case catch nameprep(_val) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
erlang:error({xmpp_codec,
|
erlang:error({xmpp_codec,
|
||||||
{bad_attr_value, <<"from">>, <<"db:result">>,
|
{bad_attr_value, <<"from">>, <<"db:result">>,
|
||||||
@ -5023,13 +5029,13 @@ decode_db_result_attr_from(__TopXMLNS, _val) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
encode_db_result_attr_from(_val, _acc) ->
|
encode_db_result_attr_from(_val, _acc) ->
|
||||||
[{<<"from">>, enc_jid(_val)} | _acc].
|
[{<<"from">>, nameprep(_val)} | _acc].
|
||||||
|
|
||||||
decode_db_result_attr_to(__TopXMLNS, undefined) ->
|
decode_db_result_attr_to(__TopXMLNS, undefined) ->
|
||||||
erlang:error({xmpp_codec,
|
erlang:error({xmpp_codec,
|
||||||
{missing_attr, <<"to">>, <<"db:result">>, __TopXMLNS}});
|
{missing_attr, <<"to">>, <<"db:result">>, __TopXMLNS}});
|
||||||
decode_db_result_attr_to(__TopXMLNS, _val) ->
|
decode_db_result_attr_to(__TopXMLNS, _val) ->
|
||||||
case catch dec_jid(_val) of
|
case catch nameprep(_val) of
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
erlang:error({xmpp_codec,
|
erlang:error({xmpp_codec,
|
||||||
{bad_attr_value, <<"to">>, <<"db:result">>,
|
{bad_attr_value, <<"to">>, <<"db:result">>,
|
||||||
@ -5038,7 +5044,7 @@ decode_db_result_attr_to(__TopXMLNS, _val) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
encode_db_result_attr_to(_val, _acc) ->
|
encode_db_result_attr_to(_val, _acc) ->
|
||||||
[{<<"to">>, enc_jid(_val)} | _acc].
|
[{<<"to">>, nameprep(_val)} | _acc].
|
||||||
|
|
||||||
decode_db_result_attr_type(__TopXMLNS, undefined) ->
|
decode_db_result_attr_type(__TopXMLNS, undefined) ->
|
||||||
undefined;
|
undefined;
|
||||||
|
@ -2860,9 +2860,9 @@
|
|||||||
result = {db_result, '$from', '$to', '$type', '$key', '$_els'},
|
result = {db_result, '$from', '$to', '$type', '$key', '$_els'},
|
||||||
cdata = #cdata{default = <<"">>, label = '$key'},
|
cdata = #cdata{default = <<"">>, label = '$key'},
|
||||||
attrs = [#attr{name = <<"from">>, required = true,
|
attrs = [#attr{name = <<"from">>, required = true,
|
||||||
dec = {dec_jid, []}, enc = {enc_jid, []}},
|
dec = {nameprep, []}, enc = {nameprep, []}},
|
||||||
#attr{name = <<"to">>, required = true,
|
#attr{name = <<"to">>, required = true,
|
||||||
dec = {dec_jid, []}, enc = {enc_jid, []}},
|
dec = {nameprep, []}, enc = {nameprep, []}},
|
||||||
#attr{name = <<"type">>,
|
#attr{name = <<"type">>,
|
||||||
dec = {dec_enum, [[valid, invalid, error]]},
|
dec = {dec_enum, [[valid, invalid, error]]},
|
||||||
enc = {enc_enum, []}}]}).
|
enc = {enc_enum, []}}]}).
|
||||||
@ -2873,9 +2873,9 @@
|
|||||||
result = {db_verify, '$from', '$to', '$id', '$type', '$key', '$_els'},
|
result = {db_verify, '$from', '$to', '$id', '$type', '$key', '$_els'},
|
||||||
cdata = #cdata{default = <<"">>, label = '$key'},
|
cdata = #cdata{default = <<"">>, label = '$key'},
|
||||||
attrs = [#attr{name = <<"from">>, required = true,
|
attrs = [#attr{name = <<"from">>, required = true,
|
||||||
dec = {dec_jid, []}, enc = {enc_jid, []}},
|
dec = {nameprep, []}, enc = {nameprep, []}},
|
||||||
#attr{name = <<"to">>, required = true,
|
#attr{name = <<"to">>, required = true,
|
||||||
dec = {dec_jid, []}, enc = {enc_jid, []}},
|
dec = {nameprep, []}, enc = {nameprep, []}},
|
||||||
#attr{name = <<"id">>, required = true},
|
#attr{name = <<"id">>, required = true},
|
||||||
#attr{name = <<"type">>,
|
#attr{name = <<"type">>,
|
||||||
dec = {dec_enum, [[valid, invalid, error]]},
|
dec = {dec_enum, [[valid, invalid, error]]},
|
||||||
@ -3113,6 +3113,15 @@ resourceprep(R) ->
|
|||||||
R1
|
R1
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec nameprep(_) -> binary().
|
||||||
|
nameprep(S) ->
|
||||||
|
case jid:nameprep(S) of
|
||||||
|
error ->
|
||||||
|
erlang:error(badarg);
|
||||||
|
S1 ->
|
||||||
|
S1
|
||||||
|
end.
|
||||||
|
|
||||||
-spec dec_bool(_) -> boolean().
|
-spec dec_bool(_) -> boolean().
|
||||||
dec_bool(<<"false">>) -> false;
|
dec_bool(<<"false">>) -> false;
|
||||||
dec_bool(<<"0">>) -> false;
|
dec_bool(<<"0">>) -> false;
|
||||||
@ -3137,7 +3146,7 @@ enc_ip({0,0,0,0,0,16#ffff,A,B}) ->
|
|||||||
enc_ip(Addr) ->
|
enc_ip(Addr) ->
|
||||||
list_to_binary(inet_parse:ntoa(Addr)).
|
list_to_binary(inet_parse:ntoa(Addr)).
|
||||||
|
|
||||||
-spec re:split(_, _) -> binary().
|
-spec re:split(_, _) -> [binary()].
|
||||||
-spec base64:decode(_) -> binary().
|
-spec base64:decode(_) -> binary().
|
||||||
|
|
||||||
-spec dec_host_port(_) -> binary() | inet:ip_address() |
|
-spec dec_host_port(_) -> binary() | inet:ip_address() |
|
||||||
|
Loading…
Reference in New Issue
Block a user