mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-24 17:29:28 +01:00
Big #jid to binary() conversion.
Internal tables (ejabberd_router, ejabberd_sm, ejabberd_hooks, mod_last, mod_roster) use binary() as storage. Basic test using the ODBC backend. SVN Revision: 1770
This commit is contained in:
parent
1a44fe29b4
commit
4827db4f56
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
||||
2009-01-03 Pablo Polvorin <pablo.polvorin@process-one.net>
|
||||
* src/mod_pubsub_node_default.erl: Fix typo
|
||||
|
||||
* src/mod_vcard.erl, src/mod_vcard_ldap.erl,src/ ejabberd_hooks.erl,
|
||||
mod_muc/mod_muc_room.erl, src/mod_muc/mod_muc.erl,
|
||||
src/mod_muc/mod_muc_log.erl, src/mod_shared_roster.erl,
|
||||
src/ejabberd_auth_odbc.erl, src/mod_offline_odbc.erl,
|
||||
src/ejabberd_system_monitor.erl, src/ejabberd_s2s_in.erl,
|
||||
src/mod_configure.erl, src/ejabberd_receiver.erl, src/mod_irc/mod_irc.erl,
|
||||
src/ejabberd_sm.erl, src/mod_privacy_odbc.erl, src/ejabberd_c2s.erl,
|
||||
src/mod_announce.erl, src/ejabberd_local.erl, src/mod_privacy.erl,
|
||||
src/ejabberd_auth_internal.erl, src/mod_adhoc.erl, src/mod_echo.erl,
|
||||
src/jlib.erl, src/mod_vcard_odbc.erl, src/ejabberd_s2s.erl,
|
||||
src/mod_stats.erl, src/ejabberd_router.erl, src/mod_last.erl,
|
||||
src/mod_private.erl, src/mod_roster.erl, src/ejabberd_service.erl,
|
||||
src/mod_disco.erl, src/mod_private_odbc.erl, src/mod_service_log.erl,
|
||||
src/mod_configure2.erl, src/mod_roster_odbc.erl, src/mod_offline.erl,
|
||||
src/mod_register.erl, src/mod_version.erl, src/mod_caps.erl,
|
||||
src/mod_last_odbc.erl: Use exmpp API to access JID fields. Keep
|
||||
#jid fields in binary format when possible. Change all 'user' and
|
||||
'server' arguments in all hooks to binary. Change internal tables of
|
||||
ejabberd_sm, ejabberd_router, ejabberd_hooks, mod_last, mod_roster
|
||||
to use binary() storage.
|
||||
|
||||
|
||||
|
||||
2009-01-03 Christophe Romain <christophe.romain@process-one.net>
|
||||
|
||||
* src/mod_pubsub/mod_pubsub.erl: deliver notification depending on
|
||||
|
@ -261,7 +261,9 @@ remove_user(User, Server) ->
|
||||
mnesia:delete({passwd, US})
|
||||
end,
|
||||
mnesia:transaction(F),
|
||||
ejabberd_hooks:run(remove_user, LServer, [User, Server])
|
||||
ejabberd_hooks:run(remove_user,
|
||||
list_to_binary(LServer),
|
||||
[list_to_binary(User), list_to_binary(Server)])
|
||||
catch
|
||||
_ ->
|
||||
ok
|
||||
@ -285,7 +287,9 @@ remove_user(User, Server, Password) ->
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, ok} ->
|
||||
ejabberd_hooks:run(remove_user, LServer, [User, Server]),
|
||||
ejabberd_hooks:run(remove_user,
|
||||
list_to_binary(LServer),
|
||||
[list_to_binary(User), list_to_binary(Server)]),
|
||||
ok;
|
||||
{atomic, Res} ->
|
||||
Res;
|
||||
|
@ -231,8 +231,8 @@ remove_user(User, Server) ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
catch odbc_queries:del_user(LServer, Username),
|
||||
ejabberd_hooks:run(remove_user, exmpp_stringprep:nameprep(Server),
|
||||
[User, Server])
|
||||
ejabberd_hooks:run(remove_user, list_to_binary(LServer),
|
||||
[list_to_binary(User), list_to_binary(Server)])
|
||||
catch
|
||||
_ ->
|
||||
error
|
||||
@ -249,8 +249,8 @@ remove_user(User, Server, Password) ->
|
||||
LServer, Username, Pass),
|
||||
case Result of
|
||||
{selected, ["password"], [{Password}]} ->
|
||||
ejabberd_hooks:run(remove_user, exmpp_stringprep:nameprep(Server),
|
||||
[User, Server]),
|
||||
ejabberd_hooks:run(remove_user, list_to_binary(LServer),
|
||||
[list_to_binary(User), list_to_binary(Server)]),
|
||||
ok;
|
||||
{selected, ["password"], []} ->
|
||||
not_exists;
|
||||
|
@ -37,7 +37,8 @@
|
||||
send_element/2,
|
||||
socket_type/0,
|
||||
get_presence/1,
|
||||
get_subscribed/1]).
|
||||
get_subscribed/1,
|
||||
get_subscribed_and_online/1]).
|
||||
|
||||
%% gen_fsm callbacks
|
||||
-export([init/1,
|
||||
@ -54,6 +55,9 @@
|
||||
handle_info/3,
|
||||
terminate/3]).
|
||||
|
||||
|
||||
-export([get_state/1]).
|
||||
|
||||
-include_lib("exmpp/include/exmpp.hrl").
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@ -78,12 +82,13 @@
|
||||
tls_options = [],
|
||||
authenticated = false,
|
||||
jid,
|
||||
user = undefined, server = ?MYNAME, resource = undefined,
|
||||
user = undefined, server = list_to_binary(?MYNAME), resource = undefined,
|
||||
sid,
|
||||
pres_t = ?SETS:new(),
|
||||
pres_f = ?SETS:new(),
|
||||
pres_a = ?SETS:new(),
|
||||
pres_i = ?SETS:new(),
|
||||
pres_available = ?DICT:new(),
|
||||
pres_last, pres_pri,
|
||||
pres_timestamp,
|
||||
pres_invis = false,
|
||||
@ -98,7 +103,7 @@
|
||||
-ifdef(DBGFSM).
|
||||
-define(FSMOPTS, [{debug, [trace]}]).
|
||||
-else.
|
||||
-define(FSMOPTS, []).
|
||||
-define(FSMOPTS, [{spawn_opt,[{fullsweep_after,10}]}]).
|
||||
-endif.
|
||||
|
||||
%% Module start with or without supervisor:
|
||||
@ -142,6 +147,11 @@ socket_type() ->
|
||||
get_presence(FsmRef) ->
|
||||
gen_fsm:sync_send_all_state_event(FsmRef, {get_presence}, 1000).
|
||||
|
||||
|
||||
%%TODO: for debug only
|
||||
get_state(FsmRef) ->
|
||||
gen_fsm:sync_send_all_state_event(FsmRef, get_state, 1000).
|
||||
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% Callback functions from gen_fsm
|
||||
%%%----------------------------------------------------------------------
|
||||
@ -170,7 +180,6 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
TLSOpts = lists:filter(fun({certfile, _}) -> true;
|
||||
(_) -> false
|
||||
end, Opts),
|
||||
Zlib = lists:member(zlib, Opts) andalso (not StartTLSRequired),
|
||||
IP = peerip(SockMod, Socket),
|
||||
%% Check if IP is blacklisted:
|
||||
case is_ip_blacklisted(IP) of
|
||||
@ -203,8 +212,14 @@ init([{SockMod, Socket}, Opts]) ->
|
||||
end.
|
||||
|
||||
%% Return list of all available resources of contacts,
|
||||
%% in form [{JID, Caps}].
|
||||
get_subscribed(FsmRef) ->
|
||||
gen_fsm:sync_send_all_state_event(FsmRef, get_subscribed, 1000).
|
||||
gen_fsm:sync_send_all_state_event(
|
||||
FsmRef, get_subscribed, 1000).
|
||||
get_subscribed_and_online(FsmRef) ->
|
||||
gen_fsm:sync_send_all_state_event(
|
||||
FsmRef, get_subscribed_and_online, 1000).
|
||||
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: StateName/2
|
||||
@ -226,6 +241,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
|
||||
?NS_XMPP ->
|
||||
Server = exmpp_stringprep:nameprep(
|
||||
exmpp_stream:get_receiving_entity(Opening)),
|
||||
ServerB = list_to_binary(Server),
|
||||
case lists:member(Server, ?MYHOSTS) of
|
||||
true ->
|
||||
Lang = exmpp_stream:get_lang(Opening),
|
||||
@ -275,7 +291,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
|
||||
end,
|
||||
Other_Feats = ejabberd_hooks:run_fold(
|
||||
c2s_stream_features,
|
||||
Server,
|
||||
ServerB,
|
||||
[], []),
|
||||
send_element(StateData,
|
||||
exmpp_stream:features(
|
||||
@ -285,7 +301,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
|
||||
Other_Feats)),
|
||||
fsm_next_state(wait_for_feature_request,
|
||||
StateData#state{
|
||||
server = Server,
|
||||
server = ServerB,
|
||||
sasl_state = SASLState,
|
||||
lang = Lang});
|
||||
_ ->
|
||||
@ -299,7 +315,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
|
||||
])),
|
||||
fsm_next_state(wait_for_bind,
|
||||
StateData#state{
|
||||
server = Server,
|
||||
server = ServerB,
|
||||
lang = Lang});
|
||||
_ ->
|
||||
send_element(
|
||||
@ -307,7 +323,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
|
||||
exmpp_stream:features([])),
|
||||
fsm_next_state(wait_for_session,
|
||||
StateData#state{
|
||||
server = Server,
|
||||
server = ServerB,
|
||||
lang = Lang})
|
||||
end
|
||||
end;
|
||||
@ -324,7 +340,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
|
||||
send_element(StateData, Header),
|
||||
fsm_next_state(wait_for_auth,
|
||||
StateData#state{
|
||||
server = Server,
|
||||
server = ServerB,
|
||||
lang = Lang})
|
||||
end
|
||||
end;
|
||||
@ -368,10 +384,11 @@ wait_for_stream(closed, StateData) ->
|
||||
|
||||
|
||||
wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
ServerString = binary_to_list(StateData#state.server),
|
||||
case is_auth_packet(El) of
|
||||
{auth, _ID, get, {_U, _, _, _}} ->
|
||||
Fields = case ejabberd_auth:plain_password_required(
|
||||
StateData#state.server) of
|
||||
ServerString) of
|
||||
false -> both;
|
||||
true -> plain
|
||||
end,
|
||||
@ -386,11 +403,12 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
{auth, _ID, set, {U, P, D, R}} ->
|
||||
try
|
||||
JID = exmpp_jid:make_jid(U, StateData#state.server, R),
|
||||
case acl:match_rule(StateData#state.server,
|
||||
UBinary = exmpp_jid:lnode(JID),
|
||||
case acl:match_rule(ServerString,
|
||||
StateData#state.access, JID) of
|
||||
allow ->
|
||||
case ejabberd_auth:check_password_with_authmodule(
|
||||
U, StateData#state.server, P,
|
||||
U, ServerString, P,
|
||||
StateData#state.streamid, D) of
|
||||
{true, AuthModule} ->
|
||||
?INFO_MSG(
|
||||
@ -402,7 +420,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
Info = [{ip, StateData#state.ip}, {conn, Conn},
|
||||
{auth_module, AuthModule}],
|
||||
ejabberd_sm:open_session(
|
||||
SID, U, StateData#state.server, R, Info),
|
||||
SID, exmpp_jid:make_jid(U, StateData#state.server, R), Info),
|
||||
Res = exmpp_server_legacy_auth:success(El),
|
||||
send_element(StateData, Res),
|
||||
change_shaper(StateData, JID),
|
||||
@ -410,18 +428,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
|
||||
roster_get_subscription_lists,
|
||||
StateData#state.server,
|
||||
{[], []},
|
||||
[U, StateData#state.server]),
|
||||
[UBinary, StateData#state.server]),
|
||||
LJID = jlib:short_prepd_bare_jid(JID),
|
||||
Fs1 = [LJID | Fs],
|
||||
Ts1 = [LJID | Ts],
|
||||
PrivList = ejabberd_hooks:run_fold(
|
||||
privacy_get_user_list, StateData#state.server,
|
||||
#userlist{},
|
||||
[U, StateData#state.server]),
|
||||
[UBinary, StateData#state.server]),
|
||||
fsm_next_state(session_established,
|
||||
StateData#state{
|
||||
user = U,
|
||||
resource = R,
|
||||
sasl_state = 'undefined',
|
||||
%not used anymore, let the GC work.
|
||||
user = list_to_binary(U),
|
||||
resource = list_to_binary(R),
|
||||
jid = JID,
|
||||
sid = SID,
|
||||
conn = Conn,
|
||||
@ -504,7 +524,7 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
|
||||
StateData#state{
|
||||
streamid = new_id(),
|
||||
authenticated = true,
|
||||
user = U });
|
||||
user = list_to_binary(U) });
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
send_element(StateData,
|
||||
exmpp_server_sasl:challenge(ServerOut)),
|
||||
@ -528,8 +548,9 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
|
||||
{?NS_TLS, 'starttls'} when TLS == true,
|
||||
TLSEnabled == false,
|
||||
SockMod == gen_tcp ->
|
||||
ServerString = binary_to_list(StateData#state.server),
|
||||
TLSOpts = case ejabberd_config:get_local_option(
|
||||
{domain_certfile, StateData#state.server}) of
|
||||
{domain_certfile, ServerString}) of
|
||||
undefined ->
|
||||
StateData#state.tls_options;
|
||||
CertFile ->
|
||||
@ -619,7 +640,7 @@ wait_for_sasl_response({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
|
||||
streamid = new_id(),
|
||||
authenticated = true,
|
||||
auth_module = AuthModule,
|
||||
user = U});
|
||||
user = list_to_binary(U)});
|
||||
{continue, ServerOut, NewSASLState} ->
|
||||
send_element(StateData,
|
||||
exmpp_server_sasl:challenge(ServerOut)),
|
||||
@ -662,18 +683,17 @@ wait_for_sasl_response(closed, StateData) ->
|
||||
|
||||
wait_for_bind({xmlstreamelement, El}, StateData) ->
|
||||
try
|
||||
U = StateData#state.user,
|
||||
R = case exmpp_server_binding:wished_resource(El) of
|
||||
undefined ->
|
||||
lists:concat([randoms:get_string() | tuple_to_list(now())]);
|
||||
Resource ->
|
||||
Resource
|
||||
end,
|
||||
JID = exmpp_jid:make_jid(U, StateData#state.server, R),
|
||||
JID = exmpp_jid:make_jid(StateData#state.user, StateData#state.server, R),
|
||||
Res = exmpp_server_binding:bind(El, JID),
|
||||
send_element(StateData, Res),
|
||||
fsm_next_state(wait_for_session,
|
||||
StateData#state{resource = R, jid = JID})
|
||||
StateData#state{resource = exmpp_jid:resource(JID), jid = JID})
|
||||
catch
|
||||
throw:{stringprep, resourceprep, _, _} ->
|
||||
Err = exmpp_server_binding:error(El, 'bad-request'),
|
||||
@ -702,11 +722,10 @@ wait_for_bind(closed, StateData) ->
|
||||
|
||||
wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
try
|
||||
U = StateData#state.user,
|
||||
R = StateData#state.resource,
|
||||
ServerString = binary_to_list(StateData#state.server),
|
||||
JID = StateData#state.jid,
|
||||
true = exmpp_server_session:want_establishment(El),
|
||||
case acl:match_rule(StateData#state.server,
|
||||
case acl:match_rule(ServerString,
|
||||
StateData#state.access, JID) of
|
||||
allow ->
|
||||
?INFO_MSG("(~w) Opened session for ~s",
|
||||
@ -717,7 +736,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
Info = [{ip, StateData#state.ip}, {conn, Conn},
|
||||
{auth_module, StateData#state.auth_module}],
|
||||
ejabberd_sm:open_session(
|
||||
SID, U, StateData#state.server, R, Info),
|
||||
SID, JID, Info),
|
||||
Res = exmpp_server_session:establish(El),
|
||||
send_element(StateData, Res),
|
||||
change_shaper(StateData, JID),
|
||||
@ -725,7 +744,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
roster_get_subscription_lists,
|
||||
StateData#state.server,
|
||||
{[], []},
|
||||
[U, StateData#state.server]),
|
||||
[StateData#state.user, StateData#state.server]),
|
||||
LJID = jlib:short_prepd_bare_jid(JID),
|
||||
Fs1 = [LJID | Fs],
|
||||
Ts1 = [LJID | Ts],
|
||||
@ -733,9 +752,11 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
|
||||
ejabberd_hooks:run_fold(
|
||||
privacy_get_user_list, StateData#state.server,
|
||||
#userlist{},
|
||||
[U, StateData#state.server]),
|
||||
[StateData#state.user, StateData#state.server]),
|
||||
fsm_next_state(session_established,
|
||||
StateData#state{
|
||||
sasl_state = 'undefined',
|
||||
%not used anymore, let the GC work.
|
||||
sid = SID,
|
||||
conn = Conn,
|
||||
pres_f = ?SETS:from_list(Fs1),
|
||||
@ -773,15 +794,13 @@ wait_for_session(closed, StateData) ->
|
||||
|
||||
|
||||
session_established({xmlstreamelement, El}, StateData) ->
|
||||
FromJID = StateData#state.jid,
|
||||
% Check 'from' attribute in stanza RFC 3920 Section 9.1.2
|
||||
case check_from(El, FromJID) of
|
||||
'invalid-from' ->
|
||||
send_element(StateData, exmpp_stream:error('invalid-from')),
|
||||
send_element(StateData, exmpp_stream:closing()),
|
||||
{stop, normal, StateData};
|
||||
_NewEl ->
|
||||
session_established2(El, StateData)
|
||||
case check_from(El, StateData#state.jid) of
|
||||
'invalid-from' ->
|
||||
send_element(StateData, exmpp_stream:error('invalid-from')),
|
||||
send_element(StateData, exmpp_stream:closing()),
|
||||
{stop, normal, StateData};
|
||||
_ ->
|
||||
session_established2(El, StateData)
|
||||
end;
|
||||
|
||||
%% We hibernate the process to reduce memory consumption after a
|
||||
@ -810,11 +829,13 @@ session_established2(El, StateData) ->
|
||||
try
|
||||
User = StateData#state.user,
|
||||
Server = StateData#state.server,
|
||||
|
||||
% TODO: check 'from' attribute in stanza
|
||||
FromJID = StateData#state.jid,
|
||||
To = exmpp_stanza:get_recipient(El),
|
||||
ToJID = case To of
|
||||
undefined ->
|
||||
exmpp_jid:make_bare_jid(User, Server);
|
||||
exmpp_jid:jid_to_bare_jid(StateData#state.jid);
|
||||
_ ->
|
||||
exmpp_jid:list_to_jid(To)
|
||||
end,
|
||||
@ -839,10 +860,10 @@ session_established2(El, StateData) ->
|
||||
user_send_packet,
|
||||
Server,
|
||||
[FromJID, ToJID, PresenceEl]),
|
||||
case ToJID of
|
||||
#jid{node = User,
|
||||
domain = Server,
|
||||
resource = undefined} ->
|
||||
case {exmpp_jid:node(ToJID),
|
||||
exmpp_jid:domain(ToJID),
|
||||
exmpp_jid:resource(ToJID)} of
|
||||
{User, Server,undefined} ->
|
||||
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
|
||||
[FromJID, PresenceEl, StateData]),
|
||||
presence_update(FromJID, PresenceEl,
|
||||
@ -894,6 +915,7 @@ session_established2(El, StateData) ->
|
||||
fsm_next_state(session_established, StateData)
|
||||
end.
|
||||
|
||||
|
||||
%%----------------------------------------------------------------------
|
||||
%% Func: StateName/3
|
||||
%% Returns: {next_state, NextStateName, NextStateData} |
|
||||
@ -925,8 +947,12 @@ handle_event(_Event, StateName, StateData) ->
|
||||
%% {stop, Reason, NewStateData} |
|
||||
%% {stop, Reason, Reply, NewStateData}
|
||||
%%----------------------------------------------------------------------
|
||||
%TODO: for debug only
|
||||
handle_sync_event(get_state,_From,StateName,StateData) ->
|
||||
{reply,{StateName, StateData}, StateName, StateData};
|
||||
|
||||
handle_sync_event({get_presence}, _From, StateName, StateData) ->
|
||||
User = StateData#state.user,
|
||||
User = binary_to_list(StateData#state.user),
|
||||
PresLast = StateData#state.pres_last,
|
||||
|
||||
Show = case PresLast of
|
||||
@ -937,14 +963,35 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
|
||||
undefined -> "";
|
||||
_ -> exmpp_presence:get_status(PresLast)
|
||||
end,
|
||||
Resource = StateData#state.resource,
|
||||
Resource = binary_to_list(StateData#state.resource),
|
||||
|
||||
Reply = {User, Resource, atom_to_list(Show), Status},
|
||||
fsm_reply(Reply, StateName, StateData);
|
||||
|
||||
handle_sync_event(get_subscribed, _From, StateName, StateData) ->
|
||||
Subscribed = ?SETS:to_list(StateData#state.pres_f),
|
||||
{reply, Subscribed, StateName, StateData};
|
||||
Subscribed = StateData#state.pres_f,
|
||||
Online = StateData#state.pres_available,
|
||||
Pred = fun({U, S, _} = User, _Caps) ->
|
||||
?SETS:is_element({U, S, undefined},
|
||||
Subscribed) orelse
|
||||
?SETS:is_element(User, Subscribed)
|
||||
end,
|
||||
SubscribedAndOnline = ?DICT:filter(Pred, Online),
|
||||
SubscribedWithCaps = ?SETS:fold(fun(User, Acc) ->
|
||||
[{User, undefined}|Acc]
|
||||
end, ?DICT:to_list(SubscribedAndOnline), Subscribed),
|
||||
{reply, SubscribedWithCaps, StateName, StateData};
|
||||
|
||||
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
|
||||
Subscribed = StateData#state.pres_f,
|
||||
Online = StateData#state.pres_available,
|
||||
Pred = fun({U, S, _R} = User, _Caps) ->
|
||||
?SETS:is_element({U, S, undefined},
|
||||
Subscribed) orelse
|
||||
?SETS:is_element(User, Subscribed)
|
||||
end,
|
||||
SubscribedAndOnline = ?DICT:filter(Pred, Online),
|
||||
{reply, ?DICT:to_list(SubscribedAndOnline), StateName, StateData};
|
||||
|
||||
handle_sync_event(_Event, _From, StateName, StateData) ->
|
||||
Reply = ok,
|
||||
@ -1036,39 +1083,44 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
LFrom = jlib:short_prepd_jid(From),
|
||||
LBFrom = jlib:short_prepd_bare_jid(From),
|
||||
%% Note contact availability
|
||||
case exmpp_presence:get_type(Packet) of
|
||||
'unavailable' ->
|
||||
mod_caps:clear_caps(From);
|
||||
_ ->
|
||||
Caps = mod_caps:read_caps(Packet#xmlel.children),
|
||||
mod_caps:note_caps(StateData#state.server, From, Caps)
|
||||
end,
|
||||
Els = Packet#xmlel.children,
|
||||
Caps = mod_caps:read_caps(Els),
|
||||
ServerString = binary_to_list(StateData#state.server),
|
||||
mod_caps:note_caps(ServerString, From, Caps),
|
||||
NewAvailable = case exmpp_presence:get_type(Packet) of
|
||||
'unavailable' ->
|
||||
?DICT:erase(LFrom, StateData#state.pres_available);
|
||||
_ ->
|
||||
%?DICT:store(LFrom, Caps, StateData#state.pres_available)
|
||||
StateData#state.pres_available
|
||||
end,
|
||||
NewStateData = StateData#state{pres_available = NewAvailable},
|
||||
case ?SETS:is_element(
|
||||
LFrom, StateData#state.pres_a) orelse
|
||||
LFrom, NewStateData#state.pres_a) orelse
|
||||
?SETS:is_element(
|
||||
LBFrom, StateData#state.pres_a) of
|
||||
LBFrom, NewStateData#state.pres_a) of
|
||||
true ->
|
||||
{true, Attrs, StateData};
|
||||
{true, Attrs, NewStateData};
|
||||
false ->
|
||||
case ?SETS:is_element(
|
||||
LFrom, StateData#state.pres_f) of
|
||||
LFrom, NewStateData#state.pres_f) of
|
||||
true ->
|
||||
A = ?SETS:add_element(
|
||||
LFrom,
|
||||
StateData#state.pres_a),
|
||||
NewStateData#state.pres_a),
|
||||
{true, Attrs,
|
||||
StateData#state{pres_a = A}};
|
||||
NewStateData#state{pres_a = A}};
|
||||
false ->
|
||||
case ?SETS:is_element(
|
||||
LBFrom, StateData#state.pres_f) of
|
||||
LBFrom, NewStateData#state.pres_f) of
|
||||
true ->
|
||||
A = ?SETS:add_element(
|
||||
LBFrom,
|
||||
StateData#state.pres_a),
|
||||
NewStateData#state.pres_a),
|
||||
{true, Attrs,
|
||||
StateData#state{pres_a = A}};
|
||||
NewStateData#state{pres_a = A}};
|
||||
false ->
|
||||
{true, Attrs, StateData}
|
||||
{true, Attrs, NewStateData}
|
||||
end
|
||||
end
|
||||
end;
|
||||
@ -1080,7 +1132,9 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
?DEBUG("broadcast~n~p~n", [Packet#xmlel.children]),
|
||||
case Packet#xmlel.children of
|
||||
[{item, {U, S, R} = _IJIDShort, ISubscription}] ->
|
||||
IJID = exmpp_jid:make_jid(U, S, R),
|
||||
IJID = exmpp_jid:make_jid(U,
|
||||
S,
|
||||
R),
|
||||
{false, Attrs,
|
||||
roster_change(IJID, ISubscription,
|
||||
StateData)};
|
||||
@ -1108,7 +1162,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
|
||||
true ->
|
||||
case exmpp_iq:get_request(Packet) of
|
||||
#xmlel{ns = ?NS_VCARD} ->
|
||||
Host = StateData#state.server,
|
||||
Host = binary_to_list(StateData#state.server),
|
||||
case ets:lookup(sm_iqtable, {?NS_VCARD, Host}) of
|
||||
[{_, Module, Function, Opts}] ->
|
||||
gen_iq_handler:handle(Host, Module, Function, Opts,
|
||||
@ -1186,6 +1240,7 @@ handle_info(Info, StateName, StateData) ->
|
||||
%% Returns: any
|
||||
%%----------------------------------------------------------------------
|
||||
terminate(_Reason, StateName, StateData) ->
|
||||
%%TODO: resource could be 'undefined' if terminate before bind?
|
||||
case StateName of
|
||||
session_established ->
|
||||
case StateData#state.authenticated of
|
||||
@ -1199,9 +1254,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
"Replaced by new connection"),
|
||||
ejabberd_sm:close_session_unset_presence(
|
||||
StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
StateData#state.jid,
|
||||
"Replaced by new connection"),
|
||||
presence_broadcast(
|
||||
StateData, From, StateData#state.pres_a, Packet1),
|
||||
@ -1219,17 +1272,13 @@ terminate(_Reason, StateName, StateData) ->
|
||||
pres_i = EmptySet,
|
||||
pres_invis = false} ->
|
||||
ejabberd_sm:close_session(StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource);
|
||||
StateData#state.jid);
|
||||
_ ->
|
||||
From = StateData#state.jid,
|
||||
Packet = exmpp_presence:unavailable(),
|
||||
ejabberd_sm:close_session_unset_presence(
|
||||
StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
StateData#state.jid,
|
||||
""),
|
||||
presence_broadcast(
|
||||
StateData, From, StateData#state.pres_a, Packet),
|
||||
@ -1248,7 +1297,7 @@ terminate(_Reason, StateName, StateData) ->
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
change_shaper(StateData, JID) ->
|
||||
Shaper = acl:match_rule(StateData#state.server,
|
||||
Shaper = acl:match_rule(binary_to_list(StateData#state.server),
|
||||
StateData#state.shaper, JID),
|
||||
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
|
||||
|
||||
@ -1257,9 +1306,9 @@ send_text(StateData, Text) ->
|
||||
(StateData#state.sockmod):send(StateData#state.socket, Text).
|
||||
|
||||
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
|
||||
send_text(StateData, exmpp_stream:to_list(El));
|
||||
send_text(StateData, exmpp_stream:to_iolist(El));
|
||||
send_element(StateData, El) ->
|
||||
send_text(StateData, exmpp_stanza:to_list(El)).
|
||||
send_text(StateData, exmpp_stanza:to_iolist(El)).
|
||||
|
||||
|
||||
new_id() ->
|
||||
@ -1372,9 +1421,7 @@ presence_update(From, Packet, StateData) ->
|
||||
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
|
||||
{auth_module, StateData#state.auth_module}],
|
||||
ejabberd_sm:unset_presence(StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
StateData#state.jid,
|
||||
Status,
|
||||
Info),
|
||||
presence_broadcast(StateData, From, StateData#state.pres_a, Packet),
|
||||
@ -1476,8 +1523,6 @@ presence_update(From, Packet, StateData) ->
|
||||
|
||||
presence_track(From, To, Packet, StateData) ->
|
||||
LTo = jlib:short_prepd_jid(To),
|
||||
User = StateData#state.user,
|
||||
Server = StateData#state.server,
|
||||
BFrom = exmpp_jid:jid_to_bare_jid(From),
|
||||
case exmpp_presence:get_type(Packet) of
|
||||
'unavailable' ->
|
||||
@ -1494,26 +1539,26 @@ presence_track(From, To, Packet, StateData) ->
|
||||
pres_a = A};
|
||||
'subscribe' ->
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
Server,
|
||||
[User, Server, To, subscribe]),
|
||||
StateData#state.server,
|
||||
[StateData#state.user, StateData#state.server, To, subscribe]),
|
||||
ejabberd_router:route(BFrom, To, Packet),
|
||||
StateData;
|
||||
'subscribed' ->
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
Server,
|
||||
[User, Server, To, subscribed]),
|
||||
StateData#state.server,
|
||||
[StateData#state.user, StateData#state.server, To, subscribed]),
|
||||
ejabberd_router:route(BFrom, To, Packet),
|
||||
StateData;
|
||||
'unsubscribe' ->
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
Server,
|
||||
[User, Server, To, unsubscribe]),
|
||||
StateData#state.server,
|
||||
[StateData#state.user, StateData#state.server, To, unsubscribe]),
|
||||
ejabberd_router:route(BFrom, To, Packet),
|
||||
StateData;
|
||||
'unsubscribed' ->
|
||||
ejabberd_hooks:run(roster_out_subscription,
|
||||
Server,
|
||||
[User, Server, To, unsubscribed]),
|
||||
StateData#state.server,
|
||||
[StateData#state.user, StateData#state.server, To, unsubscribed]),
|
||||
ejabberd_router:route(BFrom, To, Packet),
|
||||
StateData;
|
||||
'error' ->
|
||||
@ -1718,9 +1763,7 @@ update_priority(Priority, Packet, StateData) ->
|
||||
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
|
||||
{auth_module, StateData#state.auth_module}],
|
||||
ejabberd_sm:set_presence(StateData#state.sid,
|
||||
StateData#state.user,
|
||||
StateData#state.server,
|
||||
StateData#state.resource,
|
||||
StateData#state.jid,
|
||||
Priority,
|
||||
Packet,
|
||||
Info).
|
||||
@ -1732,7 +1775,7 @@ process_privacy_iq(From, To,
|
||||
case Type of
|
||||
get ->
|
||||
R = ejabberd_hooks:run_fold(
|
||||
privacy_iq_get, StateData#state.server,
|
||||
privacy_iq_get, StateData#state.server ,
|
||||
{error, ?ERR_FEATURE_NOT_IMPLEMENTED(IQ_NS)},
|
||||
[From, To, IQ_Rec, StateData#state.privacy_list]),
|
||||
{R, StateData};
|
||||
@ -1761,22 +1804,23 @@ process_privacy_iq(From, To,
|
||||
NewStateData.
|
||||
|
||||
|
||||
resend_offline_messages(#state{user = User,
|
||||
server = Server,
|
||||
resend_offline_messages(#state{user = UserB,
|
||||
server = ServerB,
|
||||
privacy_list = PrivList} = StateData) ->
|
||||
|
||||
case ejabberd_hooks:run_fold(resend_offline_messages_hook,
|
||||
Server,
|
||||
StateData#state.server,
|
||||
[],
|
||||
[User, Server]) of
|
||||
[UserB, ServerB]) of
|
||||
Rs when list(Rs) ->
|
||||
lists:foreach(
|
||||
fun({route,
|
||||
From, To, Packet}) ->
|
||||
Pass = case ejabberd_hooks:run_fold(
|
||||
privacy_check_packet, Server,
|
||||
privacy_check_packet, StateData#state.server,
|
||||
allow,
|
||||
[User,
|
||||
Server,
|
||||
[StateData#state.user,
|
||||
StateData#state.server,
|
||||
PrivList,
|
||||
{From, To, Packet},
|
||||
in]) of
|
||||
@ -1799,13 +1843,13 @@ resend_offline_messages(#state{user = User,
|
||||
end, Rs)
|
||||
end.
|
||||
|
||||
resend_subscription_requests(#state{user = User,
|
||||
server = Server} = StateData) ->
|
||||
resend_subscription_requests(#state{user = UserB,
|
||||
server = ServerB} = StateData) ->
|
||||
PendingSubscriptions = ejabberd_hooks:run_fold(
|
||||
resend_subscription_requests_hook,
|
||||
Server,
|
||||
StateData#state.server,
|
||||
[],
|
||||
[User, Server]),
|
||||
[UserB, ServerB]),
|
||||
lists:foreach(fun(XMLPacket) ->
|
||||
send_element(StateData,
|
||||
XMLPacket)
|
||||
@ -1813,6 +1857,7 @@ resend_subscription_requests(#state{user = User,
|
||||
PendingSubscriptions).
|
||||
|
||||
process_unauthenticated_stanza(StateData, El) when ?IS_IQ(El) ->
|
||||
ServerString = binary_to_list(StateData#state.server),
|
||||
case exmpp_iq:get_kind(El) of
|
||||
request ->
|
||||
IQ_Rec = exmpp_iq:xmlel_to_iq(El),
|
||||
@ -1828,7 +1873,7 @@ process_unauthenticated_stanza(StateData, El) when ?IS_IQ(El) ->
|
||||
ResIQ = exmpp_iq:error_without_original(El,
|
||||
'service-unavailable'),
|
||||
Res1 = exmpp_stanza:set_sender(ResIQ,
|
||||
exmpp_jid:make_bare_jid(StateData#state.server)),
|
||||
exmpp_jid:make_bare_jid(ServerString)),
|
||||
Res2 = exmpp_stanza:remove_recipient(Res1),
|
||||
send_element(StateData, Res2);
|
||||
_ ->
|
||||
|
@ -61,19 +61,21 @@ start_link() ->
|
||||
add(Hook, Module, Function, Seq) ->
|
||||
add(Hook, global, Module, Function, Seq).
|
||||
|
||||
add(Hook, Host, Module, Function, Seq) ->
|
||||
add(Hook, Host, Module, Function, Seq)
|
||||
when is_binary(Host) orelse is_atom(Host) ->
|
||||
gen_server:call(ejabberd_hooks, {add, Hook, Host, Module, Function, Seq}).
|
||||
|
||||
delete(Hook, Module, Function, Seq) ->
|
||||
delete(Hook, global, Module, Function, Seq).
|
||||
|
||||
delete(Hook, Host, Module, Function, Seq) ->
|
||||
delete(Hook, Host, Module, Function, Seq)
|
||||
when is_binary(Host) orelse is_atom(Host) ->
|
||||
gen_server:call(ejabberd_hooks, {delete, Hook, Host, Module, Function, Seq}).
|
||||
|
||||
run(Hook, Args) ->
|
||||
run(Hook, global, Args).
|
||||
|
||||
run(Hook, Host, Args) ->
|
||||
run(Hook, Host, Args) when is_binary(Host) orelse is_atom(Host) ->
|
||||
case ets:lookup(hooks, {Hook, Host}) of
|
||||
[{_, Ls}] ->
|
||||
run1(Ls, Hook, Args);
|
||||
@ -84,7 +86,7 @@ run(Hook, Host, Args) ->
|
||||
run_fold(Hook, Val, Args) ->
|
||||
run_fold(Hook, global, Val, Args).
|
||||
|
||||
run_fold(Hook, Host, Val, Args) ->
|
||||
run_fold(Hook, Host, Val, Args) when is_binary(Host) orelse is_atom(Host) ->
|
||||
case ets:lookup(hooks, {Hook, Host}) of
|
||||
[{_, Ls}] ->
|
||||
run_fold1(Ls, Hook, Val, Args);
|
||||
|
@ -76,7 +76,7 @@ start_link() ->
|
||||
process_iq(From, To, Packet) ->
|
||||
case exmpp_iq:xmlel_to_iq(Packet) of
|
||||
#iq{kind = request, ns = XMLNS} = IQ_Rec ->
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
|
||||
[{_, Module, Function}] ->
|
||||
ResIQ = Module:Function(From, To, IQ_Rec),
|
||||
@ -182,7 +182,7 @@ init([]) ->
|
||||
lists:foreach(
|
||||
fun(Host) ->
|
||||
ejabberd_router:register_route(Host, {apply, ?MODULE, route}),
|
||||
ejabberd_hooks:add(local_send_to_resource_hook, Host,
|
||||
ejabberd_hooks:add(local_send_to_resource_hook, list_to_binary(Host),
|
||||
?MODULE, bounce_resource_packet, 100)
|
||||
end, ?MYHOSTS),
|
||||
catch ets:new(?IQTABLE, [named_table, public]),
|
||||
@ -302,10 +302,13 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
do_route(From, To, Packet) ->
|
||||
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||
[From, To, Packet, 8]),
|
||||
|
||||
LNode = exmpp_jid:lnode(To),
|
||||
LResource = exmpp_jid:lresource(To),
|
||||
if
|
||||
To#jid.lnode /= undefined ->
|
||||
LNode /= undefined ->
|
||||
ejabberd_sm:route(From, To, Packet);
|
||||
To#jid.lresource == undefined ->
|
||||
LResource == undefined ->
|
||||
case Packet of
|
||||
_ when ?IS_IQ(Packet) ->
|
||||
process_iq(From, To, Packet);
|
||||
@ -322,7 +325,7 @@ do_route(From, To, Packet) ->
|
||||
"result" -> ok;
|
||||
_ ->
|
||||
ejabberd_hooks:run(local_send_to_resource_hook,
|
||||
To#jid.ldomain,
|
||||
exmpp_jid:ldomain(To),
|
||||
[From, To, Packet])
|
||||
end
|
||||
end.
|
||||
|
@ -134,13 +134,14 @@ init([Socket, SockMod, Shaper, MaxStanzaSize]) ->
|
||||
%%--------------------------------------------------------------------
|
||||
handle_call({starttls, TLSSocket}, _From,
|
||||
#state{xml_stream_state = XMLStreamState} = State) ->
|
||||
NewXMLStreamState = exmpp_xmlstream:reset(XMLStreamState),
|
||||
NewXMLStreamState = do_reset_stream(XMLStreamState),
|
||||
NewState = State#state{socket = TLSSocket,
|
||||
sock_mod = tls,
|
||||
xml_stream_state = NewXMLStreamState},
|
||||
case tls:recv_data(TLSSocket, "") of
|
||||
{ok, TLSData} ->
|
||||
{reply, ok, process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT};
|
||||
{NextState, Hib} = process_data(TLSData, NewState),
|
||||
{reply, ok, NextState, Hib};
|
||||
{error, _Reason} ->
|
||||
{stop, normal, ok, NewState}
|
||||
end;
|
||||
@ -152,7 +153,8 @@ handle_call({compress, ZlibSocket}, _From,
|
||||
xml_stream_state = NewXMLStreamState},
|
||||
case ejabberd_zlib:recv_data(ZlibSocket, "") of
|
||||
{ok, ZlibData} ->
|
||||
{reply, ok, process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT};
|
||||
{NextState, Hib} = process_data(ZlibData, NewState),
|
||||
{reply, ok, NextState, Hib};
|
||||
{error, _Reason} ->
|
||||
{stop, normal, ok, NewState}
|
||||
end;
|
||||
@ -164,7 +166,10 @@ handle_call(reset_stream, _From,
|
||||
?HIBERNATE_TIMEOUT};
|
||||
handle_call({become_controller, C2SPid}, _From, State) ->
|
||||
Parser = exmpp_xml:start_parser([
|
||||
names_as_atom,
|
||||
{names_as_atom, true},
|
||||
{check_nss, xmpp},
|
||||
{check_elems, xmpp},
|
||||
{check_attrs, xmpp},
|
||||
{max_size, State#state.max_stanza_size}
|
||||
]),
|
||||
XMLStreamState = exmpp_xmlstream:start(
|
||||
@ -208,21 +213,22 @@ handle_info({Tag, _TCPSocket, Data},
|
||||
tls ->
|
||||
case tls:recv_data(Socket, Data) of
|
||||
{ok, TLSData} ->
|
||||
{noreply, process_data(TLSData, State),
|
||||
?HIBERNATE_TIMEOUT};
|
||||
{NextState, Hib} = process_data(TLSData, State),
|
||||
{noreply, NextState, Hib};
|
||||
{error, _Reason} ->
|
||||
{stop, normal, State}
|
||||
end;
|
||||
ejabberd_zlib ->
|
||||
case ejabberd_zlib:recv_data(Socket, Data) of
|
||||
{ok, ZlibData} ->
|
||||
{noreply, process_data(ZlibData, State),
|
||||
?HIBERNATE_TIMEOUT};
|
||||
{NextState, Hib} = process_data(ZlibData, State),
|
||||
{noreply, NextState, Hib};
|
||||
{error, _Reason} ->
|
||||
{stop, normal, State}
|
||||
end;
|
||||
_ ->
|
||||
{noreply, process_data(Data, State), ?HIBERNATE_TIMEOUT}
|
||||
{NextState, Hib} = process_data(Data, State),
|
||||
{noreply, NextState, Hib}
|
||||
end;
|
||||
handle_info({Tag, _TCPSocket}, State)
|
||||
when (Tag == tcp_closed) or (Tag == ssl_closed) ->
|
||||
@ -239,8 +245,8 @@ handle_info({timeout, _Ref, activate}, State) ->
|
||||
activate_socket(State),
|
||||
{noreply, State, ?HIBERNATE_TIMEOUT};
|
||||
handle_info(timeout, State) ->
|
||||
proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]),
|
||||
{noreply, State, ?HIBERNATE_TIMEOUT};
|
||||
{noreply, State, hibernate};
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State, ?HIBERNATE_TIMEOUT}.
|
||||
|
||||
@ -299,19 +305,30 @@ process_data(Data,
|
||||
?DEBUG("Received XML on stream = ~p", [binary_to_list(Data)]),
|
||||
{ok, XMLStreamState1} = exmpp_xmlstream:parse(XMLStreamState, Data),
|
||||
{NewShaperState, Pause} = shaper:update(ShaperState, size(Data)),
|
||||
if
|
||||
C2SPid == undefined ->
|
||||
ok;
|
||||
Pause > 0 ->
|
||||
erlang:start_timer(Pause, self(), activate);
|
||||
true ->
|
||||
activate_socket(State)
|
||||
end,
|
||||
State#state{xml_stream_state = XMLStreamState1,
|
||||
shaper_state = NewShaperState}.
|
||||
HibTimeout =
|
||||
if
|
||||
C2SPid == undefined ->
|
||||
infinity;
|
||||
Pause > 0 ->
|
||||
erlang:start_timer(Pause, self(), activate),
|
||||
hibernate;
|
||||
|
||||
true ->
|
||||
activate_socket(State),
|
||||
?HIBERNATE_TIMEOUT
|
||||
end,
|
||||
{State#state{xml_stream_state = XMLStreamState1,
|
||||
shaper_state = NewShaperState}, HibTimeout}.
|
||||
|
||||
close_stream(undefined) ->
|
||||
ok;
|
||||
close_stream(XMLStreamState) ->
|
||||
exmpp_xml:stop_parser(exmpp_xmlstream:get_parser(XMLStreamState)),
|
||||
exmpp_xmlstream:stop(XMLStreamState).
|
||||
|
||||
|
||||
do_reset_stream(undefined) ->
|
||||
undefined;
|
||||
|
||||
do_reset_stream(XMLStreamState) ->
|
||||
exmpp_xmlstream:reset(XMLStreamState).
|
||||
|
@ -89,27 +89,28 @@ register_route(Domain) ->
|
||||
register_route(Domain, LocalHint) ->
|
||||
try
|
||||
LDomain = exmpp_stringprep:nameprep(Domain),
|
||||
LDomainB = list_to_binary(LDomain),
|
||||
Pid = self(),
|
||||
case get_component_number(LDomain) of
|
||||
undefined ->
|
||||
F = fun() ->
|
||||
mnesia:write(#route{domain = LDomain,
|
||||
mnesia:write(#route{domain = LDomainB,
|
||||
pid = Pid,
|
||||
local_hint = LocalHint})
|
||||
end,
|
||||
mnesia:transaction(F);
|
||||
N ->
|
||||
F = fun() ->
|
||||
case mnesia:read({route, LDomain}) of
|
||||
case mnesia:read({route, LDomainB}) of
|
||||
[] ->
|
||||
mnesia:write(
|
||||
#route{domain = LDomain,
|
||||
#route{domain = LDomainB,
|
||||
pid = Pid,
|
||||
local_hint = 1}),
|
||||
lists:foreach(
|
||||
fun(I) ->
|
||||
mnesia:write(
|
||||
#route{domain = LDomain,
|
||||
#route{domain = LDomainB,
|
||||
pid = undefined,
|
||||
local_hint = I})
|
||||
end, lists:seq(2, N));
|
||||
@ -118,7 +119,7 @@ register_route(Domain, LocalHint) ->
|
||||
fun(#route{pid = undefined,
|
||||
local_hint = I} = R) ->
|
||||
mnesia:write(
|
||||
#route{domain = LDomain,
|
||||
#route{domain = LDomainB,
|
||||
pid = Pid,
|
||||
local_hint = I}),
|
||||
mnesia:delete_object(R),
|
||||
@ -143,12 +144,13 @@ register_routes(Domains) ->
|
||||
unregister_route(Domain) ->
|
||||
try
|
||||
LDomain = exmpp_stringprep:nameprep(Domain),
|
||||
LDomainB = list_to_binary(LDomain),
|
||||
Pid = self(),
|
||||
case get_component_number(LDomain) of
|
||||
undefined ->
|
||||
F = fun() ->
|
||||
case mnesia:match_object(
|
||||
#route{domain = LDomain,
|
||||
#route{domain = LDomainB,
|
||||
pid = Pid,
|
||||
_ = '_'}) of
|
||||
[R] ->
|
||||
@ -160,13 +162,13 @@ unregister_route(Domain) ->
|
||||
mnesia:transaction(F);
|
||||
_ ->
|
||||
F = fun() ->
|
||||
case mnesia:match_object(#route{domain=LDomain,
|
||||
case mnesia:match_object(#route{domain=LDomainB,
|
||||
pid = Pid,
|
||||
_ = '_'}) of
|
||||
[R] ->
|
||||
I = R#route.local_hint,
|
||||
mnesia:write(
|
||||
#route{domain = LDomain,
|
||||
#route{domain = LDomainB,
|
||||
pid = undefined,
|
||||
local_hint = I}),
|
||||
mnesia:delete_object(R);
|
||||
@ -188,10 +190,14 @@ unregister_routes(Domains) ->
|
||||
|
||||
|
||||
dirty_get_all_routes() ->
|
||||
lists:usort(mnesia:dirty_all_keys(route)) -- ?MYHOSTS.
|
||||
lists:usort(
|
||||
lists:map(fun erlang:binary_to_list/1,
|
||||
mnesia:dirty_all_keys(route))) -- ?MYHOSTS.
|
||||
|
||||
dirty_get_all_domains() ->
|
||||
lists:usort(mnesia:dirty_all_keys(route)).
|
||||
lists:usort(
|
||||
lists:map(fun erlang:binary_to_list/1,
|
||||
mnesia:dirty_all_keys(route))).
|
||||
|
||||
|
||||
%%====================================================================
|
||||
@ -326,8 +332,8 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
|
||||
case ejabberd_hooks:run_fold(filter_packet,
|
||||
{OrigFrom, OrigTo, OrigPacket}, []) of
|
||||
{From, To, Packet} ->
|
||||
LDstDomain = To#jid.ldomain,
|
||||
case mnesia:dirty_read(route, LDstDomain) of
|
||||
LDomain = exmpp_jid:ldomain(To),
|
||||
case mnesia:dirty_read(route, LDomain) of
|
||||
[] ->
|
||||
ejabberd_s2s:route(From, To, Packet);
|
||||
[R] ->
|
||||
@ -346,6 +352,7 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
|
||||
drop
|
||||
end;
|
||||
Rs ->
|
||||
LDstDomain = exmpp_jid:ldomain_as_list(To),
|
||||
Value = case ejabberd_config:get_local_option(
|
||||
{domain_balancing, LDstDomain}) of
|
||||
undefined -> now();
|
||||
|
@ -281,7 +281,7 @@ do_route(From, To, Packet) ->
|
||||
?DEBUG("sending to process ~p~n", [Pid]),
|
||||
NewPacket1 = exmpp_stanza:set_sender(Packet, From),
|
||||
NewPacket = exmpp_stanza:set_recipient(NewPacket1, To),
|
||||
#jid{ldomain = MyServer} = From,
|
||||
MyServer = exmpp_jid:ldomain(From),
|
||||
ejabberd_hooks:run(
|
||||
s2s_send_packet,
|
||||
MyServer,
|
||||
@ -301,8 +301,8 @@ do_route(From, To, Packet) ->
|
||||
end.
|
||||
|
||||
find_connection(From, To) ->
|
||||
#jid{ldomain = MyServer} = From,
|
||||
#jid{ldomain = Server} = To,
|
||||
MyServer = exmpp_jid:ldomain_as_list(From),
|
||||
Server = exmpp_jid:ldomain_as_list(To),
|
||||
FromTo = {MyServer, Server},
|
||||
MaxS2SConnectionsNumber = max_s2s_connections_number(FromTo),
|
||||
MaxS2SConnectionsNumberPerNode =
|
||||
@ -430,12 +430,12 @@ needed_connections_number(Ls, MaxS2SConnectionsNumber,
|
||||
%% service.
|
||||
%% --------------------------------------------------------------------
|
||||
is_service(From, To) ->
|
||||
LFromDomain = From#jid.ldomain,
|
||||
LFromDomain = exmpp_jid:ldomain_as_list(From),
|
||||
case ejabberd_config:get_local_option({route_subdomains, LFromDomain}) of
|
||||
s2s -> % bypass RFC 3920 10.3
|
||||
false;
|
||||
_ ->
|
||||
LDstDomain = To#jid.ldomain,
|
||||
LDstDomain = exmpp_jid:ldomain_as_list(To),
|
||||
P = fun(Domain) -> is_subdomain(LDstDomain, Domain) end,
|
||||
lists:any(P, ?MYHOSTS)
|
||||
end.
|
||||
|
@ -390,8 +390,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
||||
% This is handled by C2S and S2S send_element functions.
|
||||
if
|
||||
(To /= error) and (From /= error) ->
|
||||
LFrom = From#jid.ldomain,
|
||||
LTo = To#jid.ldomain,
|
||||
LFrom = exmpp_jid:ldomain_as_list(From),
|
||||
LTo = exmpp_jid:ldomain_as_list(To),
|
||||
if
|
||||
StateData#state.authenticated ->
|
||||
case (LFrom == StateData#state.auth_domain)
|
||||
@ -406,7 +406,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
||||
(Name == 'presence')) ->
|
||||
ejabberd_hooks:run(
|
||||
s2s_receive_packet,
|
||||
LFrom,
|
||||
exmpp_jid:ldomain(From),
|
||||
[From, To, El]),
|
||||
ejabberd_router:route(
|
||||
From, To, El);
|
||||
@ -426,7 +426,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
||||
(Name == 'presence')) ->
|
||||
ejabberd_hooks:run(
|
||||
s2s_receive_packet,
|
||||
LFrom,
|
||||
exmpp_jid:ldomain(From),
|
||||
[From, To, El]),
|
||||
ejabberd_router:route(
|
||||
From, To, El);
|
||||
@ -612,10 +612,11 @@ get_cert_domains(Cert) ->
|
||||
end,
|
||||
if
|
||||
D /= error ->
|
||||
case exmpp_jid:list_to_jid(D) of
|
||||
#jid{lnode = undefined,
|
||||
ldomain = LD,
|
||||
lresource = undefined} ->
|
||||
JID = exmpp_jid:list_to_jid(D),
|
||||
case {exmpp_jid:lnode_as_list(JID),
|
||||
exmpp_jid:ldomain_as_list(JID),
|
||||
exmpp_jid:lresource_as_list(JID)} of
|
||||
{undefined, LD, undefined} ->
|
||||
[LD];
|
||||
_ ->
|
||||
[]
|
||||
@ -647,11 +648,11 @@ get_cert_domains(Cert) ->
|
||||
case 'XmppAddr':decode(
|
||||
'XmppAddr', XmppAddr) of
|
||||
{ok, D} when is_binary(D) ->
|
||||
case exmpp_jid:list_to_jid(
|
||||
binary_to_list(D)) of
|
||||
#jid{lnode = undefined,
|
||||
ldomain = LD,
|
||||
lresource = undefined} ->
|
||||
JID2 = exmpp_jid:list_to_jid(binary_to_list(D)),
|
||||
case {exmpp_jid:lnode_as_list(JID2),
|
||||
exmpp_jid:ldomain_as_list(JID2),
|
||||
exmpp_jid:lresource_as_list(JID2)} of
|
||||
{ undefined, LD, undefined} ->
|
||||
case idna:domain_utf8_to_ascii(LD) of
|
||||
false ->
|
||||
[];
|
||||
@ -665,10 +666,11 @@ get_cert_domains(Cert) ->
|
||||
[]
|
||||
end;
|
||||
({dNSName, D}) when is_list(D) ->
|
||||
case exmpp_jid:list_to_jid(D) of
|
||||
#jid{lnode = undefined,
|
||||
ldomain = LD,
|
||||
lresource = undefined} ->
|
||||
JID3 = exmpp_jid:list_to_jid(D),
|
||||
case {exmpp_jid:lnode_as_list(JID3),
|
||||
exmpp_jid:ldomain_as_list(JID3),
|
||||
exmpp_jid:lresource_as_list(JID3)} of
|
||||
{undefined, LD, undefined} ->
|
||||
[LD];
|
||||
_ ->
|
||||
[]
|
||||
|
@ -231,14 +231,11 @@ stream_established({xmlstreamelement, El}, StateData) ->
|
||||
%% The default is the standard behaviour in XEP-0114
|
||||
_ ->
|
||||
FromJID1 = exmpp_jib:string_to_jid(From),
|
||||
case FromJID1 of
|
||||
#jid{ldomain = Server} ->
|
||||
case lists:member(Server, StateData#state.hosts) of
|
||||
Server = exmpp_jid:ldomain_as_list(FromJID1),
|
||||
case lists:member(Server, StateData#state.hosts) of
|
||||
true -> FromJID1;
|
||||
false -> error
|
||||
end;
|
||||
_ -> error
|
||||
end
|
||||
end
|
||||
end,
|
||||
To = exmpp_stanza:get_recipient(El),
|
||||
ToJID = case To of
|
||||
|
@ -32,14 +32,14 @@
|
||||
%% API
|
||||
-export([start_link/0,
|
||||
route/3,
|
||||
open_session/5, close_session/4,
|
||||
open_session/3, close_session/2,
|
||||
check_in_subscription/6,
|
||||
bounce_offline_message/3,
|
||||
disconnect_removed_user/2,
|
||||
get_user_resources/2,
|
||||
set_presence/7,
|
||||
unset_presence/6,
|
||||
close_session_unset_presence/5,
|
||||
set_presence/5,
|
||||
unset_presence/4,
|
||||
close_session_unset_presence/3,
|
||||
dirty_get_sessions_list/0,
|
||||
dirty_get_my_sessions_list/0,
|
||||
get_vh_session_list/1,
|
||||
@ -49,9 +49,9 @@
|
||||
connected_users/0,
|
||||
connected_users_number/0,
|
||||
user_resources/2,
|
||||
get_session_pid/3,
|
||||
get_session_pid/1,
|
||||
get_user_info/3,
|
||||
get_user_ip/3
|
||||
get_user_ip/1
|
||||
]).
|
||||
|
||||
%% gen_server callbacks
|
||||
@ -76,6 +76,9 @@
|
||||
{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
|
||||
]).
|
||||
|
||||
|
||||
-define(IS_BINARY_OR_UNDEF(X),
|
||||
(is_binary(X) orelse X == 'undefined')).
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
@ -105,14 +108,13 @@ route(From, To, Packet) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
open_session(SID, User, Server, Resource, Info) ->
|
||||
set_session(SID, User, Server, Resource, undefined, Info),
|
||||
check_for_sessions_to_replace(User, Server, Resource),
|
||||
JID = exmpp_jid:make_jid(User, Server, Resource),
|
||||
ejabberd_hooks:run(sm_register_connection_hook, JID#jid.ldomain,
|
||||
open_session(SID, JID, Info) when ?IS_JID(JID) ->
|
||||
set_session(SID, JID, undefined, Info),
|
||||
check_for_sessions_to_replace(JID),
|
||||
ejabberd_hooks:run(sm_register_connection_hook, exmpp_jid:ldomain(JID),
|
||||
[SID, JID, Info]).
|
||||
|
||||
close_session(SID, User, Server, Resource) ->
|
||||
close_session(SID, JID ) when ?IS_JID(JID)->
|
||||
Info = case mnesia:dirty_read({session, SID}) of
|
||||
[] -> [];
|
||||
[#session{info=I}] -> I
|
||||
@ -121,12 +123,12 @@ close_session(SID, User, Server, Resource) ->
|
||||
mnesia:delete({session, SID})
|
||||
end,
|
||||
mnesia:sync_dirty(F),
|
||||
JID = exmpp_jid:make_jid(User, Server, Resource),
|
||||
ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.ldomain,
|
||||
ejabberd_hooks:run(sm_remove_connection_hook, exmpp_jid:ldomain(JID),
|
||||
[SID, JID, Info]).
|
||||
|
||||
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
|
||||
case ejabberd_auth:is_user_exists(User, Server) of
|
||||
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason)
|
||||
when is_binary(User), is_binary(Server)->
|
||||
case ejabberd_auth:is_user_exists(binary_to_list(User), binary_to_list(Server)) of
|
||||
true ->
|
||||
Acc;
|
||||
false ->
|
||||
@ -139,27 +141,26 @@ bounce_offline_message(From, To, Packet) ->
|
||||
stop.
|
||||
|
||||
disconnect_removed_user(User, Server) ->
|
||||
ejabberd_sm:route(#jid{},
|
||||
exmpp_jid:make_bare_jid(User, Server),
|
||||
ejabberd_sm:route(exmpp_jid:make_jid(),
|
||||
exmpp_jid:make_bare_jid(User,
|
||||
Server),
|
||||
#xmlel{name = 'broadcast',
|
||||
children = [{exit, "User removed"}]}).
|
||||
|
||||
get_user_resources(User, Server) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
get_user_resources(User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
US = {User, Server},
|
||||
case catch mnesia:dirty_index_read(session, US, #session.us) of
|
||||
{'EXIT', _Reason} ->
|
||||
[];
|
||||
Ss ->
|
||||
[element(3, S#session.usr) || S <- clean_session_list(Ss)]
|
||||
[binary_to_list(element(3, S#session.usr)) || S <- clean_session_list(Ss)]
|
||||
end.
|
||||
|
||||
get_user_ip(User, Server, Resource) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LResource = exmpp_stringprep:resourceprep(Resource),
|
||||
USR = {LUser, LServer, LResource},
|
||||
get_user_ip(JID) when ?IS_JID(JID) ->
|
||||
USR = {exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID)},
|
||||
case mnesia:dirty_index_read(session, USR, #session.usr) of
|
||||
[] ->
|
||||
undefined;
|
||||
@ -168,11 +169,16 @@ get_user_ip(User, Server, Resource) ->
|
||||
proplists:get_value(ip, Session#session.info)
|
||||
end.
|
||||
|
||||
get_user_info(User, Server, Resource) ->
|
||||
get_user_info(User, Server, Resource)
|
||||
when is_binary(User),
|
||||
is_binary(Server),
|
||||
is_binary(Resource) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LResource = exmpp_stringprep:resourceprep(Resource),
|
||||
USR = {LUser, LServer, LResource},
|
||||
USR = {list_to_binary(LUser),
|
||||
list_to_binary(LServer),
|
||||
list_to_binary(LResource)},
|
||||
case mnesia:dirty_index_read(session, USR, #session.usr) of
|
||||
[] ->
|
||||
offline;
|
||||
@ -184,26 +190,37 @@ get_user_info(User, Server, Resource) ->
|
||||
[{node, Node}, {conn, Conn}, {ip, IP}]
|
||||
end.
|
||||
|
||||
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
|
||||
set_session(SID, User, Server, Resource, Priority, Info),
|
||||
ejabberd_hooks:run(set_presence_hook, exmpp_stringprep:nameprep(Server),
|
||||
[User, Server, Resource, Presence]).
|
||||
set_presence(SID, JID, Priority, Presence, Info) when ?IS_JID(JID) ->
|
||||
set_session(SID, JID, Priority, Info),
|
||||
ejabberd_hooks:run(set_presence_hook,
|
||||
exmpp_jid:ldomain(JID),
|
||||
[exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID),
|
||||
Presence]).
|
||||
|
||||
unset_presence(SID, User, Server, Resource, Status, Info) ->
|
||||
set_session(SID, User, Server, Resource, undefined, Info),
|
||||
ejabberd_hooks:run(unset_presence_hook, exmpp_stringprep:nameprep(Server),
|
||||
[User, Server, Resource, Status]).
|
||||
unset_presence(SID, JID, Status, Info) when ?IS_JID(JID)->
|
||||
set_session(SID, JID, undefined, Info),
|
||||
ejabberd_hooks:run(unset_presence_hook,
|
||||
exmpp_jid:ldomain(JID),
|
||||
[exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID),
|
||||
Status]).
|
||||
|
||||
close_session_unset_presence(SID, User, Server, Resource, Status) ->
|
||||
close_session(SID, User, Server, Resource),
|
||||
ejabberd_hooks:run(unset_presence_hook, exmpp_stringprep:nameprep(Server),
|
||||
[User, Server, Resource, Status]).
|
||||
close_session_unset_presence(SID, JID, Status) when ?IS_JID(JID) ->
|
||||
close_session(SID, JID),
|
||||
ejabberd_hooks:run(unset_presence_hook,
|
||||
exmpp_jid:ldomain(JID),
|
||||
[exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID),
|
||||
Status]).
|
||||
|
||||
get_session_pid(User, Server, Resource) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LResource = exmpp_stringprep:resourceprep(Resource),
|
||||
USR = {LUser, LServer, LResource},
|
||||
get_session_pid(JID) when ?IS_JID(JID) ->
|
||||
USR = {exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID)},
|
||||
case catch mnesia:dirty_index_read(session, USR, #session.usr) of
|
||||
[#session{sid = {_, Pid}}] -> Pid;
|
||||
_ -> none
|
||||
@ -223,8 +240,9 @@ dirty_get_my_sessions_list() ->
|
||||
[{'==', {node, '$1'}, node()}],
|
||||
['$_']}]).
|
||||
|
||||
get_vh_session_list(Server) ->
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
get_vh_session_list(Server) when is_binary(Server) ->
|
||||
LServer = list_to_binary(
|
||||
exmpp_stringprep:nameprep(Server)),
|
||||
mnesia:dirty_select(
|
||||
session,
|
||||
[{#session{usr = '$1', _ = '_'},
|
||||
@ -264,11 +282,12 @@ init([]) ->
|
||||
ets:new(sm_iqtable, [named_table]),
|
||||
lists:foreach(
|
||||
fun(Host) ->
|
||||
ejabberd_hooks:add(roster_in_subscription, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:add(roster_in_subscription, HostB,
|
||||
ejabberd_sm, check_in_subscription, 20),
|
||||
ejabberd_hooks:add(offline_message_hook, Host,
|
||||
ejabberd_hooks:add(offline_message_hook, HostB,
|
||||
ejabberd_sm, bounce_offline_message, 100),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
ejabberd_sm, disconnect_removed_user, 100)
|
||||
end, ?MYHOSTS),
|
||||
ejabberd_commands:register_commands(commands()),
|
||||
@ -365,12 +384,11 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
set_session(SID, User, Server, Resource, Priority, Info) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LResource = exmpp_stringprep:resourceprep(Resource),
|
||||
US = {LUser, LServer},
|
||||
USR = {LUser, LServer, LResource},
|
||||
set_session(SID, JID, Priority, Info) ->
|
||||
US = {exmpp_jid:node(JID), exmpp_jid:ldomain(JID)},
|
||||
USR = {exmpp_jid:node(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID)},
|
||||
F = fun() ->
|
||||
mnesia:write(#session{sid = SID,
|
||||
usr = USR,
|
||||
@ -398,9 +416,7 @@ clean_table_from_bad_node(Node) ->
|
||||
do_route(From, To, Packet) ->
|
||||
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
|
||||
[From, To, Packet, 8]),
|
||||
#jid{node = User, domain = Server,
|
||||
lnode = LUser, ldomain = LServer, lresource = LResource} = To,
|
||||
case LResource of
|
||||
case exmpp_jid:lresource(To) of
|
||||
undefined ->
|
||||
case Packet of
|
||||
_ when ?IS_PRESENCE(Packet) ->
|
||||
@ -410,37 +426,37 @@ do_route(From, To, Packet) ->
|
||||
Reason = exmpp_presence:get_status(Packet),
|
||||
{ejabberd_hooks:run_fold(
|
||||
roster_in_subscription,
|
||||
LServer,
|
||||
exmpp_jid:ldomain(To),
|
||||
false,
|
||||
[User, Server, From, subscribe, Reason]),
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, subscribe, Reason]),
|
||||
true};
|
||||
'subscribed' ->
|
||||
{ejabberd_hooks:run_fold(
|
||||
roster_in_subscription,
|
||||
LServer,
|
||||
exmpp_jid:ldomain(To),
|
||||
false,
|
||||
[User, Server, From, subscribed, <<>>]),
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, subscribed, <<>>]),
|
||||
true};
|
||||
'unsubscribe' ->
|
||||
{ejabberd_hooks:run_fold(
|
||||
roster_in_subscription,
|
||||
LServer,
|
||||
exmpp_jid:ldomain(To),
|
||||
false,
|
||||
[User, Server, From, unsubscribe, <<>>]),
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, unsubscribe, <<>>]),
|
||||
true};
|
||||
'unsubscribed' ->
|
||||
{ejabberd_hooks:run_fold(
|
||||
roster_in_subscription,
|
||||
LServer,
|
||||
exmpp_jid:ldomain(To),
|
||||
false,
|
||||
[User, Server, From, unsubscribed, <<>>]),
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, unsubscribed, <<>>]),
|
||||
true};
|
||||
_ ->
|
||||
{true, false}
|
||||
end,
|
||||
if Pass ->
|
||||
PResources = get_user_present_resources(
|
||||
LUser, LServer),
|
||||
exmpp_jid:lnode(To), exmpp_jid:ldomain(To)),
|
||||
lists:foreach(
|
||||
fun({_, R}) ->
|
||||
do_route(
|
||||
@ -461,12 +477,15 @@ do_route(From, To, Packet) ->
|
||||
do_route(From,
|
||||
exmpp_jid:bare_jid_to_jid(To, R),
|
||||
Packet)
|
||||
end, get_user_resources(User, Server));
|
||||
end, get_user_resources(exmpp_jid:lnode(To),
|
||||
exmpp_jid:ldomain(To)));
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
USR = {LUser, LServer, LResource},
|
||||
USR = {exmpp_jid:lnode(To),
|
||||
exmpp_jid:ldomain(To),
|
||||
exmpp_jid:lresource(To)},
|
||||
case mnesia:dirty_index_read(session, USR, #session.usr) of
|
||||
[] ->
|
||||
case Packet of
|
||||
@ -494,8 +513,8 @@ do_route(From, To, Packet) ->
|
||||
end.
|
||||
|
||||
route_message(From, To, Packet) ->
|
||||
LUser = To#jid.lnode,
|
||||
LServer = To#jid.ldomain,
|
||||
LUser = exmpp_jid:lnode(To),
|
||||
LServer = exmpp_jid:ldomain(To),
|
||||
PrioRes = get_user_present_resources(LUser, LServer),
|
||||
case catch lists:max(PrioRes) of
|
||||
{Priority, _R} when is_integer(Priority), Priority >= 0 ->
|
||||
@ -503,8 +522,7 @@ route_message(From, To, Packet) ->
|
||||
%% Route messages to all priority that equals the max, if
|
||||
%% positive
|
||||
fun({P, R}) when P == Priority ->
|
||||
LResource = exmpp_stringprep:resourceprep(R),
|
||||
USR = {LUser, LServer, LResource},
|
||||
USR = {LUser, LServer, R},
|
||||
case mnesia:dirty_index_read(session, USR, #session.usr) of
|
||||
[] ->
|
||||
ok; % Race condition
|
||||
@ -528,10 +546,11 @@ route_message(From, To, Packet) ->
|
||||
'headline' ->
|
||||
bounce_offline_message(From, To, Packet);
|
||||
_ ->
|
||||
case ejabberd_auth:is_user_exists(LUser, LServer) of
|
||||
case ejabberd_auth:is_user_exists(exmpp_jid:lnode_as_list(To),
|
||||
exmpp_jid:ldomain_as_list(To)) of
|
||||
true ->
|
||||
ejabberd_hooks:run(offline_message_hook,
|
||||
LServer,
|
||||
exmpp_jid:ldomain(To),
|
||||
[From, To, Packet]);
|
||||
_ ->
|
||||
Err = exmpp_stanza:reply_with_error(
|
||||
@ -580,18 +599,16 @@ get_user_present_resources(LUser, LServer) ->
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
%% On new session, check if some existing connections need to be replace
|
||||
check_for_sessions_to_replace(User, Server, Resource) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LResource = exmpp_stringprep:resourceprep(Resource),
|
||||
|
||||
check_for_sessions_to_replace(JID) ->
|
||||
%% TODO: Depending on how this is executed, there could be an unneeded
|
||||
%% replacement for max_sessions. We need to check this at some point.
|
||||
check_existing_resources(LUser, LServer, LResource),
|
||||
check_max_sessions(LUser, LServer).
|
||||
check_existing_resources(JID),
|
||||
check_max_sessions(JID).
|
||||
|
||||
check_existing_resources(LUser, LServer, LResource) ->
|
||||
USR = {LUser, LServer, LResource},
|
||||
check_existing_resources(JID) ->
|
||||
USR = {exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID)},
|
||||
%% A connection exist with the same resource. We replace it:
|
||||
SIDs = mnesia:dirty_select(
|
||||
session,
|
||||
@ -607,14 +624,16 @@ check_existing_resources(LUser, LServer, LResource) ->
|
||||
end, SIDs)
|
||||
end.
|
||||
|
||||
check_max_sessions(LUser, LServer) ->
|
||||
check_max_sessions(JID) ->
|
||||
%% If the max number of sessions for a given is reached, we replace the
|
||||
%% first one
|
||||
SIDs = mnesia:dirty_select(
|
||||
session,
|
||||
[{#session{sid = '$1', us = {LUser, LServer}, _ = '_'}, [],
|
||||
[{#session{sid = '$1',
|
||||
us = {exmpp_jid:lnode(JID), exmpp_jid:ldomain(JID)},
|
||||
_ = '_'}, [],
|
||||
['$1']}]),
|
||||
MaxSessions = get_max_user_sessions(LUser, LServer),
|
||||
MaxSessions = get_max_user_sessions(JID),
|
||||
if
|
||||
length(SIDs) =< MaxSessions ->
|
||||
ok;
|
||||
@ -628,9 +647,9 @@ check_max_sessions(LUser, LServer) ->
|
||||
%% This option defines the max number of time a given users are allowed to
|
||||
%% log in
|
||||
%% Defaults to infinity
|
||||
get_max_user_sessions(LUser, Host) ->
|
||||
get_max_user_sessions(JID) ->
|
||||
case acl:match_rule(
|
||||
Host, max_user_sessions, exmpp_jid:make_bare_jid(LUser, Host)) of
|
||||
exmpp_jid:ldomain_as_list(JID), max_user_sessions, exmpp_jid:jid_to_bare_jid(JID)) of
|
||||
Max when is_integer(Max) -> Max;
|
||||
infinity -> infinity;
|
||||
_ -> ?MAX_USER_SESSIONS
|
||||
@ -642,8 +661,8 @@ get_max_user_sessions(LUser, Host) ->
|
||||
process_iq(From, To, Packet) ->
|
||||
case exmpp_iq:xmlel_to_iq(Packet) of
|
||||
#iq{kind = request, ns = XMLNS} = IQ_Rec ->
|
||||
Host = To#jid.ldomain,
|
||||
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case ets:lookup(sm_iqtable, {XMLNS, LServer}) of
|
||||
[{_, Module, Function}] ->
|
||||
ResIQ = Module:Function(From, To, IQ_Rec),
|
||||
if
|
||||
@ -654,8 +673,8 @@ process_iq(From, To, Packet) ->
|
||||
ok
|
||||
end;
|
||||
[{_, Module, Function, Opts}] ->
|
||||
gen_iq_handler:handle(Host, Module, Function, Opts,
|
||||
From, To, IQ_Rec);
|
||||
gen_iq_handler:handle(LServer,
|
||||
Module, Function, Opts, From, To, IQ_Rec);
|
||||
[] ->
|
||||
Err = exmpp_iq:error(Packet, 'service-unavailable'),
|
||||
ejabberd_router:route(To, From, Err)
|
||||
@ -703,7 +722,8 @@ connected_users_number() ->
|
||||
length(dirty_get_sessions_list()).
|
||||
|
||||
user_resources(User, Server) ->
|
||||
Resources = get_user_resources(User, Server),
|
||||
Resources = get_user_resources(list_to_binary(User),
|
||||
list_to_binary(Server)),
|
||||
lists:sort(Resources).
|
||||
|
||||
|
||||
|
@ -55,12 +55,13 @@ start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
process_command(From, To, Packet) ->
|
||||
case To of
|
||||
#jid{lnode = undefined, lresource = "watchdog"} ->
|
||||
case {exmpp_jid:lnode(To), exmpp_jid:lresource(To) } of
|
||||
{undefined, <<"watchdog">>} ->
|
||||
case Packet#xmlel.name of
|
||||
'message' ->
|
||||
LFrom = jlib:short_prepd_bare_jid(From),
|
||||
case lists:member(LFrom, get_admin_jids()) of
|
||||
case lists:any(fun(J) ->
|
||||
exmpp_jid:compare_jids(J,From)
|
||||
end, get_admin_jids()) of
|
||||
true ->
|
||||
Body = exmpp_xml:get_path(
|
||||
Packet, [{element, 'body'}, cdata_as_list]),
|
||||
@ -95,7 +96,8 @@ init([]) ->
|
||||
erlang:system_monitor(self(), [{large_heap, 1000000}]),
|
||||
lists:foreach(
|
||||
fun(Host) ->
|
||||
ejabberd_hooks:add(local_send_to_resource_hook, Host,
|
||||
ejabberd_hooks:add(local_send_to_resource_hook,
|
||||
list_to_binary(Host),
|
||||
?MODULE, process_command, 50)
|
||||
end, ?MYHOSTS),
|
||||
{ok, #state{}}.
|
||||
@ -168,7 +170,7 @@ process_large_heap(Pid, Info) ->
|
||||
"(~w) The process ~w is consuming too much memory: ~w.~n"
|
||||
"~s",
|
||||
[node(), Pid, Info, DetailedInfo]),
|
||||
From = exmpp_jid:make_jid(undefined, Host, "watchdog"),
|
||||
From = exmpp_jid:make_jid(undefined, Host, <<"watchdog">>),
|
||||
lists:foreach(
|
||||
fun(S) ->
|
||||
try
|
||||
@ -195,7 +197,9 @@ get_admin_jids() ->
|
||||
fun(S) ->
|
||||
try
|
||||
JID = exmpp_jid:list_to_jid(S),
|
||||
[jlib:short_prepd_jid(JID)]
|
||||
[{exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID)}]
|
||||
catch
|
||||
_ ->
|
||||
[]
|
||||
|
52
src/jlib.erl
52
src/jlib.erl
@ -37,7 +37,6 @@
|
||||
encode_base64/1,
|
||||
ip_to_list/1,
|
||||
from_old_jid/1,
|
||||
to_old_jid/1,
|
||||
short_jid/1,
|
||||
short_bare_jid/1,
|
||||
short_prepd_jid/1,
|
||||
@ -295,49 +294,26 @@ ip_to_list({A,B,C,D}) ->
|
||||
%%
|
||||
%% Empty fields are set to `undefined', not the empty string.
|
||||
|
||||
from_old_jid(#jid{node = Node, resource = Resource,
|
||||
lnode = LNode, lresource = LResource} = JID) ->
|
||||
{Node1, LNode1} = case Node of
|
||||
"" -> {undefined, undefined};
|
||||
_ -> {Node, LNode}
|
||||
end,
|
||||
{Resource1, LResource1} = case Resource of
|
||||
"" -> {undefined, undefined};
|
||||
_ -> {Resource, LResource}
|
||||
end,
|
||||
JID#jid{node = Node1, resource = Resource1,
|
||||
lnode = LNode1, lresource = LResource1}.
|
||||
%%TODO: this doesn't make sence!, it is still used?.
|
||||
from_old_jid(JID) ->
|
||||
Node = exmpp_jid:node(JID),
|
||||
Resource = exmpp_jid:resource(JID),
|
||||
Domain = exmpp_jid:domain(JID),
|
||||
exmpp_jid:make_jid(Node,Domain,Resource).
|
||||
|
||||
%% @spec (JID) -> New_JID
|
||||
%% JID = jid()
|
||||
%% New_JID = jid()
|
||||
%% @doc Convert a JID from its exmpp form to its ejabberd form.
|
||||
%%
|
||||
%% Empty fields are set to the empty string, not `undefined'.
|
||||
|
||||
to_old_jid(#jid{node = Node, resource = Resource,
|
||||
lnode = LNode, lresource = LResource} = JID) ->
|
||||
{Node1, LNode1} = case Node of
|
||||
undefined -> {"", ""};
|
||||
_ -> {Node, LNode}
|
||||
end,
|
||||
{Resource1, LResource1} = case Resource of
|
||||
undefined -> {"", ""};
|
||||
_ -> {Resource, LResource}
|
||||
end,
|
||||
JID#jid{node = Node1, resource = Resource1,
|
||||
lnode = LNode1, lresource = LResource1}.
|
||||
|
||||
short_jid(JID) ->
|
||||
{JID#jid.node, JID#jid.domain, JID#jid.resource}.
|
||||
{exmpp_jid:node(JID), exmpp_jid:domain(JID), exmpp_jid:resource(JID)}.
|
||||
|
||||
short_bare_jid(JID) ->
|
||||
Bare_JID = exmpp_jid:jid_to_bare_jid(JID),
|
||||
{Bare_JID#jid.node, Bare_JID#jid.domain, Bare_JID#jid.resource}.
|
||||
short_jid(exmpp_jid:jid_to_bare_jid(JID)).
|
||||
|
||||
short_prepd_jid(JID) ->
|
||||
{JID#jid.lnode, JID#jid.ldomain, JID#jid.lresource}.
|
||||
{exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID),
|
||||
exmpp_jid:lresource(JID)}.
|
||||
|
||||
short_prepd_bare_jid(JID) ->
|
||||
Bare_JID = exmpp_jid:jid_to_bare_jid(JID),
|
||||
{Bare_JID#jid.lnode, Bare_JID#jid.ldomain, Bare_JID#jid.lresource}.
|
||||
short_prepd_jid(exmpp_jid:jid_to_bare_jid(JID)).
|
||||
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
-include("adhoc.hrl").
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ADHOC,
|
||||
@ -55,31 +56,34 @@ start(Host, Opts) ->
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ADHOC,
|
||||
?MODULE, process_sm_iq, IQDisc),
|
||||
|
||||
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
|
||||
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 99),
|
||||
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_commands, 99),
|
||||
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99),
|
||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 99),
|
||||
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_commands, 99),
|
||||
ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, ping_item, 100),
|
||||
ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, ping_command, 100).
|
||||
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, get_local_identity, 99),
|
||||
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, get_local_features, 99),
|
||||
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, get_local_commands, 99),
|
||||
ejabberd_hooks:add(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 99),
|
||||
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 99),
|
||||
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_sm_commands, 99),
|
||||
ejabberd_hooks:add(adhoc_local_items, HostB, ?MODULE, ping_item, 100),
|
||||
ejabberd_hooks:add(adhoc_local_commands, HostB, ?MODULE, ping_command, 100).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, ping_command, 100),
|
||||
ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, ping_item, 100),
|
||||
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_commands, 99),
|
||||
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 99),
|
||||
ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99),
|
||||
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_commands, 99),
|
||||
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 99),
|
||||
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(adhoc_local_commands, HostB, ?MODULE, ping_command, 100),
|
||||
ejabberd_hooks:delete(adhoc_local_items, HostB, ?MODULE, ping_item, 100),
|
||||
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_sm_commands, 99),
|
||||
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 99),
|
||||
ejabberd_hooks:delete(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 99),
|
||||
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, get_local_commands, 99),
|
||||
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, get_local_features, 99),
|
||||
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, get_local_identity, 99),
|
||||
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC).
|
||||
|
||||
%-------------------------------------------------------------------------
|
||||
|
||||
get_local_commands(Acc, _From, #jid{domain = Server, ldomain = LServer} = _To, "", Lang) ->
|
||||
get_local_commands(Acc, _From, To, "", Lang) ->
|
||||
Server = exmpp_jid:domain_as_list(To),
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
|
||||
case Display of
|
||||
false ->
|
||||
@ -98,8 +102,8 @@ get_local_commands(Acc, _From, #jid{domain = Server, ldomain = LServer} = _To, "
|
||||
{result, Items ++ Nodes}
|
||||
end;
|
||||
|
||||
get_local_commands(_Acc, From, #jid{ldomain = LServer} = To, ?NS_ADHOC_s, Lang) ->
|
||||
ejabberd_hooks:run_fold(adhoc_local_items, LServer, {result, []}, [From, To, Lang]);
|
||||
get_local_commands(_Acc, From, To, ?NS_ADHOC_s, Lang) ->
|
||||
ejabberd_hooks:run_fold(adhoc_local_items, exmpp_jid:ldomain(To), {result, []}, [From, To, Lang]);
|
||||
|
||||
get_local_commands(_Acc, _From, _To, "ping", _Lang) ->
|
||||
{result, []};
|
||||
@ -109,7 +113,8 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) ->
|
||||
|
||||
%-------------------------------------------------------------------------
|
||||
|
||||
get_sm_commands(Acc, _From, #jid{ldomain = LServer} = To, "", Lang) ->
|
||||
get_sm_commands(Acc, _From, To, "", Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
|
||||
case Display of
|
||||
false ->
|
||||
@ -128,8 +133,8 @@ get_sm_commands(Acc, _From, #jid{ldomain = LServer} = To, "", Lang) ->
|
||||
{result, Items ++ Nodes}
|
||||
end;
|
||||
|
||||
get_sm_commands(_Acc, From, #jid{ldomain = LServer} = To, ?NS_ADHOC_s, Lang) ->
|
||||
ejabberd_hooks:run_fold(adhoc_sm_items, LServer, {result, []}, [From, To, Lang]);
|
||||
get_sm_commands(_Acc, From, To, ?NS_ADHOC_s, Lang) ->
|
||||
ejabberd_hooks:run_fold(adhoc_sm_items, exmpp_jid:ldomain(To), {result, []}, [From, To, Lang]);
|
||||
|
||||
get_sm_commands(Acc, _From, _To, _Node, _Lang) ->
|
||||
Acc.
|
||||
@ -216,8 +221,7 @@ process_adhoc_request(From, To, IQ_Rec, Hook) ->
|
||||
{error, Error} ->
|
||||
exmpp_iq:error(IQ_Rec, Error);
|
||||
#adhoc_request{} = AdhocRequest ->
|
||||
Host = To#jid.ldomain,
|
||||
case ejabberd_hooks:run_fold(Hook, Host, empty,
|
||||
case ejabberd_hooks:run_fold(Hook, exmpp_jid:ldomain(To), empty,
|
||||
[From, To, AdhocRequest]) of
|
||||
ignore ->
|
||||
ignore;
|
||||
@ -231,7 +235,8 @@ process_adhoc_request(From, To, IQ_Rec, Hook) ->
|
||||
end.
|
||||
|
||||
|
||||
ping_item(Acc, _From, #jid{domain = Server} = _To, Lang) ->
|
||||
ping_item(Acc, _From, To, Lang) ->
|
||||
Server = exmpp_jid:domain_as_list(To),
|
||||
Items = case Acc of
|
||||
{result, I} ->
|
||||
I;
|
||||
|
@ -59,19 +59,20 @@
|
||||
tokenize(Node) -> string:tokens(Node, "/#").
|
||||
|
||||
start(Host, _Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
mnesia:create_table(motd, [{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, motd)}]),
|
||||
mnesia:create_table(motd_users, [{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, motd_users)}]),
|
||||
update_tables(),
|
||||
ejabberd_hooks:add(local_send_to_resource_hook, Host,
|
||||
ejabberd_hooks:add(local_send_to_resource_hook, HostB,
|
||||
?MODULE, announce, 50),
|
||||
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 50),
|
||||
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
|
||||
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 50),
|
||||
ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, announce_items, 50),
|
||||
ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
|
||||
ejabberd_hooks:add(user_available_hook, Host,
|
||||
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, disco_identity, 50),
|
||||
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, disco_features, 50),
|
||||
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, disco_items, 50),
|
||||
ejabberd_hooks:add(adhoc_local_items, HostB, ?MODULE, announce_items, 50),
|
||||
ejabberd_hooks:add(adhoc_local_commands, HostB, ?MODULE, announce_commands, 50),
|
||||
ejabberd_hooks:add(user_available_hook, HostB,
|
||||
?MODULE, send_motd, 50),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
proc_lib:spawn(?MODULE, init, [])).
|
||||
@ -116,14 +117,15 @@ loop() ->
|
||||
end.
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
|
||||
ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, announce_items, 50),
|
||||
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50),
|
||||
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50),
|
||||
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50),
|
||||
ejabberd_hooks:delete(local_send_to_resource_hook, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(adhoc_local_commands, HostB, ?MODULE, announce_commands, 50),
|
||||
ejabberd_hooks:delete(adhoc_local_items, HostB, ?MODULE, announce_items, 50),
|
||||
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, disco_identity, 50),
|
||||
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, disco_features, 50),
|
||||
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, disco_items, 50),
|
||||
ejabberd_hooks:delete(local_send_to_resource_hook, HostB,
|
||||
?MODULE, announce, 50),
|
||||
ejabberd_hooks:delete(user_available_hook, Host,
|
||||
ejabberd_hooks:delete(user_available_hook, HostB,
|
||||
?MODULE, send_motd, 50),
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
exit(whereis(Proc), stop),
|
||||
@ -131,39 +133,39 @@ stop(Host) ->
|
||||
|
||||
%% Announcing via messages to a custom resource
|
||||
announce(From, To, Packet) ->
|
||||
case To of
|
||||
#jid{lnode = undefined, lresource = Res} ->
|
||||
case {exmpp_jid:lnode(To), exmpp_jid:lresource(To)} of
|
||||
{undefined, Res} ->
|
||||
Name = Packet#xmlel.name,
|
||||
Proc = gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME),
|
||||
Proc = gen_mod:get_module_proc(exmpp_jid:ldomain_as_list(To), ?PROCNAME),
|
||||
case {Res, Name} of
|
||||
{"announce/all", 'message'} ->
|
||||
{<<"announce/all">>, 'message'} ->
|
||||
Proc ! {announce_all, From, To, Packet},
|
||||
stop;
|
||||
{"announce/all-hosts/all", 'message'} ->
|
||||
{<<"announce/all-hosts/all">>, 'message'} ->
|
||||
Proc ! {announce_all_hosts_all, From, To, Packet},
|
||||
stop;
|
||||
{"announce/online", 'message'} ->
|
||||
{<<"announce/online">>, 'message'} ->
|
||||
Proc ! {announce_online, From, To, Packet},
|
||||
stop;
|
||||
{"announce/all-hosts/online", 'message'} ->
|
||||
{<<"announce/all-hosts/online">>, 'message'} ->
|
||||
Proc ! {announce_all_hosts_online, From, To, Packet},
|
||||
stop;
|
||||
{"announce/motd", 'message'} ->
|
||||
{<<"announce/motd">>, 'message'} ->
|
||||
Proc ! {announce_motd, From, To, Packet},
|
||||
stop;
|
||||
{"announce/all-hosts/motd", 'message'} ->
|
||||
{<<"announce/all-hosts/motd">>, 'message'} ->
|
||||
Proc ! {announce_all_hosts_motd, From, To, Packet},
|
||||
stop;
|
||||
{"announce/motd/update", 'message'} ->
|
||||
{<<"announce/motd/update">>, 'message'} ->
|
||||
Proc ! {announce_motd_update, From, To, Packet},
|
||||
stop;
|
||||
{"announce/all-hosts/motd/update", 'message'} ->
|
||||
{<<"announce/all-hosts/motd/update">>, 'message'} ->
|
||||
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
|
||||
stop;
|
||||
{"announce/motd/delete", 'message'} ->
|
||||
{<<"announce/motd/delete">>, 'message'} ->
|
||||
Proc ! {announce_motd_delete, From, To, Packet},
|
||||
stop;
|
||||
{"announce/all-hosts/motd/delete", 'message'} ->
|
||||
{<<"announce/all-hosts/motd/delete">>, 'message'} ->
|
||||
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
|
||||
stop;
|
||||
_ ->
|
||||
@ -218,8 +220,8 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
|
||||
{result, Feats}
|
||||
end).
|
||||
|
||||
disco_features(Acc, From, #jid{ldomain = LServer} = _To,
|
||||
"announce", _Lang) ->
|
||||
disco_features(Acc, From, To, "announce", _Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -235,8 +237,8 @@ disco_features(Acc, From, #jid{ldomain = LServer} = _To,
|
||||
end
|
||||
end;
|
||||
|
||||
disco_features(Acc, From, #jid{ldomain = LServer} = _To,
|
||||
Node, _Lang) ->
|
||||
disco_features(Acc, From, To, Node, _Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -287,8 +289,10 @@ disco_features(Acc, From, #jid{ldomain = LServer} = _To,
|
||||
{result, Items}
|
||||
end).
|
||||
|
||||
disco_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To,
|
||||
"", Lang) ->
|
||||
disco_items(Acc, From, To, "", Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
Server = exmpp_jid:domain_as_list(To),
|
||||
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -309,7 +313,8 @@ disco_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To,
|
||||
end
|
||||
end;
|
||||
|
||||
disco_items(Acc, From, #jid{ldomain = LServer} = To, "announce", Lang) ->
|
||||
disco_items(Acc, From, To, "announce", Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -317,7 +322,8 @@ disco_items(Acc, From, #jid{ldomain = LServer} = To, "announce", Lang) ->
|
||||
announce_items(Acc, From, To, Lang)
|
||||
end;
|
||||
|
||||
disco_items(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
|
||||
disco_items(Acc, From, To, Node, _Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -354,7 +360,9 @@ disco_items(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
|
||||
|
||||
%%-------------------------------------------------------------------------
|
||||
|
||||
announce_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To, Lang) ->
|
||||
announce_items(Acc, From, To, Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
Server = exmpp_jid:domain_as_list(To),
|
||||
Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
|
||||
Nodes1 = case acl:match_rule(LServer, Access1, From) of
|
||||
allow ->
|
||||
@ -399,8 +407,8 @@ commands_result(Allow, From, To, Request) ->
|
||||
end.
|
||||
|
||||
|
||||
announce_commands(Acc, From, #jid{ldomain = LServer} = To,
|
||||
#adhoc_request{ node = Node} = Request) ->
|
||||
announce_commands(Acc, From, To, #adhoc_request{ node = Node} = Request) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
LNode = tokenize(Node),
|
||||
F = fun() ->
|
||||
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
|
||||
@ -455,7 +463,7 @@ announce_commands(From, To,
|
||||
#adhoc_response{status = canceled});
|
||||
XData == false, ActionIsExecute ->
|
||||
%% User requests form
|
||||
Elements = generate_adhoc_form(Lang, Node, To#jid.ldomain),
|
||||
Elements = generate_adhoc_form(Lang, Node, exmpp_jid:ldomain_as_list(To)),
|
||||
adhoc:produce_response(
|
||||
Request,
|
||||
#adhoc_response{status = executing,
|
||||
@ -529,11 +537,12 @@ join_lines([], Acc) ->
|
||||
%% Remove last newline
|
||||
lists:flatten(lists:reverse(tl(Acc))).
|
||||
|
||||
handle_adhoc_form(From, #jid{ldomain = LServer} = To,
|
||||
handle_adhoc_form(From, To,
|
||||
#adhoc_request{lang = Lang,
|
||||
node = Node,
|
||||
sessionid = SessionID},
|
||||
Fields) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
Confirm = case lists:keysearch("confirm", 1, Fields) of
|
||||
{value, {"confirm", ["true"]}} ->
|
||||
true;
|
||||
@ -654,14 +663,14 @@ get_title(Lang, ?NS_ADMIN_s ++ "#delete-motd-allhosts") ->
|
||||
%%-------------------------------------------------------------------------
|
||||
|
||||
announce_all(From, To, Packet) ->
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Local = exmpp_jid:make_jid(To#jid.domain),
|
||||
Local = exmpp_jid:make_jid(exmpp_jid:domain(To)),
|
||||
lists:foreach(
|
||||
fun({User, Server}) ->
|
||||
Dest = exmpp_jid:make_jid(User, Server),
|
||||
@ -676,7 +685,7 @@ announce_all_hosts_all(From, To, Packet) ->
|
||||
Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
Local = exmpp_jid:make_jid(To#jid.domain),
|
||||
Local = exmpp_jid:make_jid(exmpp_jid:domain(To)),
|
||||
lists:foreach(
|
||||
fun({User, Server}) ->
|
||||
Dest = exmpp_jid:make_jid(User, Server),
|
||||
@ -685,15 +694,15 @@ announce_all_hosts_all(From, To, Packet) ->
|
||||
end.
|
||||
|
||||
announce_online(From, To, Packet) ->
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_online1(ejabberd_sm:get_vh_session_list(Host),
|
||||
To#jid.domain,
|
||||
announce_online1(ejabberd_sm:get_vh_session_list(exmpp_jid:ldomain(To)),
|
||||
exmpp_jid:domain_as_list(To),
|
||||
Packet)
|
||||
end.
|
||||
|
||||
@ -705,7 +714,7 @@ announce_all_hosts_online(From, To, Packet) ->
|
||||
ejabberd_router:route(To, From, Err);
|
||||
allow ->
|
||||
announce_online1(ejabberd_sm:dirty_get_sessions_list(),
|
||||
To#jid.domain,
|
||||
exmpp_jid:domain_as_list(To),
|
||||
Packet)
|
||||
end.
|
||||
|
||||
@ -718,7 +727,7 @@ announce_online1(Sessions, Server, Packet) ->
|
||||
end, Sessions).
|
||||
|
||||
announce_motd(From, To, Packet) ->
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
@ -741,7 +750,7 @@ announce_all_hosts_motd(From, To, Packet) ->
|
||||
|
||||
announce_motd(Host, Packet) ->
|
||||
announce_motd_update(Host, Packet),
|
||||
Sessions = ejabberd_sm:get_vh_session_list(Host),
|
||||
Sessions = ejabberd_sm:get_vh_session_list(list_to_binary(Host)),
|
||||
announce_online1(Sessions, Host, Packet),
|
||||
F = fun() ->
|
||||
lists:foreach(
|
||||
@ -752,7 +761,7 @@ announce_motd(Host, Packet) ->
|
||||
mnesia:transaction(F).
|
||||
|
||||
announce_motd_update(From, To, Packet) ->
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
@ -781,7 +790,7 @@ announce_motd_update(LServer, Packet) ->
|
||||
mnesia:transaction(F).
|
||||
|
||||
announce_motd_delete(From, To, Packet) ->
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
|
||||
case acl:match_rule(Host, Access, From) of
|
||||
deny ->
|
||||
@ -817,7 +826,9 @@ announce_motd_delete(LServer) ->
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
send_motd(#jid{lnode = LUser, ldomain = LServer} = JID) ->
|
||||
send_motd(JID) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(JID),
|
||||
LUser = exmpp_jid:lnode_as_list(JID),
|
||||
case catch mnesia:dirty_read({motd, LServer}) of
|
||||
[#motd{packet = Packet}] ->
|
||||
US = {LUser, LServer},
|
||||
@ -825,7 +836,7 @@ send_motd(#jid{lnode = LUser, ldomain = LServer} = JID) ->
|
||||
[#motd_users{}] ->
|
||||
ok;
|
||||
_ ->
|
||||
Local = exmpp_jid:make_jid(LServer),
|
||||
Local = exmpp_jid:make_jid(exmpp_jid:ldomain(JID)),
|
||||
ejabberd_router:route(Local, JID, Packet),
|
||||
F = fun() ->
|
||||
mnesia:write(#motd_users{us = US})
|
||||
|
@ -87,7 +87,7 @@ read_caps([], Result) ->
|
||||
|
||||
%% get_caps reads user caps from database
|
||||
get_caps({U, S, R}) ->
|
||||
BJID = exmpp_jlib:jid_to_binary(U, S, R),
|
||||
BJID = exmpp_jid:jid_to_binary(U, S, R),
|
||||
case catch mnesia:dirty_read({user_caps, BJID}) of
|
||||
[#user_caps{caps=Caps}] ->
|
||||
Caps;
|
||||
@ -97,8 +97,8 @@ get_caps({U, S, R}) ->
|
||||
|
||||
%% clear_caps removes user caps from database
|
||||
clear_caps({U, S, R}) ->
|
||||
BJID = exmpp_jlib:jid_to_binary(U, S, R),
|
||||
BUID = exmpp_jlib:jid_to_binary(U, S),
|
||||
BJID = exmpp_jid:jid_to_binary(U, S, R),
|
||||
BUID = exmpp_jid:jid_to_binary(U, S),
|
||||
catch mnesia:dirty_delete({user_caps, BJID}),
|
||||
case catch mnesia:dirty_read({user_caps_default, BUID}) of
|
||||
[#user_caps_default{resource=R}] ->
|
||||
@ -109,7 +109,7 @@ clear_caps({U, S, R}) ->
|
||||
|
||||
%% give default user resource
|
||||
get_user_resource(U, S) ->
|
||||
BUID = exmpp_jlib:bare_jid_to_binary(U, S),
|
||||
BUID = exmpp_jid:bare_jid_to_binary(U, S),
|
||||
case catch mnesia:dirty_read({user_caps_default, BUID}) of
|
||||
[#user_caps_default{resource=R}] ->
|
||||
R;
|
||||
@ -225,15 +225,18 @@ handle_cast({note_caps, From,
|
||||
#state{host = Host, disco_requests = Requests} = State) ->
|
||||
%% XXX: this leads to race conditions where ejabberd will send
|
||||
%% lots of caps disco requests.
|
||||
#jid{node = U, domain = S, resource = R} = From,
|
||||
BJID = exmpp_jlib:jid_to_binary(From),
|
||||
%#jid{node = U, domain = S, resource = R} = From,
|
||||
U = exmpp_jid:lnode(From),
|
||||
S = exmpp_jid:ldomain(From),
|
||||
R = exmpp_jid:resource(From),
|
||||
BJID = exmpp_jid:jid_to_binary(From),
|
||||
mnesia:dirty_write(#user_caps{jid = BJID, caps = Caps}),
|
||||
case ejabberd_sm:get_user_resources(U, S) of
|
||||
[] ->
|
||||
ok;
|
||||
_ ->
|
||||
% only store default resource of external contacts
|
||||
BUID = exmpp_jlib:bare_jid_to_binary(From),
|
||||
BUID = exmpp_jid:bare_jid_to_binary(From),
|
||||
mnesia:dirty_write(#user_caps_default{uid = BUID, resource = R})
|
||||
end,
|
||||
SubNodes = [Version | Exts],
|
||||
@ -340,7 +343,7 @@ handle_cast(visit_feature_queries, #state{feature_queries = FeatureQueries} = St
|
||||
{noreply, State#state{feature_queries = NewFeatureQueries}}.
|
||||
|
||||
handle_disco_response(From, To, IQ_Rec) ->
|
||||
#jid{ldomain = Host} = To,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
gen_server:cast(Proc, {disco_response, From, To, IQ_Rec}).
|
||||
|
||||
|
@ -59,29 +59,31 @@
|
||||
-define(NS_ADMIN_s, "http://jabber.org/protocol/admin").
|
||||
|
||||
start(Host, _Opts) ->
|
||||
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_items, 50),
|
||||
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50),
|
||||
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
|
||||
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
|
||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50),
|
||||
ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50),
|
||||
ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50),
|
||||
ejabberd_hooks:add(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50),
|
||||
ejabberd_hooks:add(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50),
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, get_local_items, 50),
|
||||
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, get_local_features, 50),
|
||||
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, get_local_identity, 50),
|
||||
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_sm_items, 50),
|
||||
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:add(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 50),
|
||||
ejabberd_hooks:add(adhoc_local_items, HostB, ?MODULE, adhoc_local_items, 50),
|
||||
ejabberd_hooks:add(adhoc_local_commands, HostB, ?MODULE, adhoc_local_commands, 50),
|
||||
ejabberd_hooks:add(adhoc_sm_items, HostB, ?MODULE, adhoc_sm_items, 50),
|
||||
ejabberd_hooks:add(adhoc_sm_commands, HostB, ?MODULE, adhoc_sm_commands, 50),
|
||||
ok.
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50),
|
||||
ejabberd_hooks:delete(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50),
|
||||
ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50),
|
||||
ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50),
|
||||
ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50),
|
||||
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
|
||||
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
|
||||
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50),
|
||||
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_items, 50),
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(adhoc_sm_commands, HostB, ?MODULE, adhoc_sm_commands, 50),
|
||||
ejabberd_hooks:delete(adhoc_sm_items, HostB, ?MODULE, adhoc_sm_items, 50),
|
||||
ejabberd_hooks:delete(adhoc_local_commands, HostB, ?MODULE, adhoc_local_commands, 50),
|
||||
ejabberd_hooks:delete(adhoc_local_items, HostB, ?MODULE, adhoc_local_items, 50),
|
||||
ejabberd_hooks:delete(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 50),
|
||||
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_sm_items, 50),
|
||||
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, get_local_identity, 50),
|
||||
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, get_local_features, 50),
|
||||
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, get_local_items, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC).
|
||||
|
||||
@ -181,7 +183,8 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
|
||||
{result, Feats}
|
||||
end).
|
||||
|
||||
get_sm_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
|
||||
get_sm_features(Acc, From, To, Node, _Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -195,7 +198,8 @@ get_sm_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
|
||||
end
|
||||
end.
|
||||
|
||||
get_local_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
|
||||
get_local_features(Acc, From, To, Node, _Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -250,7 +254,8 @@ get_local_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
|
||||
|
||||
%%%-----------------------------------------------------------------------
|
||||
|
||||
adhoc_sm_items(Acc, From, #jid{ldomain = LServer} = To, Lang) ->
|
||||
adhoc_sm_items(Acc, From, To, Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case acl:match_rule(LServer, configure, From) of
|
||||
allow ->
|
||||
Items = case Acc of
|
||||
@ -268,9 +273,8 @@ adhoc_sm_items(Acc, From, #jid{ldomain = LServer} = To, Lang) ->
|
||||
|
||||
%%%-----------------------------------------------------------------------
|
||||
|
||||
get_sm_items(Acc, From,
|
||||
#jid{node = User, domain = Server, ldomain = LServer} = To,
|
||||
Node, Lang) ->
|
||||
get_sm_items(Acc, From, To, Node, Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -283,7 +287,7 @@ get_sm_items(Acc, From,
|
||||
{allow, ""} ->
|
||||
Nodes = [?NODEJID(To, "Configuration", "config"),
|
||||
?NODEJID(To, "User Management", "user")],
|
||||
{result, Items ++ Nodes ++ get_user_resources(User, Server)};
|
||||
{result, Items ++ Nodes ++ get_user_resources(To)};
|
||||
{allow, "config"} ->
|
||||
{result, []};
|
||||
{_, "config"} ->
|
||||
@ -293,18 +297,23 @@ get_sm_items(Acc, From,
|
||||
end
|
||||
end.
|
||||
|
||||
get_user_resources(User, Server) ->
|
||||
Rs = ejabberd_sm:get_user_resources(User, Server),
|
||||
get_user_resources(BareJID) ->
|
||||
Rs = ejabberd_sm:get_user_resources(exmpp_jid:lnode(BareJID),
|
||||
exmpp_jid:ldomain(BareJID)),
|
||||
lists:map(fun(R) ->
|
||||
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
|
||||
[#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(User, Server, R)},
|
||||
#xmlattr{name = 'name', value = User}]}
|
||||
[#xmlattr{name = 'jid',
|
||||
value = exmpp_jid:jid_to_list(
|
||||
exmpp_jid:bare_jid_to_jid(BareJID, R))},
|
||||
#xmlattr{name = 'name',
|
||||
value = exmpp_jid:lnode_as_list(BareJID)}]}
|
||||
end, lists:sort(Rs)).
|
||||
|
||||
%%%-----------------------------------------------------------------------
|
||||
|
||||
adhoc_local_items(Acc, From, #jid{ldomain = LServer, domain = Server} = To,
|
||||
Lang) ->
|
||||
adhoc_local_items(Acc, From, To, Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
Server = exmpp_jid:domain_as_list(To),
|
||||
case acl:match_rule(LServer, configure, From) of
|
||||
allow ->
|
||||
Items = case Acc of
|
||||
@ -373,7 +382,8 @@ recursively_get_local_items(LServer, Node, Server, Lang) ->
|
||||
end
|
||||
end).
|
||||
|
||||
get_local_items(Acc, From, #jid{ldomain = LServer} = To, "", Lang) ->
|
||||
get_local_items(Acc, From, To, "", Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -397,7 +407,8 @@ get_local_items(Acc, From, #jid{ldomain = LServer} = To, "", Lang) ->
|
||||
end
|
||||
end;
|
||||
|
||||
get_local_items(Acc, From, #jid{ldomain = LServer} = To, Node, Lang) ->
|
||||
get_local_items(Acc, From, To, Node, Lang) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case gen_mod:is_loaded(LServer, mod_adhoc) of
|
||||
false ->
|
||||
Acc;
|
||||
@ -584,7 +595,7 @@ get_local_items(_Host, _, _Server, _Lang) ->
|
||||
|
||||
|
||||
get_online_vh_users(Host) ->
|
||||
case catch ejabberd_sm:get_vh_session_list(Host) of
|
||||
case catch ejabberd_sm:get_vh_session_list(list_to_binary(Host)) of
|
||||
{'EXIT', _Reason} ->
|
||||
[];
|
||||
USRs ->
|
||||
@ -716,8 +727,8 @@ get_stopped_nodes(_Lang) ->
|
||||
adhoc_local_commands(From, To, Request)
|
||||
end).
|
||||
|
||||
adhoc_local_commands(Acc, From, #jid{ldomain = LServer} = To,
|
||||
#adhoc_request{node = Node} = Request) ->
|
||||
adhoc_local_commands(Acc, From, To, #adhoc_request{node = Node} = Request) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
LNode = tokenize(Node),
|
||||
Allow = acl:match_rule(LServer, configure, From),
|
||||
case LNode of
|
||||
@ -741,12 +752,13 @@ adhoc_local_commands(Acc, From, #jid{ldomain = LServer} = To,
|
||||
Acc
|
||||
end.
|
||||
|
||||
adhoc_local_commands(From, #jid{ldomain = LServer} = _To,
|
||||
adhoc_local_commands(From, To,
|
||||
#adhoc_request{lang = Lang,
|
||||
node = Node,
|
||||
sessionid = SessionID,
|
||||
action = Action,
|
||||
xdata = XData} = Request) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
LNode = tokenize(Node),
|
||||
%% If the "action" attribute is not present, it is
|
||||
%% understood as "execute". If there was no <actions/>
|
||||
@ -1247,7 +1259,7 @@ get_form(Host, ?NS_ADMINL("get-registered-users-num"), Lang) ->
|
||||
}]}]};
|
||||
|
||||
get_form(Host, ?NS_ADMINL("get-online-users-num"), Lang) ->
|
||||
Num = io_lib:format("~p", [length(ejabberd_sm:get_vh_session_list(Host))]),
|
||||
Num = io_lib:format("~p", [length(ejabberd_sm:get_vh_session_list(list_to_binary(Host)))]),
|
||||
{result, completed,
|
||||
[#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
|
||||
[?HFIELD(),
|
||||
@ -1535,8 +1547,8 @@ set_form(_From, _Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
|
||||
Password = get_value("password", XData),
|
||||
Password = get_value("password-verify", XData),
|
||||
AccountJID = exmpp_jid:list_to_jid(AccountString),
|
||||
User = AccountJID#jid.lnode,
|
||||
Server = AccountJID#jid.ldomain,
|
||||
User = exmpp_jid:lnode_as_list(AccountJID),
|
||||
Server = exmpp_jid:ldomain_as_list(AccountJID),
|
||||
true = lists:member(Server, ?MYHOSTS),
|
||||
ejabberd_auth:try_register(User, Server, Password),
|
||||
{result, []};
|
||||
@ -1547,9 +1559,8 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
|
||||
ASL2 = lists:map(
|
||||
fun(AccountString) ->
|
||||
JID = exmpp_jid:list_to_jid(AccountString),
|
||||
[_|_] = JID#jid.lnode,
|
||||
User = JID#jid.lnode,
|
||||
Server = JID#jid.ldomain,
|
||||
User = [_|_] = exmpp_jid:lnode_as_list(JID),
|
||||
Server = exmpp_jid:ldomain_as_list(JID),
|
||||
true = ejabberd_auth:is_user_exists(User, Server),
|
||||
{User, Server}
|
||||
end,
|
||||
@ -1560,11 +1571,10 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
|
||||
set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
|
||||
AccountString = get_value("accountjid", XData),
|
||||
JID = exmpp_jid:list_to_jid(AccountString),
|
||||
[_|_] = JID#jid.lnode,
|
||||
LUser = JID#jid.lnode,
|
||||
LServer = JID#jid.ldomain,
|
||||
LUser = [_|_] = exmpp_jid:lnode_as_list(JID),
|
||||
LServer = exmpp_jid:ldomain_as_list(JID),
|
||||
%% Code copied from ejabberd_sm.erl
|
||||
case JID#jid.lresource of
|
||||
case exmpp_jid:lresource_as_list(JID) of
|
||||
undefined ->
|
||||
SIDs = mnesia:dirty_select(session,
|
||||
[{#session{sid = '$1', usr = {LUser, LServer, '_'}, _ = '_'}, [], ['$1']}]),
|
||||
@ -1579,9 +1589,8 @@ set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
|
||||
set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
|
||||
AccountString = get_value("accountjid", XData),
|
||||
JID = exmpp_jid:list_to_jid(AccountString),
|
||||
[_|_] = JID#jid.lnode,
|
||||
User = JID#jid.lnode,
|
||||
Server = JID#jid.ldomain,
|
||||
User = [_|_] = exmpp_jid:lnode_as_list(JID),
|
||||
Server = exmpp_jid:ldomain_as_list(JID),
|
||||
Password = ejabberd_auth:get_password(User, Server),
|
||||
true = is_list(Password),
|
||||
{result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
|
||||
@ -1594,9 +1603,8 @@ set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
|
||||
AccountString = get_value("accountjid", XData),
|
||||
Password = get_value("password", XData),
|
||||
JID = exmpp_jid:list_to_jid(AccountString),
|
||||
[_|_] = JID#jid.lnode,
|
||||
User = JID#jid.lnode,
|
||||
Server = JID#jid.ldomain,
|
||||
User = [_|_] = exmpp_jid:lnode_as_list(JID),
|
||||
Server = exmpp_jid:ldomain_as_list(JID),
|
||||
true = ejabberd_auth:is_user_exists(User, Server),
|
||||
ejabberd_auth:set_password(User, Server, Password),
|
||||
{result, []};
|
||||
@ -1604,14 +1612,14 @@ set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
|
||||
set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
|
||||
AccountString = get_value("accountjid", XData),
|
||||
JID = exmpp_jid:list_to_jid(AccountString),
|
||||
[_|_] = JID#jid.lnode,
|
||||
User = JID#jid.lnode,
|
||||
Server = JID#jid.ldomain,
|
||||
User = [_|_] = exmpp_jid:lnode_as_list(JID),
|
||||
Server = exmpp_jid:ldomain_as_list(JID),
|
||||
|
||||
%% Code copied from web/ejabberd_web_admin.erl
|
||||
%% TODO: Update time format to XEP-0202: Entity Time
|
||||
FLast =
|
||||
case ejabberd_sm:get_user_resources(User, Server) of
|
||||
case ejabberd_sm:get_user_resources(exmpp_jid:lnode(User),
|
||||
exmpp_jid:ldomain(Server)) of
|
||||
[] ->
|
||||
_US = {User, Server},
|
||||
case get_last_info(User, Server) of
|
||||
@ -1641,15 +1649,19 @@ set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
|
||||
set_form(_From, _Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
|
||||
AccountString = get_value("accountjid", XData),
|
||||
JID = exmpp_jid:list_to_jid(AccountString),
|
||||
[_|_] = JID#jid.lnode,
|
||||
User = JID#jid.lnode,
|
||||
Server = JID#jid.ldomain,
|
||||
User = [_|_] = exmpp_jid:lnode_as_list(JID),
|
||||
Server = exmpp_jid:ldomain_as_list(JID),
|
||||
|
||||
Resources = ejabberd_sm:get_user_resources(User, Server),
|
||||
IPs1 = [ejabberd_sm:get_user_ip(User, Server, Resource) || Resource <- Resources],
|
||||
Resources = ejabberd_sm:get_user_resources(exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID)),
|
||||
IPs1 = [ejabberd_sm:get_user_ip(exmpp_jid:bare_jid_to_jid(JID,Resource))
|
||||
|| Resource <- Resources],
|
||||
IPs = [inet_parse:ntoa(IP)++":"++integer_to_list(Port) || {IP, Port} <- IPs1],
|
||||
|
||||
Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]),
|
||||
Items = ejabberd_hooks:run_fold(roster_get,
|
||||
exmpp_jid:ldomain(JID),
|
||||
[],
|
||||
[{list_to_binary(User), list_to_binary(Server)}]),
|
||||
Rostersize = integer_to_list(erlang:length(Items)),
|
||||
|
||||
{result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
|
||||
@ -1729,12 +1741,14 @@ get_last_info(User, Server) ->
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
adhoc_sm_commands(_Acc, From,
|
||||
#jid{node = User, domain = Server, ldomain = LServer} = _To,
|
||||
adhoc_sm_commands(_Acc, From, To,
|
||||
#adhoc_request{lang = Lang,
|
||||
node = "config",
|
||||
action = Action,
|
||||
xdata = XData} = Request) ->
|
||||
User = exmpp_jid:node_as_list(To),
|
||||
Server = exmpp_jid:domain_as_list(To),
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case acl:match_rule(LServer, configure, From) of
|
||||
deny ->
|
||||
{error, 'forbidden'};
|
||||
|
@ -71,7 +71,7 @@ stop(Host) ->
|
||||
|
||||
|
||||
process_local_iq(From, To, #iq{type = Type, payload = Request} = IQ_Rec) ->
|
||||
case acl:match_rule(To#jid.ldomain, configure, From) of
|
||||
case acl:match_rule(exmpp_jid:ldomain_as_list(To), configure, From) of
|
||||
deny ->
|
||||
exmpp_iq:error(IQ_Rec, 'not-allowed');
|
||||
allow ->
|
||||
|
@ -54,6 +54,7 @@
|
||||
-record(disco_publish, {owner_node, jid, name, node}).
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
mnesia:create_table(disco_publish,
|
||||
[{disc_only_copies, [node()]},
|
||||
{attributes, record_info(fields, disco_publish)},
|
||||
@ -84,23 +85,24 @@ start(Host, Opts) ->
|
||||
ExtraDomains),
|
||||
catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
|
||||
catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
|
||||
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_services, 100),
|
||||
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 100),
|
||||
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
|
||||
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
|
||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
|
||||
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
|
||||
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_publish_items, 75),
|
||||
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, get_local_services, 100),
|
||||
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, get_local_features, 100),
|
||||
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, get_local_identity, 100),
|
||||
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_sm_items, 100),
|
||||
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 100),
|
||||
ejabberd_hooks:add(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 100),
|
||||
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_publish_items, 75),
|
||||
ok.
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_publish_items, 75),
|
||||
ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
|
||||
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
|
||||
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
|
||||
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
|
||||
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100),
|
||||
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100),
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_publish_items, 75),
|
||||
ejabberd_hooks:delete(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 100),
|
||||
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 100),
|
||||
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_sm_items, 100),
|
||||
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, get_local_identity, 100),
|
||||
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, get_local_features, 100),
|
||||
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, get_local_services, 100),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
|
||||
@ -128,11 +130,10 @@ unregister_extra_domain(Host, Domain) ->
|
||||
|
||||
process_local_iq_items(From, To, #iq{type = get, payload = SubEl,
|
||||
lang = Lang} = IQ_Rec) ->
|
||||
Host = To#jid.ldomain,
|
||||
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
|
||||
|
||||
case ejabberd_hooks:run_fold(disco_local_items,
|
||||
Host,
|
||||
exmpp_jid:ldomain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
{result, Items} ->
|
||||
@ -152,14 +153,13 @@ process_local_iq_items(_From, _To, #iq{type = set} = IQ_Rec) ->
|
||||
|
||||
process_local_iq_info(From, To, #iq{type = get, payload = SubEl,
|
||||
lang = Lang} = IQ_Rec) ->
|
||||
Host = To#jid.ldomain,
|
||||
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
|
||||
Identity = ejabberd_hooks:run_fold(disco_local_identity,
|
||||
Host,
|
||||
exmpp_jid:ldomain(To),
|
||||
[],
|
||||
[From, To, Node, Lang]),
|
||||
case ejabberd_hooks:run_fold(disco_local_features,
|
||||
Host,
|
||||
exmpp_jid:ldomain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
{result, Features} ->
|
||||
@ -196,7 +196,7 @@ get_local_features(Acc, _From, To, [], _Lang) ->
|
||||
{result, Features} -> Features;
|
||||
empty -> []
|
||||
end,
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
{result,
|
||||
ets:select(disco_features, [{{{'_', Host}}, [], ['$_']}]) ++ Feats};
|
||||
|
||||
@ -237,7 +237,7 @@ get_local_services(Acc, _From, To, [], _Lang) ->
|
||||
{result, Its} -> Its;
|
||||
empty -> []
|
||||
end,
|
||||
Host = To#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(To),
|
||||
{result,
|
||||
lists:usort(
|
||||
lists:map(fun domain_to_xml/1,
|
||||
@ -270,10 +270,9 @@ get_vh_services(Host) ->
|
||||
|
||||
process_sm_iq_items(From, To, #iq{type = get, payload = SubEl,
|
||||
lang = Lang} = IQ_Rec) ->
|
||||
Host = To#jid.ldomain,
|
||||
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
|
||||
case ejabberd_hooks:run_fold(disco_sm_items,
|
||||
Host,
|
||||
exmpp_jid:ldomain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
{result, Items} ->
|
||||
@ -288,8 +287,10 @@ process_sm_iq_items(From, To, #iq{type = get, payload = SubEl,
|
||||
exmpp_iq:error(IQ_Rec, Error)
|
||||
end;
|
||||
process_sm_iq_items(From, To, #iq{type = set, payload = SubEl} = IQ_Rec) ->
|
||||
#jid{lnode = LTo, ldomain = ToServer} = To,
|
||||
#jid{lnode = LFrom, ldomain = LServer} = From,
|
||||
LTo = exmpp_jid:lnode_as_list(To),
|
||||
ToServer = exmpp_jid:ldomain_as_list(To),
|
||||
LFrom = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
Self = (LTo == LFrom) andalso (ToServer == LServer),
|
||||
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
|
||||
if
|
||||
@ -310,16 +311,18 @@ process_sm_iq_items(From, To, #iq{type = set, payload = SubEl} = IQ_Rec) ->
|
||||
get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
|
||||
Acc;
|
||||
|
||||
get_sm_items(Acc,
|
||||
#jid{lnode = LFrom, ldomain = LSFrom},
|
||||
#jid{node = User, domain = Server, lnode = LTo, ldomain = LSTo} = _To,
|
||||
[], _Lang) ->
|
||||
get_sm_items(Acc, From, To, [], _Lang) ->
|
||||
LFrom = exmpp_jid:lnode_as_list(From),
|
||||
LSFrom = exmpp_jid:ldomain_as_list(From),
|
||||
LTo = exmpp_jid:lnode_as_list(To),
|
||||
LSTo = exmpp_jid:ldomain_as_list(To),
|
||||
|
||||
Items = case Acc of
|
||||
{result, Its} -> Its;
|
||||
empty -> []
|
||||
end,
|
||||
Items1 = case {LFrom, LSFrom} of
|
||||
{LTo, LSTo} -> get_user_resources(User, Server);
|
||||
{LTo, LSTo} -> get_user_resources(To);
|
||||
_ -> []
|
||||
end,
|
||||
{result, Items ++ Items1};
|
||||
@ -328,8 +331,10 @@ get_sm_items({result, _} = Acc, _From, _To, _Node, _Lang) ->
|
||||
Acc;
|
||||
|
||||
get_sm_items(empty, From, To, _Node, _Lang) ->
|
||||
#jid{lnode = LFrom, ldomain = LSFrom} = From,
|
||||
#jid{lnode = LTo, ldomain = LSTo} = To,
|
||||
LFrom = exmpp_jid:lnode_as_list(From),
|
||||
LSFrom = exmpp_jid:ldomain_as_list(From),
|
||||
LTo = exmpp_jid:lnode_as_list(To),
|
||||
LSTo = exmpp_jid:ldomain_as_list(To),
|
||||
case {LFrom, LSFrom} of
|
||||
{LTo, LSTo} ->
|
||||
{error, 'item-not-found'};
|
||||
@ -339,14 +344,13 @@ get_sm_items(empty, From, To, _Node, _Lang) ->
|
||||
|
||||
process_sm_iq_info(From, To, #iq{type = get, payload = SubEl,
|
||||
lang = Lang} = IQ_Rec) ->
|
||||
Host = To#jid.ldomain,
|
||||
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
|
||||
Identity = ejabberd_hooks:run_fold(disco_sm_identity,
|
||||
Host,
|
||||
exmpp_jid:ldomain(To),
|
||||
[],
|
||||
[From, To, Node, Lang]),
|
||||
case ejabberd_hooks:run_fold(disco_sm_features,
|
||||
Host,
|
||||
exmpp_jid:ldomain(To),
|
||||
empty,
|
||||
[From, To, Node, Lang]) of
|
||||
{result, Features} ->
|
||||
@ -369,8 +373,10 @@ get_sm_identity(Acc, _From, _To, _Node, _Lang) ->
|
||||
Acc.
|
||||
|
||||
get_sm_features(empty, From, To, _Node, _Lang) ->
|
||||
#jid{lnode = LFrom, ldomain = LSFrom} = From,
|
||||
#jid{lnode = LTo, ldomain = LSTo} = To,
|
||||
LFrom = exmpp_jid:lnode_as_list(From),
|
||||
LSFrom = exmpp_jid:ldomain_as_list(From),
|
||||
LTo = exmpp_jid:lnode_as_list(To),
|
||||
LSTo = exmpp_jid:ldomain_as_list(To),
|
||||
case {LFrom, LSFrom} of
|
||||
{LTo, LSTo} ->
|
||||
{error, 'item-not-found'};
|
||||
@ -383,21 +389,23 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) ->
|
||||
|
||||
|
||||
|
||||
get_user_resources(User, Server) ->
|
||||
Rs = ejabberd_sm:get_user_resources(User, Server),
|
||||
get_user_resources(JID) ->
|
||||
Rs = ejabberd_sm:get_user_resources(exmpp_jid:lnode(JID),
|
||||
exmpp_jid:ldomain(JID)),
|
||||
lists:map(fun(R) ->
|
||||
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [
|
||||
#xmlattr{name = 'jid', value =
|
||||
exmpp_jid:jid_to_list(User, Server, R)},
|
||||
#xmlattr{name = 'name', value = User}
|
||||
exmpp_jid:jid_to_list(exmpp_jid:bare_jid_to_jid(JID, R))},
|
||||
#xmlattr{name = 'name', value = exmpp_jid:lnode_as_list(JID)}
|
||||
]}
|
||||
end, lists:sort(Rs)).
|
||||
|
||||
|
||||
get_publish_items(empty,
|
||||
#jid{lnode = LFrom, ldomain = LSFrom},
|
||||
#jid{lnode = LTo, ldomain = LSTo} = _To,
|
||||
Node, _Lang) ->
|
||||
get_publish_items(empty, From, To, Node, _Lang) ->
|
||||
LFrom = exmpp_jid:lnode_as_list(From),
|
||||
LSFrom = exmpp_jid:ldomain_as_list(From),
|
||||
LTo = exmpp_jid:lnode_as_list(To),
|
||||
LSTo = exmpp_jid:ldomain_as_list(To),
|
||||
if
|
||||
(LFrom == LTo) and (LSFrom == LSTo) ->
|
||||
retrieve_disco_publish({LTo, LSTo}, Node);
|
||||
|
@ -118,7 +118,7 @@ handle_cast(_Msg, State) ->
|
||||
%% Description: Handling all non call/cast messages
|
||||
%%--------------------------------------------------------------------
|
||||
handle_info({route, From, To, Packet}, State) ->
|
||||
Packet2 = case From#jid.node of
|
||||
Packet2 = case exmpp_jid:node(From) of
|
||||
undefined -> exmpp_stanza:reply_with_error(Packet, 'bad-request');
|
||||
_ -> Packet
|
||||
end,
|
||||
@ -174,8 +174,7 @@ do_client_version(disabled, _From, _To) ->
|
||||
do_client_version(enabled, From, To) ->
|
||||
%% It is important to identify this process and packet
|
||||
Random_resource = integer_to_list(random:uniform(100000)),
|
||||
From2 = From#jid{resource = Random_resource,
|
||||
lresource = Random_resource},
|
||||
From2 = exmpp_jid:bare_jid_to_jid(From,Random_resource),
|
||||
|
||||
%% Build an iq:query request
|
||||
Request = #xmlel{ns = ?NS_SOFT_VERSION, name = 'query'},
|
||||
|
@ -204,7 +204,8 @@ do_route(Host, ServerHost, Access, From, To, Packet, DefEnc) ->
|
||||
end.
|
||||
|
||||
do_route1(Host, ServerHost, From, To, Packet, DefEnc) ->
|
||||
#jid{node = ChanServ, resource = Resource} = To,
|
||||
ChanServ = exmpp_jid:node_as_list(To),
|
||||
Resource = exmpp_jid:resource_as_list(To),
|
||||
case ChanServ of
|
||||
undefined ->
|
||||
case Resource of
|
||||
@ -400,8 +401,10 @@ process_irc_register(Host, From, _To, _DefEnc,
|
||||
|
||||
|
||||
get_form(Host, From, [], Lang, DefEnc) ->
|
||||
#jid{node = User, domain = Server,
|
||||
lnode = LUser, ldomain = LServer} = From,
|
||||
User = exmpp_jid:node_as_list(From),
|
||||
Server = exmpp_jid:domain_as_list(From),
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
US = {LUser, LServer},
|
||||
Customs =
|
||||
case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
|
||||
@ -485,7 +488,8 @@ get_form(_Host, _, _, _Lang, _) ->
|
||||
|
||||
|
||||
set_form(Host, From, [], _Lang, XData) ->
|
||||
{LUser, LServer, _} = jlib:short_prepd_jid(From),
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
US = {LUser, LServer},
|
||||
case {lists:keysearch("username", 1, XData),
|
||||
lists:keysearch("encodings", 1, XData)} of
|
||||
@ -529,8 +533,9 @@ set_form(_Host, _, _, _Lang, _XData) ->
|
||||
|
||||
|
||||
get_user_and_encoding(Host, From, IRCServer, DefEnc) ->
|
||||
#jid{node = User, domain = _Server,
|
||||
lnode = LUser, ldomain = LServer} = From,
|
||||
User = exmpp_jid:node_as_list(From),
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
US = {LUser, LServer},
|
||||
case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
|
||||
{'EXIT', _Reason} ->
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
mnesia:create_table(last_activity,
|
||||
[{disc_copies, [node()]},
|
||||
@ -56,15 +57,16 @@ start(Host, Opts) ->
|
||||
?MODULE, process_local_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY,
|
||||
?MODULE, process_sm_iq, IQDisc),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(unset_presence_hook, Host,
|
||||
ejabberd_hooks:add(unset_presence_hook, HostB,
|
||||
?MODULE, on_presence_update, 50).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(unset_presence_hook, Host,
|
||||
ejabberd_hooks:delete(unset_presence_hook, HostB,
|
||||
?MODULE, on_presence_update, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY).
|
||||
@ -79,27 +81,25 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
|
||||
|
||||
|
||||
process_sm_iq(From, To, #iq{type = get} = IQ_Rec) ->
|
||||
User = To#jid.lnode,
|
||||
Server = To#jid.ldomain,
|
||||
{Subscription, _Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
roster_get_jid_info, exmpp_jid:ldomain(To),
|
||||
{none, []}, [exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From]),
|
||||
if
|
||||
(Subscription == both) or (Subscription == from) ->
|
||||
UserListRecord = ejabberd_hooks:run_fold(
|
||||
privacy_get_user_list, Server,
|
||||
privacy_get_user_list, exmpp_jid:ldomain(To),
|
||||
#userlist{},
|
||||
[User, Server]),
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To)]),
|
||||
case ejabberd_hooks:run_fold(
|
||||
privacy_check_packet, Server,
|
||||
privacy_check_packet, exmpp_jid:ldomain(To),
|
||||
allow,
|
||||
[User, Server, UserListRecord,
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), UserListRecord,
|
||||
{From, To,
|
||||
exmpp_presence:available()},
|
||||
out]) of
|
||||
allow ->
|
||||
get_last(IQ_Rec, User, Server);
|
||||
get_last(IQ_Rec, exmpp_jid:lnode(To), exmpp_jid:ldomain(To));
|
||||
deny ->
|
||||
exmpp_iq:error(IQ_Rec, 'not-allowed')
|
||||
end;
|
||||
@ -133,11 +133,10 @@ on_presence_update(User, Server, _Resource, Status) ->
|
||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||
store_last_info(User, Server, TimeStamp, Status).
|
||||
|
||||
store_last_info(User, Server, TimeStamp, Status) ->
|
||||
store_last_info(User, Server, TimeStamp, Status)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
US = {User, Server},
|
||||
F = fun() ->
|
||||
mnesia:write(#last_activity{us = US,
|
||||
timestamp = TimeStamp,
|
||||
@ -150,7 +149,7 @@ store_last_info(User, Server, TimeStamp, Status) ->
|
||||
end.
|
||||
|
||||
%% Returns: {ok, Timestamp, Status} | not_found
|
||||
get_last_info(LUser, LServer) ->
|
||||
get_last_info(LUser, LServer) when is_binary(LUser), is_binary(LServer) ->
|
||||
case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of
|
||||
{'EXIT', _Reason} ->
|
||||
not_found;
|
||||
@ -160,7 +159,7 @@ get_last_info(LUser, LServer) ->
|
||||
{ok, TimeStamp, Status}
|
||||
end.
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
@ -250,7 +249,8 @@ convert_to_exmpp2(#last_activity{us = {U, S} = Key, status = Status} = LA,
|
||||
% Convert status.
|
||||
Status1 = list_to_binary(Status),
|
||||
% Prepare the new record.
|
||||
New_LA = LA#last_activity{us = {U1, S}, status = Status1},
|
||||
New_LA = LA#last_activity{us = {list_to_binary(U1), list_to_binary(S)},
|
||||
status = Status1},
|
||||
% Write the new record.
|
||||
mnesia:write(New_LA),
|
||||
Acc.
|
||||
|
@ -44,20 +44,22 @@
|
||||
-include("mod_privacy.hrl").
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY,
|
||||
?MODULE, process_local_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY,
|
||||
?MODULE, process_sm_iq, IQDisc),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(unset_presence_hook, Host,
|
||||
ejabberd_hooks:add(unset_presence_hook, HostB,
|
||||
?MODULE, on_presence_update, 50).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(unset_presence_hook, Host,
|
||||
ejabberd_hooks:delete(unset_presence_hook, HostB,
|
||||
?MODULE, on_presence_update, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY).
|
||||
@ -71,22 +73,22 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
|
||||
exmpp_iq:error(IQ_Rec, 'not-allowed').
|
||||
|
||||
process_sm_iq(From, To, #iq{type = get} = IQ_Rec) ->
|
||||
User = To#jid.lnode,
|
||||
Server = To#jid.ldomain,
|
||||
User = exmpp_jid:lnode_as_list(To),
|
||||
Server = exmpp_jid:ldomain_as_list(To),
|
||||
{Subscription, _Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
roster_get_jid_info, exmpp_jid:ldomain(To),
|
||||
{none, []}, [exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From]),
|
||||
if
|
||||
(Subscription == both) or (Subscription == from) ->
|
||||
UserListRecord = ejabberd_hooks:run_fold(
|
||||
privacy_get_user_list, Server,
|
||||
privacy_get_user_list, exmpp_jid:ldomain(To),
|
||||
#userlist{},
|
||||
[User, Server]),
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To)]),
|
||||
case ejabberd_hooks:run_fold(
|
||||
privacy_check_packet, Server,
|
||||
privacy_check_packet, exmpp_jid:ldomain(To),
|
||||
allow,
|
||||
[User, Server, UserListRecord,
|
||||
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), UserListRecord,
|
||||
{From, To,
|
||||
exmpp_presence:available()},
|
||||
out]) of
|
||||
@ -129,13 +131,17 @@ on_presence_update(User, Server, _Resource, Status) ->
|
||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||
store_last_info(User, Server, TimeStamp, Status).
|
||||
|
||||
store_last_info(User, Server, TimeStamp, Status) ->
|
||||
store_last_info(User, Server, TimeStamp, Status)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
%LUser = exmpp_stringprep:nodeprep(User),
|
||||
%LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
|
||||
State = ejabberd_odbc:escape(binary_to_list(Status)),
|
||||
State = ejabberd_odbc:escape(Status),
|
||||
odbc_queries:set_last_t(LServer, Username, Seconds, State)
|
||||
catch
|
||||
_ ->
|
||||
@ -151,7 +157,7 @@ get_last_info(LUser, LServer) ->
|
||||
{selected, ["seconds","state"], [{STimeStamp, Status}]} ->
|
||||
case catch list_to_integer(STimeStamp) of
|
||||
TimeStamp when is_integer(TimeStamp) ->
|
||||
{ok, TimeStamp, list_to_binary(Status)};
|
||||
{ok, TimeStamp, Status};
|
||||
_ ->
|
||||
not_found
|
||||
end;
|
||||
|
@ -136,7 +136,7 @@ process_iq_disco_items(Host, From, To, #iq{} = IQ) ->
|
||||
can_use_nick(_Host, _JID, "") ->
|
||||
false;
|
||||
can_use_nick(Host, JID, Nick) ->
|
||||
LUS = {JID#jid.lnode, JID#jid.ldomain},
|
||||
LUS = {exmpp_jid:lnode_as_list(JID), exmpp_jid:ldomain_as_list(JID)},
|
||||
case catch mnesia:dirty_select(
|
||||
muc_registered,
|
||||
[{#muc_registered{us_host = '$1',
|
||||
@ -312,8 +312,8 @@ do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
|
||||
do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
|
||||
From, To, Packet, DefRoomOpts) ->
|
||||
{_AccessRoute, AccessCreate, AccessAdmin, _AccessPersistent} = Access,
|
||||
Room = To#jid.lnode,
|
||||
Nick = To#jid.lresource,
|
||||
Room = exmpp_jid:lnode_as_list(To),
|
||||
Nick = exmpp_jid:lresource_as_list(To),
|
||||
#xmlel{name = Name} = Packet,
|
||||
case Room of
|
||||
'undefined' ->
|
||||
@ -554,8 +554,8 @@ flush() ->
|
||||
children = [#xmlcdata{cdata = Val}]}]}).
|
||||
|
||||
iq_get_register_info(Host, From, Lang) ->
|
||||
LUser = From#jid.lnode,
|
||||
LServer = From#jid.ldomain,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
LUS = {LUser, LServer},
|
||||
{Nick, Registered} =
|
||||
case catch mnesia:dirty_read(muc_registered, {LUS, Host}) of
|
||||
@ -584,8 +584,8 @@ iq_get_register_info(Host, From, Lang) ->
|
||||
|
||||
|
||||
iq_set_register_info(Host, From, Nick, Lang) ->
|
||||
LUser = From#jid.lnode,
|
||||
LServer = From#jid.ldomain,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
LUS = {LUser, LServer},
|
||||
F = fun() ->
|
||||
case Nick of
|
||||
|
@ -272,7 +272,7 @@ build_filename_string(TimeStamp, OutDir, RoomJID, DirType, DirName, FileFormat)
|
||||
|
||||
get_room_name(RoomJID) ->
|
||||
JID = exmpp_jid:list_to_jid(RoomJID),
|
||||
JID#jid.node.
|
||||
exmpp_jid:node_as_list(JID).
|
||||
|
||||
%% calculate day before
|
||||
get_timestamp_daydiff(TimeStamp, Daydiff) ->
|
||||
|
@ -261,6 +261,7 @@ normal_state({route, From, undefined,
|
||||
StateData#state.jid,
|
||||
From, exmpp_stanza:reply_with_error(Packet, Err)),
|
||||
{next_state, normal_state, StateData};
|
||||
%%TODO: currently exmpp_message:get_type/1 never returns 'undefined'
|
||||
Type when (Type == 'normal') orelse (Type == 'undefined') ->
|
||||
case catch check_invitation(From,
|
||||
exmpp_xml:get_child_elements(Packet),
|
||||
@ -2139,11 +2140,16 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
|
||||
fun(E, SD) ->
|
||||
case catch (
|
||||
case E of
|
||||
{JID, affiliation, owner, _}
|
||||
when (JID#jid.lnode == "") ->
|
||||
{JID, affiliation, owner, _} ->
|
||||
case exmpp_jid:lnode(JID) of
|
||||
<<>> ->
|
||||
SD;
|
||||
%% TODO: <<>> or 'undefined' ?
|
||||
%% TODO: double case on the E var, because
|
||||
%% exmpp_jid:lnode/1 can't be used in guards
|
||||
%% If the provided JID does not have username,
|
||||
%% forget the affiliation completely
|
||||
SD;
|
||||
_ -> case E of
|
||||
{JID, role, none, Reason} ->
|
||||
catch send_kickban_presence(
|
||||
JID, Reason, "307", SD),
|
||||
@ -2187,6 +2193,8 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
|
||||
send_update_presence(JID, SD1),
|
||||
SD1
|
||||
end
|
||||
end
|
||||
end
|
||||
) of
|
||||
{'EXIT', ErrReason} ->
|
||||
?ERROR_MSG("MUC ITEMS SET ERR: ~p~n",
|
||||
@ -3285,7 +3293,7 @@ check_invitation(From, Els, Lang, StateData) ->
|
||||
_ -> [" (", Reason, ") "]
|
||||
end
|
||||
])}]},
|
||||
%%TODO: always NS_JABER_CLIENT?
|
||||
%%TODO: always NS_JABBER_CLIENT?
|
||||
Msg =
|
||||
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'message',
|
||||
attrs = [#xmlattr{name = 'type', value = "normal"}],
|
||||
@ -3370,8 +3378,8 @@ add_to_log(Type, Data, StateData) ->
|
||||
%% Users number checking
|
||||
|
||||
tab_add_online_user(JID, StateData) ->
|
||||
LUser = JID#jid.lnode,
|
||||
LServer = JID#jid.ldomain,
|
||||
LUser = exmpp_jid:lnode(JID),
|
||||
LServer = exmpp_jid:ldomain(JID),
|
||||
US = {LUser, LServer},
|
||||
Room = StateData#state.room,
|
||||
Host = StateData#state.host,
|
||||
@ -3381,7 +3389,9 @@ tab_add_online_user(JID, StateData) ->
|
||||
|
||||
|
||||
|
||||
tab_remove_online_user(#jid{lnode = LUser, ldomain = LServer}, StateData) ->
|
||||
tab_remove_online_user(JID, StateData) when ?IS_JID(JID) ->
|
||||
LUser = exmpp_jid:lnode(JID),
|
||||
LServer = exmpp_jid:ldomain(JID),
|
||||
tab_remove_online_user({LUser, LServer, none},StateData);
|
||||
|
||||
tab_remove_online_user({LUser, LServer,_}, StateData) ->
|
||||
@ -3393,8 +3403,8 @@ tab_remove_online_user({LUser, LServer,_}, StateData) ->
|
||||
#muc_online_users{us = US, room = Room, host = Host}).
|
||||
|
||||
tab_count_user(JID) ->
|
||||
LUser = JID#jid.lnode,
|
||||
LServer = JID#jid.ldomain,
|
||||
LUser = exmpp_jid:lnode(JID),
|
||||
LServer = exmpp_jid:ldomain(JID),
|
||||
US = {LUser, LServer},
|
||||
case catch ets:select(
|
||||
muc_online_users,
|
||||
@ -3407,11 +3417,7 @@ tab_count_user(JID) ->
|
||||
|
||||
|
||||
jid_replace_resource(JID, Resource) ->
|
||||
case exmpp_stringprep:resourceprep(Resource) of
|
||||
error -> error;
|
||||
LResource ->
|
||||
JID#jid{resource = Resource, lresource = LResource}
|
||||
end.
|
||||
exmpp_jid:bare_jid_to_jid(JID, Resource).
|
||||
|
||||
|
||||
|
||||
|
@ -59,24 +59,25 @@
|
||||
-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
mnesia:create_table(offline_msg,
|
||||
[{disc_only_copies, [node()]},
|
||||
{type, bag},
|
||||
{attributes, record_info(fields, offline_msg)}]),
|
||||
update_table(),
|
||||
ejabberd_hooks:add(offline_message_hook, Host,
|
||||
ejabberd_hooks:add(offline_message_hook, HostB,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:add(resend_offline_messages_hook, Host,
|
||||
ejabberd_hooks:add(resend_offline_messages_hook, HostB,
|
||||
?MODULE, pop_offline_messages, 50),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:add(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(webadmin_page_host, Host,
|
||||
ejabberd_hooks:add(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:add(webadmin_user, Host,
|
||||
ejabberd_hooks:add(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
ejabberd_hooks:add(webadmin_user_parse_query, Host,
|
||||
ejabberd_hooks:add(webadmin_user_parse_query, HostB,
|
||||
?MODULE, webadmin_user_parse_query, 50),
|
||||
MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
@ -134,19 +135,20 @@ receive_all(US, Msgs) ->
|
||||
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(offline_message_hook, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(offline_message_hook, HostB,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:delete(resend_offline_messages_hook, Host,
|
||||
ejabberd_hooks:delete(resend_offline_messages_hook, HostB,
|
||||
?MODULE, pop_offline_messages, 50),
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(webadmin_page_host, Host,
|
||||
ejabberd_hooks:delete(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:delete(webadmin_user, Host,
|
||||
ejabberd_hooks:delete(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
ejabberd_hooks:delete(webadmin_user_parse_query, Host,
|
||||
ejabberd_hooks:delete(webadmin_user_parse_query, HostB,
|
||||
?MODULE, webadmin_user_parse_query, 50),
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
exit(whereis(Proc), stop),
|
||||
@ -159,10 +161,11 @@ store_packet(From, To, Packet) ->
|
||||
(Type /= "headline") ->
|
||||
case check_event(From, To, Packet) of
|
||||
true ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = To,
|
||||
LUser = exmpp_jid:lnode_as_list(To),
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
TimeStamp = now(),
|
||||
Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
|
||||
gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
|
||||
gen_mod:get_module_proc(LServer, ?PROCNAME) !
|
||||
#offline_msg{us = {LUser, LServer},
|
||||
timestamp = TimeStamp,
|
||||
expire = Expire,
|
||||
@ -267,10 +270,11 @@ resend_offline_messages(User, Server) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
pop_offline_messages(Ls, User, Server) ->
|
||||
pop_offline_messages(Ls, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
US = {LUser, LServer},
|
||||
F = fun() ->
|
||||
Rs = mnesia:wread({offline_msg, US}),
|
||||
@ -347,7 +351,7 @@ remove_old_messages(Days) ->
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
|
@ -58,19 +58,20 @@
|
||||
-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
|
||||
|
||||
start(Host, Opts) ->
|
||||
ejabberd_hooks:add(offline_message_hook, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:add(offline_message_hook, HostB,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:add(resend_offline_messages_hook, Host,
|
||||
ejabberd_hooks:add(resend_offline_messages_hook, HostB,
|
||||
?MODULE, pop_offline_messages, 50),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:add(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(webadmin_page_host, Host,
|
||||
ejabberd_hooks:add(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:add(webadmin_user, Host,
|
||||
ejabberd_hooks:add(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
ejabberd_hooks:add(webadmin_user_parse_query, Host,
|
||||
ejabberd_hooks:add(webadmin_user_parse_query, HostB,
|
||||
?MODULE, webadmin_user_parse_query, 50),
|
||||
MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
@ -102,7 +103,7 @@ loop(Host, MaxOfflineMsgs) ->
|
||||
fun(M) ->
|
||||
Username =
|
||||
ejabberd_odbc:escape(
|
||||
(M#offline_msg.to)#jid.lnode),
|
||||
exmpp_jid:lnode_as_list(M#offline_msg.to)),
|
||||
From = M#offline_msg.from,
|
||||
To = M#offline_msg.to,
|
||||
Packet0 = exmpp_stanza:set_jids(
|
||||
@ -142,19 +143,20 @@ receive_all(Username, Msgs) ->
|
||||
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(offline_message_hook, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(offline_message_hook, HostB,
|
||||
?MODULE, store_packet, 50),
|
||||
ejabberd_hooks:delete(resend_offline_messages_hook, Host,
|
||||
ejabberd_hooks:delete(resend_offline_messages_hook, HostB,
|
||||
?MODULE, pop_offline_messages, 50),
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(webadmin_page_host, Host,
|
||||
ejabberd_hooks:delete(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:delete(webadmin_user, Host,
|
||||
ejabberd_hooks:delete(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
ejabberd_hooks:delete(webadmin_user_parse_query, Host,
|
||||
ejabberd_hooks:delete(webadmin_user_parse_query, HostB,
|
||||
?MODULE, webadmin_user_parse_query, 50),
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
exit(whereis(Proc), stop),
|
||||
@ -167,10 +169,10 @@ store_packet(From, To, Packet) ->
|
||||
(Type /= "headline") ->
|
||||
case check_event(From, To, Packet) of
|
||||
true ->
|
||||
#jid{lnode = LUser} = To,
|
||||
LUser = exmpp_jid:lnode_as_list(To),
|
||||
TimeStamp = now(),
|
||||
Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
|
||||
gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
|
||||
gen_mod:get_module_proc(exmpp_jid:ldomain_as_list(To), ?PROCNAME) !
|
||||
#offline_msg{user = LUser,
|
||||
timestamp = TimeStamp,
|
||||
expire = Expire,
|
||||
@ -241,17 +243,20 @@ find_x_expire(TimeStamp, [_ | Els]) ->
|
||||
find_x_expire(TimeStamp, Els).
|
||||
|
||||
|
||||
pop_offline_messages(Ls, User, Server) ->
|
||||
pop_offline_messages(Ls, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
EUser = ejabberd_odbc:escape(LUser),
|
||||
case odbc_queries:get_and_del_spool_msg_t(LServer, EUser) of
|
||||
{atomic, {selected, ["username","xml"], Rs}} ->
|
||||
Ls ++ lists:flatmap(
|
||||
fun({_, XML}) ->
|
||||
try
|
||||
[El] = exmpp_xml:parse_document(XML, [names_as_atom]),
|
||||
[El] = exmpp_xml:parse_document(XML,
|
||||
[names_as_atom, {check_elems, xmpp},
|
||||
{check_nss,xmpp}, {check_attrs,xmpp}]),
|
||||
To = exmpp_jid:list_to_jid(
|
||||
exmpp_stanza:get_recipient(El)),
|
||||
From = exmpp_jid:list_to_jid(
|
||||
@ -271,7 +276,8 @@ pop_offline_messages(Ls, User, Server) ->
|
||||
end.
|
||||
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
@ -327,7 +333,9 @@ user_queue(User, Server, Query, Lang) ->
|
||||
{selected, ["username", "xml"], Rs} ->
|
||||
lists:flatmap(
|
||||
fun({_, XML}) ->
|
||||
try exmpp_xml:parse_document(XML, [names_as_atom]) of
|
||||
try exmpp_xml:parse_document(XML,
|
||||
[names_as_atom, {check_elems, xmpp},
|
||||
{check_nss,xmpp}, {check_attrs,xmpp}]) of
|
||||
[El] ->
|
||||
[El]
|
||||
catch
|
||||
@ -394,7 +402,9 @@ user_queue_parse_query(Username, LServer, Query) ->
|
||||
{selected, ["xml", "seq"], Rs} ->
|
||||
lists:flatmap(
|
||||
fun({XML, Seq}) ->
|
||||
try exmpp_xml:parse_document(XML, [names_as_atom]) of
|
||||
try exmpp_xml:parse_document(XML,
|
||||
[names_as_atom, {check_elems, xmpp},
|
||||
{check_nss,xmpp}, {check_attrs,xmpp}]) of
|
||||
[El] ->
|
||||
[{El, Seq}]
|
||||
catch
|
||||
|
@ -44,33 +44,35 @@
|
||||
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
mnesia:create_table(privacy, [{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, privacy)}]),
|
||||
update_table(),
|
||||
ejabberd_hooks:add(privacy_iq_get, Host,
|
||||
ejabberd_hooks:add(privacy_iq_get, HostB,
|
||||
?MODULE, process_iq_get, 50),
|
||||
ejabberd_hooks:add(privacy_iq_set, Host,
|
||||
ejabberd_hooks:add(privacy_iq_set, HostB,
|
||||
?MODULE, process_iq_set, 50),
|
||||
ejabberd_hooks:add(privacy_get_user_list, Host,
|
||||
ejabberd_hooks:add(privacy_get_user_list, HostB,
|
||||
?MODULE, get_user_list, 50),
|
||||
ejabberd_hooks:add(privacy_check_packet, Host,
|
||||
ejabberd_hooks:add(privacy_check_packet, HostB,
|
||||
?MODULE, check_packet, 50),
|
||||
ejabberd_hooks:add(privacy_updated_list, Host,
|
||||
ejabberd_hooks:add(privacy_updated_list, HostB,
|
||||
?MODULE, updated_list, 50),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
|
||||
?MODULE, process_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(privacy_iq_get, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(privacy_iq_get, HostB,
|
||||
?MODULE, process_iq_get, 50),
|
||||
ejabberd_hooks:delete(privacy_iq_set, Host,
|
||||
ejabberd_hooks:delete(privacy_iq_set, HostB,
|
||||
?MODULE, process_iq_set, 50),
|
||||
ejabberd_hooks:delete(privacy_get_user_list, Host,
|
||||
ejabberd_hooks:delete(privacy_get_user_list, HostB,
|
||||
?MODULE, get_user_list, 50),
|
||||
ejabberd_hooks:delete(privacy_check_packet, Host,
|
||||
ejabberd_hooks:delete(privacy_check_packet, HostB,
|
||||
?MODULE, check_packet, 50),
|
||||
ejabberd_hooks:delete(privacy_updated_list, Host,
|
||||
ejabberd_hooks:delete(privacy_updated_list, HostB,
|
||||
?MODULE, updated_list, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY).
|
||||
|
||||
@ -80,7 +82,8 @@ process_iq(_From, _To, IQ_Rec) ->
|
||||
|
||||
process_iq_get(_, From, _To, #iq{payload = SubEl},
|
||||
#userlist{name = Active}) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case exmpp_xml:get_child_elements(SubEl) of
|
||||
[] ->
|
||||
process_lists_get(LUser, LServer, Active);
|
||||
@ -238,7 +241,8 @@ list_to_action(S) ->
|
||||
|
||||
|
||||
process_iq_set(_, From, _To, #iq{payload = SubEl}) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case exmpp_xml:get_child_elements(SubEl) of
|
||||
[#xmlel{name = Name} = Child] ->
|
||||
ListName = exmpp_xml:get_attribute(Child, 'name', false),
|
||||
@ -510,10 +514,11 @@ parse_matches1(_Item, [#xmlel{} | _Els]) ->
|
||||
|
||||
|
||||
|
||||
get_user_list(_, User, Server) ->
|
||||
get_user_list(_, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
case catch mnesia:dirty_read(privacy, {LUser, LServer}) of
|
||||
[] ->
|
||||
#userlist{};
|
||||
@ -542,7 +547,8 @@ get_user_list(_, User, Server) ->
|
||||
check_packet(_, User, Server,
|
||||
#userlist{list = List},
|
||||
{From, To, #xmlel{name = PName}},
|
||||
Dir) when PName =:= message ;
|
||||
Dir) when
|
||||
PName =:= message ;
|
||||
PName =:= iq ;
|
||||
PName =:= presence ->
|
||||
case List of
|
||||
@ -554,7 +560,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(From),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
check_packet_aux(List, message,
|
||||
LJID, Subscription, Groups);
|
||||
@ -562,7 +569,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(From),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
check_packet_aux(List, iq,
|
||||
LJID, Subscription, Groups);
|
||||
@ -570,7 +578,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(From),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
check_packet_aux(List, presence_in,
|
||||
LJID, Subscription, Groups);
|
||||
@ -578,7 +587,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(To),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, To]),
|
||||
check_packet_aux(List, presence_out,
|
||||
LJID, Subscription, Groups);
|
||||
|
@ -43,30 +43,32 @@
|
||||
-include("mod_privacy.hrl").
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
ejabberd_hooks:add(privacy_iq_get, Host,
|
||||
ejabberd_hooks:add(privacy_iq_get, HostB,
|
||||
?MODULE, process_iq_get, 50),
|
||||
ejabberd_hooks:add(privacy_iq_set, Host,
|
||||
ejabberd_hooks:add(privacy_iq_set, HostB,
|
||||
?MODULE, process_iq_set, 50),
|
||||
ejabberd_hooks:add(privacy_get_user_list, Host,
|
||||
ejabberd_hooks:add(privacy_get_user_list, HostB,
|
||||
?MODULE, get_user_list, 50),
|
||||
ejabberd_hooks:add(privacy_check_packet, Host,
|
||||
ejabberd_hooks:add(privacy_check_packet, HostB,
|
||||
?MODULE, check_packet, 50),
|
||||
ejabberd_hooks:add(privacy_updated_list, Host,
|
||||
ejabberd_hooks:add(privacy_updated_list, HostB,
|
||||
?MODULE, updated_list, 50),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
|
||||
?MODULE, process_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(privacy_iq_get, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(privacy_iq_get, HostB,
|
||||
?MODULE, process_iq_get, 50),
|
||||
ejabberd_hooks:delete(privacy_iq_set, Host,
|
||||
ejabberd_hooks:delete(privacy_iq_set, HostB,
|
||||
?MODULE, process_iq_set, 50),
|
||||
ejabberd_hooks:delete(privacy_get_user_list, Host,
|
||||
ejabberd_hooks:delete(privacy_get_user_list, HostB,
|
||||
?MODULE, get_user_list, 50),
|
||||
ejabberd_hooks:delete(privacy_check_packet, Host,
|
||||
ejabberd_hooks:delete(privacy_check_packet, HostB,
|
||||
?MODULE, check_packet, 50),
|
||||
ejabberd_hooks:delete(privacy_updated_list, Host,
|
||||
ejabberd_hooks:delete(privacy_updated_list, HostB,
|
||||
?MODULE, updated_list, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY).
|
||||
|
||||
@ -76,7 +78,8 @@ process_iq(_From, _To, IQ_Rec) ->
|
||||
|
||||
process_iq_get(_, From, _To, #iq{payload = SubEl},
|
||||
#userlist{name = Active}) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case exmpp_xml:get_child_elements(SubEl) of
|
||||
[] ->
|
||||
process_lists_get(LUser, LServer, Active);
|
||||
@ -244,7 +247,8 @@ list_to_action(S) ->
|
||||
|
||||
|
||||
process_iq_set(_, From, _To, #iq{payload = SubEl}) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case exmpp_xml:get_child_elements(SubEl) of
|
||||
[#xmlel{name = Name} = Child] ->
|
||||
ListName = exmpp_xml:get_attribute(Child, 'name', false),
|
||||
@ -511,10 +515,11 @@ parse_matches1(_Item, [#xmlel{} | _Els]) ->
|
||||
|
||||
|
||||
|
||||
get_user_list(_, User, Server) ->
|
||||
get_user_list(_, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
case catch sql_get_default_privacy_list(LUser, LServer) of
|
||||
{selected, ["name"], []} ->
|
||||
#userlist{};
|
||||
@ -541,7 +546,8 @@ get_user_list(_, User, Server) ->
|
||||
check_packet(_, User, Server,
|
||||
#userlist{list = List},
|
||||
{From, To, #xmlel{name = PName}},
|
||||
Dir) when PName =:= message ;
|
||||
Dir) when
|
||||
PName =:= message ;
|
||||
PName =:= iq ;
|
||||
PName =:= presence ->
|
||||
case List of
|
||||
@ -553,7 +559,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(From),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
check_packet_aux(List, message,
|
||||
LJID, Subscription, Groups);
|
||||
@ -561,7 +568,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(From),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
check_packet_aux(List, iq,
|
||||
LJID, Subscription, Groups);
|
||||
@ -569,7 +577,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(From),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, From]),
|
||||
check_packet_aux(List, presence_in,
|
||||
LJID, Subscription, Groups);
|
||||
@ -577,7 +586,8 @@ check_packet(_, User, Server,
|
||||
LJID = jlib:short_prepd_jid(To),
|
||||
{Subscription, Groups} =
|
||||
ejabberd_hooks:run_fold(
|
||||
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
|
||||
roster_get_jid_info,
|
||||
Server,
|
||||
{none, []}, [User, Server, To]),
|
||||
check_packet_aux(List, presence_out,
|
||||
LJID, Subscription, Groups);
|
||||
|
@ -41,18 +41,20 @@
|
||||
-record(private_storage, {usns, xml}).
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
mnesia:create_table(private_storage,
|
||||
[{disc_only_copies, [node()]},
|
||||
{attributes, record_info(fields, private_storage)}]),
|
||||
update_table(),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
|
||||
?MODULE, process_sm_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE).
|
||||
|
||||
@ -71,7 +73,8 @@ process_sm_iq(From, To, #iq{type = Type} = IQ_Rec) ->
|
||||
end.
|
||||
|
||||
process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case catch get_data(LUser,
|
||||
LServer,
|
||||
exmpp_xml:get_child_elements(SubEl)) of
|
||||
@ -85,7 +88,8 @@ process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
|
||||
|
||||
|
||||
process_iq_set(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
F = fun() ->
|
||||
lists:foreach(
|
||||
fun(El) ->
|
||||
@ -108,7 +112,8 @@ check_packet(From, To, IQ_Rec, [F | R]) ->
|
||||
ok -> check_packet(From, To, IQ_Rec, R)
|
||||
end.
|
||||
|
||||
check_domain(#jid{ldomain = LServer}, _To, _IQ_Rec) ->
|
||||
check_domain(From, _To, _IQ_Rec) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
true -> ok;
|
||||
false -> {error, 'not-allowed'}
|
||||
@ -158,7 +163,8 @@ get_data(LUser, LServer, [El | Els], Res) ->
|
||||
[El | Res])
|
||||
end.
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
|
@ -39,14 +39,16 @@
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
|
||||
?MODULE, process_sm_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE).
|
||||
|
||||
@ -65,7 +67,8 @@ process_sm_iq(From, To, #iq{type = Type} = IQ_Rec) ->
|
||||
end.
|
||||
|
||||
process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case catch get_data(LUser,
|
||||
LServer,
|
||||
exmpp_xml:get_child_elements(SubEl)) of
|
||||
@ -79,7 +82,8 @@ process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
|
||||
|
||||
|
||||
process_iq_set(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
F = fun() ->
|
||||
lists:foreach(
|
||||
fun(El) ->
|
||||
@ -102,7 +106,8 @@ check_packet(From, To, IQ_Rec, [F | R]) ->
|
||||
ok -> check_packet(From, To, IQ_Rec, R)
|
||||
end.
|
||||
|
||||
check_domain(#jid{ldomain = LServer}, _To, _IQ_Rec) ->
|
||||
check_domain(From, _To, _IQ_Rec) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
true -> ok;
|
||||
false -> {error, 'not-allowed'}
|
||||
@ -151,7 +156,9 @@ get_data(LUser, LServer, [El | Els], Res) ->
|
||||
LXMLNS = ejabberd_odbc:escape(XMLNS),
|
||||
case catch odbc_queries:get_private_data(LServer, Username, LXMLNS) of
|
||||
{selected, ["data"], [{SData}]} ->
|
||||
[Data] = exmpp_xml:parse_document(SData,[names_as_atom]),
|
||||
[Data] = exmpp_xml:parse_document(SData,
|
||||
[names_as_atom, {check_elems, xmpp},
|
||||
{check_nss,xmpp}, {check_attrs,xmpp}]),
|
||||
get_data(LUser, LServer, Els, [Data | Res]);
|
||||
%% MREMOND: I wonder when the query could return a vcard ?
|
||||
{selected, ["vcard"], []} ->
|
||||
@ -162,7 +169,7 @@ get_data(LUser, LServer, [El | Els], Res) ->
|
||||
end.
|
||||
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
|
@ -631,7 +631,7 @@ get_states(Host, Node) ->
|
||||
get_state(Host, Node, JID) ->
|
||||
StateId = {JID, {Host, Node}},
|
||||
case mnesia:read({pubsub_state, StateId}) of
|
||||
[State] when is_record(State, pubsub_state) -> State
|
||||
[State] when is_record(State, pubsub_state) -> State;
|
||||
_ -> #pubsub_state{stateid=StateId}
|
||||
end.
|
||||
|
||||
|
@ -40,14 +40,15 @@
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_INBAND_REGISTER,
|
||||
?MODULE, process_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_INBAND_REGISTER,
|
||||
?MODULE, process_iq, IQDisc),
|
||||
ejabberd_hooks:add(c2s_stream_features, Host,
|
||||
ejabberd_hooks:add(c2s_stream_features, HostB,
|
||||
?MODULE, stream_feature_register, 50),
|
||||
ejabberd_hooks:add(c2s_unauthenticated_iq, Host,
|
||||
ejabberd_hooks:add(c2s_unauthenticated_iq, HostB,
|
||||
?MODULE, unauthenticated_iq_register, 50),
|
||||
mnesia:create_table(mod_register_ip,
|
||||
[{ram_copies, [node()]},
|
||||
@ -57,9 +58,10 @@ start(Host, Opts) ->
|
||||
ok.
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(c2s_stream_features, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(c2s_stream_features, HostB,
|
||||
?MODULE, stream_feature_register, 50),
|
||||
ejabberd_hooks:delete(c2s_unauthenticated_iq, Host,
|
||||
ejabberd_hooks:delete(c2s_unauthenticated_iq, HostB,
|
||||
?MODULE, unauthenticated_iq_register, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_INBAND_REGISTER),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_INBAND_REGISTER).
|
||||
@ -74,17 +76,20 @@ unauthenticated_iq_register(_Acc,
|
||||
{A, _Port} -> A;
|
||||
_ -> undefined
|
||||
end,
|
||||
ResIQ = process_iq(#jid{},
|
||||
exmpp_jid:make_bare_jid(Server),
|
||||
BareJID = exmpp_jid:make_bare_jid(Server),
|
||||
ResIQ = process_iq(exmpp_jid:make_jid(),
|
||||
BareJID,
|
||||
IQ_Rec,
|
||||
Address),
|
||||
exmpp_iq:iq_to_xmlel(ResIQ, exmpp_jid:make_bare_jid(Server), undefined);
|
||||
exmpp_iq:iq_to_xmlel(ResIQ, BareJID, undefined);
|
||||
|
||||
unauthenticated_iq_register(Acc, _Server, _IQ, _IP) ->
|
||||
Acc.
|
||||
|
||||
process_iq(From, To, IQ) ->
|
||||
process_iq(From, To, IQ, jlib:short_prepd_bare_jid(From)).
|
||||
process_iq(From, To, IQ, {exmpp_jid:lnode_as_list(From),
|
||||
exmpp_jid:ldomain_as_list(From),
|
||||
exmpp_jid:lresource_as_list(From)}).
|
||||
|
||||
process_iq(From, To,
|
||||
#iq{type = Type, lang = Lang, payload = SubEl} = IQ_Rec,
|
||||
@ -94,12 +99,12 @@ process_iq(From, To,
|
||||
UTag = exmpp_xml:get_element(SubEl, 'username'),
|
||||
PTag = exmpp_xml:get_element(SubEl, 'password'),
|
||||
RTag = exmpp_xml:get_element(SubEl, 'remove'),
|
||||
Server = To#jid.ldomain,
|
||||
Server = exmpp_jid:ldomain_as_list(To),
|
||||
if
|
||||
(UTag /= undefined) and (RTag /= undefined) ->
|
||||
User = exmpp_xml:get_cdata_as_list(UTag),
|
||||
case From of
|
||||
#jid{node = User, ldomain = Server} ->
|
||||
case {exmpp_jid:node_as_list(From), exmpp_jid:ldomain_as_list(From)} of
|
||||
{User, Server} ->
|
||||
ejabberd_auth:remove_user(User, Server),
|
||||
exmpp_iq:result(IQ_Rec, SubEl);
|
||||
_ ->
|
||||
@ -132,14 +137,18 @@ process_iq(From, To,
|
||||
end
|
||||
end;
|
||||
(UTag == undefined) and (RTag /= undefined) ->
|
||||
case From of
|
||||
#jid{node = User,
|
||||
ldomain = Server,
|
||||
resource = Resource} ->
|
||||
case {exmpp_jid:node_as_list(From),
|
||||
exmpp_jid:ldomain_as_list(From),
|
||||
exmpp_jid:resource_as_list(From)}of
|
||||
{User, Server, Resource} ->
|
||||
ResIQ = exmpp_iq:result(IQ_Rec, SubEl),
|
||||
ejabberd_router:route(
|
||||
exmpp_jid:make_jid(User, Server, Resource),
|
||||
exmpp_jid:make_jid(User, Server, Resource),
|
||||
exmpp_jid:make_jid(User,
|
||||
Server,
|
||||
Resource),
|
||||
exmpp_jid:make_jid(User,
|
||||
Server,
|
||||
Resource),
|
||||
exmpp_iq:iq_to_xmlel(ResIQ)),
|
||||
ejabberd_auth:remove_user(User, Server),
|
||||
ignore;
|
||||
@ -149,8 +158,8 @@ process_iq(From, To,
|
||||
(UTag /= undefined) and (PTag /= undefined) ->
|
||||
User = exmpp_xml:get_cdata_as_list(UTag),
|
||||
Password = exmpp_xml:get_cdata_as_list(PTag),
|
||||
case From of
|
||||
#jid{node = User, ldomain = Server} ->
|
||||
case {exmpp_jid:node_as_list(From), exmpp_jid:ldomain_as_list(From)} of
|
||||
{User, Server} ->
|
||||
try_set_password(User, Server, Password, IQ_Rec, SubEl);
|
||||
_ ->
|
||||
case try_register(User, Server, Password,
|
||||
@ -195,7 +204,8 @@ try_register(User, Server, Password, Source, Lang) ->
|
||||
false ->
|
||||
{error, 'bad-request'};
|
||||
_ ->
|
||||
JID = exmpp_jid:make_bare_jid(User, Server),
|
||||
JID = exmpp_jid:make_bare_jid(User,
|
||||
Server),
|
||||
Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
|
||||
case acl:match_rule(Server, Access, JID) of
|
||||
deny ->
|
||||
@ -205,8 +215,8 @@ try_register(User, Server, Password, Source, Lang) ->
|
||||
true ->
|
||||
case ejabberd_auth:try_register(User, Server, Password) of
|
||||
{atomic, ok} ->
|
||||
ejabberd_hooks:run(user_registered, Server,
|
||||
[User, Server]),
|
||||
ejabberd_hooks:run(user_registered, exmpp_jid:domain(JID),
|
||||
[exmpp_jid:node(JID), exmpp_jid:domain(JID)]),
|
||||
send_welcome_message(JID),
|
||||
send_registration_notifications(JID),
|
||||
ok;
|
||||
@ -233,7 +243,7 @@ try_register(User, Server, Password, Source, Lang) ->
|
||||
|
||||
|
||||
send_welcome_message(JID) ->
|
||||
Host = JID#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(JID),
|
||||
case gen_mod:get_module_opt(Host, ?MODULE, welcome_message, {"", ""}) of
|
||||
{"", ""} ->
|
||||
ok;
|
||||
@ -247,7 +257,7 @@ send_welcome_message(JID) ->
|
||||
end.
|
||||
|
||||
send_registration_notifications(UJID) ->
|
||||
Host = UJID#jid.ldomain,
|
||||
Host = exmpp_jid:ldomain_as_list(UJID),
|
||||
case gen_mod:get_module_opt(Host, ?MODULE, registration_watchers, []) of
|
||||
[] -> ok;
|
||||
JIDs when is_list(JIDs) ->
|
||||
|
@ -53,61 +53,63 @@
|
||||
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
mnesia:create_table(roster,[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, roster)}]),
|
||||
update_table(),
|
||||
mnesia:add_table_index(roster, us),
|
||||
ejabberd_hooks:add(roster_get, Host,
|
||||
ejabberd_hooks:add(roster_get, HostB,
|
||||
?MODULE, get_user_roster, 50),
|
||||
ejabberd_hooks:add(roster_in_subscription, Host,
|
||||
ejabberd_hooks:add(roster_in_subscription, HostB,
|
||||
?MODULE, in_subscription, 50),
|
||||
ejabberd_hooks:add(roster_out_subscription, Host,
|
||||
ejabberd_hooks:add(roster_out_subscription, HostB,
|
||||
?MODULE, out_subscription, 50),
|
||||
ejabberd_hooks:add(roster_get_subscription_lists, Host,
|
||||
ejabberd_hooks:add(roster_get_subscription_lists, HostB,
|
||||
?MODULE, get_subscription_lists, 50),
|
||||
ejabberd_hooks:add(roster_get_jid_info, Host,
|
||||
ejabberd_hooks:add(roster_get_jid_info, HostB,
|
||||
?MODULE, get_jid_info, 50),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:add(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(resend_subscription_requests_hook, Host,
|
||||
ejabberd_hooks:add(resend_subscription_requests_hook, HostB,
|
||||
?MODULE, get_in_pending_subscriptions, 50),
|
||||
ejabberd_hooks:add(webadmin_page_host, Host,
|
||||
ejabberd_hooks:add(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:add(webadmin_user, Host,
|
||||
ejabberd_hooks:add(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
|
||||
?MODULE, process_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(roster_get, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(roster_get, HostB,
|
||||
?MODULE, get_user_roster, 50),
|
||||
ejabberd_hooks:delete(roster_in_subscription, Host,
|
||||
ejabberd_hooks:delete(roster_in_subscription, HostB,
|
||||
?MODULE, in_subscription, 50),
|
||||
ejabberd_hooks:delete(roster_out_subscription, Host,
|
||||
ejabberd_hooks:delete(roster_out_subscription, HostB,
|
||||
?MODULE, out_subscription, 50),
|
||||
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
|
||||
ejabberd_hooks:delete(roster_get_subscription_lists, HostB,
|
||||
?MODULE, get_subscription_lists, 50),
|
||||
ejabberd_hooks:delete(roster_get_jid_info, Host,
|
||||
ejabberd_hooks:delete(roster_get_jid_info, HostB,
|
||||
?MODULE, get_jid_info, 50),
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
|
||||
ejabberd_hooks:delete(resend_subscription_requests_hook, HostB,
|
||||
?MODULE, get_in_pending_subscriptions, 50),
|
||||
ejabberd_hooks:delete(webadmin_page_host, Host,
|
||||
ejabberd_hooks:delete(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:delete(webadmin_user, Host,
|
||||
ejabberd_hooks:delete(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||
?NS_ROSTER).
|
||||
|
||||
|
||||
process_iq(From, To, IQ_Rec) ->
|
||||
#jid{ldomain = LServer} = From,
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
true ->
|
||||
process_local_iq(From, To, IQ_Rec);
|
||||
@ -123,8 +125,8 @@ process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
|
||||
|
||||
|
||||
process_iq_get(From, To, IQ_Rec) ->
|
||||
US = {From#jid.lnode, From#jid.ldomain},
|
||||
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
|
||||
US = {exmpp_jid:lnode(From), exmpp_jid:ldomain_(From)},
|
||||
case catch ejabberd_hooks:run_fold(roster_get, exmpp_jid:ldomain(To), [], [US]) of
|
||||
Items when is_list(Items) ->
|
||||
XItems = lists:map(fun item_to_xml/1, Items),
|
||||
Result = #xmlel{ns = ?NS_ROSTER, name = 'query',
|
||||
@ -189,7 +191,9 @@ process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
|
||||
process_item_set(From, To, #xmlel{} = El) ->
|
||||
try
|
||||
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
|
||||
#jid{node = User, lnode = LUser, ldomain = LServer} = From,
|
||||
User = exmpp_jid:node(From),
|
||||
LUser = exmpp_jid:lnode(From),
|
||||
LServer = exmpp_jid:ldomain(From),
|
||||
JID = jlib:short_jid(JID1),
|
||||
LJID = jlib:short_prepd_jid(JID1),
|
||||
F = fun() ->
|
||||
@ -216,7 +220,7 @@ process_item_set(From, To, #xmlel{} = El) ->
|
||||
%% If the item exist in shared roster, take the
|
||||
%% subscription information from there:
|
||||
Item3 = ejabberd_hooks:run_fold(roster_process_item,
|
||||
LServer, Item2, [LServer]),
|
||||
exmpp_jid:ldomain(From), Item2, [exmpp_jid:ldomain(From)]),
|
||||
{Item, Item3}
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
@ -305,8 +309,8 @@ process_item_els(Item, []) ->
|
||||
Item.
|
||||
|
||||
|
||||
push_item(User, Server, From, Item) ->
|
||||
ejabberd_sm:route(#jid{},
|
||||
push_item(User, Server, From, Item) when is_binary(User), is_binary(Server) ->
|
||||
ejabberd_sm:route(exmpp_jid:make_jid(),
|
||||
exmpp_jid:make_bare_jid(User, Server),
|
||||
#xmlel{name = 'broadcast', children =
|
||||
[{item,
|
||||
@ -317,7 +321,8 @@ push_item(User, Server, From, Item) ->
|
||||
end, ejabberd_sm:get_user_resources(User, Server)).
|
||||
|
||||
% TODO: don't push to those who didn't load roster
|
||||
push_item(User, Server, Resource, From, Item) ->
|
||||
push_item(User, Server, Resource, From, Item) when is_binary(User),
|
||||
is_binary(Server) ->
|
||||
Request = #xmlel{ns = ?NS_ROSTER, name = 'query',
|
||||
children = [item_to_xml(Item)]},
|
||||
ResIQ = exmpp_iq:set(?NS_JABBER_CLIENT, Request,
|
||||
@ -327,11 +332,10 @@ push_item(User, Server, Resource, From, Item) ->
|
||||
exmpp_jid:make_jid(User, Server, Resource),
|
||||
ResIQ).
|
||||
|
||||
get_subscription_lists(_, User, Server) ->
|
||||
get_subscription_lists(_, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
US = {User,Server},
|
||||
case mnesia:dirty_index_read(roster, US, #roster.us) of
|
||||
Items when is_list(Items) ->
|
||||
fill_subscription_lists(Items, [], []);
|
||||
@ -370,17 +374,16 @@ in_subscription(_, User, Server, JID, Type, Reason) ->
|
||||
out_subscription(User, Server, JID, Type) ->
|
||||
process_subscription(out, User, Server, JID, Type, <<>>).
|
||||
|
||||
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
process_subscription(Direction, User, Server, JID1, Type, Reason)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
US = {User, Server},
|
||||
LJID = jlib:short_prepd_jid(JID1),
|
||||
F = fun() ->
|
||||
Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
|
||||
Item = case mnesia:read({roster, {User, Server, LJID}}) of
|
||||
[] ->
|
||||
JID = jlib:short_jid(JID1),
|
||||
#roster{usj = {LUser, LServer, LJID},
|
||||
#roster{usj = {User, Server, LJID},
|
||||
us = US,
|
||||
jid = JID};
|
||||
[I] ->
|
||||
@ -414,7 +417,7 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
{none, AutoReply};
|
||||
{none, none} when Item#roster.subscription == none,
|
||||
Item#roster.ask == in ->
|
||||
mnesia:delete({roster, {LUser, LServer, LJID}}),
|
||||
mnesia:delete({roster, {User, Server, LJID}}),
|
||||
{none, AutoReply};
|
||||
{Subscription, Pending} ->
|
||||
AskBinary = case AskMessage of
|
||||
@ -556,10 +559,11 @@ in_auto_reply(both, none, unsubscribe) -> unsubscribed;
|
||||
in_auto_reply(_, _, _) -> none.
|
||||
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = list_to_binary(exmpp_stringprep:nodeprep(User)),
|
||||
LServer = list_to_binary(exmpp_stringprep:nameprep(Server)),
|
||||
US = {LUser, LServer},
|
||||
F = fun() ->
|
||||
lists:foreach(fun(R) ->
|
||||
@ -645,9 +649,10 @@ process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
|
||||
process_item_attrs_ws(Item, []) ->
|
||||
Item.
|
||||
|
||||
get_in_pending_subscriptions(Ls, User, Server) ->
|
||||
get_in_pending_subscriptions(Ls, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
JID = exmpp_jid:make_bare_jid(User, Server),
|
||||
US = {JID#jid.lnode, JID#jid.ldomain},
|
||||
US = {exmpp_jid:lnode(JID), exmpp_jid:ldomain(JID)},
|
||||
case mnesia:dirty_index_read(roster, US, #roster.us) of
|
||||
Result when list(Result) ->
|
||||
Ls ++ lists:map(
|
||||
@ -676,12 +681,10 @@ get_in_pending_subscriptions(Ls, User, Server) ->
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
get_jid_info(_, User, Server, JID) ->
|
||||
get_jid_info(_, User, Server, JID) when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LJID = jlib:short_prepd_jid(JID),
|
||||
case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
|
||||
case catch mnesia:dirty_read(roster, {User, Server, LJID}) of
|
||||
[#roster{subscription = Subscription, groups = Groups}] ->
|
||||
{Subscription, Groups};
|
||||
_ ->
|
||||
@ -691,7 +694,7 @@ get_jid_info(_, User, Server, JID) ->
|
||||
{none, []};
|
||||
true ->
|
||||
case catch mnesia:dirty_read(
|
||||
roster, {LUser, LServer, LRJID}) of
|
||||
roster, {User, Server, LRJID}) of
|
||||
[#roster{subscription = Subscription,
|
||||
groups = Groups}] ->
|
||||
{Subscription, Groups};
|
||||
|
@ -52,56 +52,58 @@
|
||||
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
ejabberd_hooks:add(roster_get, Host,
|
||||
ejabberd_hooks:add(roster_get, HostB,
|
||||
?MODULE, get_user_roster, 50),
|
||||
ejabberd_hooks:add(roster_in_subscription, Host,
|
||||
ejabberd_hooks:add(roster_in_subscription, HostB,
|
||||
?MODULE, in_subscription, 50),
|
||||
ejabberd_hooks:add(roster_out_subscription, Host,
|
||||
ejabberd_hooks:add(roster_out_subscription, HostB,
|
||||
?MODULE, out_subscription, 50),
|
||||
ejabberd_hooks:add(roster_get_subscription_lists, Host,
|
||||
ejabberd_hooks:add(roster_get_subscription_lists, HostB,
|
||||
?MODULE, get_subscription_lists, 50),
|
||||
ejabberd_hooks:add(roster_get_jid_info, Host,
|
||||
ejabberd_hooks:add(roster_get_jid_info, HostB,
|
||||
?MODULE, get_jid_info, 50),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:add(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:add(resend_subscription_requests_hook, Host,
|
||||
ejabberd_hooks:add(resend_subscription_requests_hook, HostB,
|
||||
?MODULE, get_in_pending_subscriptions, 50),
|
||||
ejabberd_hooks:add(webadmin_page_host, Host,
|
||||
ejabberd_hooks:add(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:add(webadmin_user, Host,
|
||||
ejabberd_hooks:add(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
|
||||
?MODULE, process_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(roster_get, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(roster_get, HostB,
|
||||
?MODULE, get_user_roster, 50),
|
||||
ejabberd_hooks:delete(roster_in_subscription, Host,
|
||||
ejabberd_hooks:delete(roster_in_subscription, HostB,
|
||||
?MODULE, in_subscription, 50),
|
||||
ejabberd_hooks:delete(roster_out_subscription, Host,
|
||||
ejabberd_hooks:delete(roster_out_subscription, HostB,
|
||||
?MODULE, out_subscription, 50),
|
||||
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
|
||||
ejabberd_hooks:delete(roster_get_subscription_lists, HostB,
|
||||
?MODULE, get_subscription_lists, 50),
|
||||
ejabberd_hooks:delete(roster_get_jid_info, Host,
|
||||
ejabberd_hooks:delete(roster_get_jid_info, HostB,
|
||||
?MODULE, get_jid_info, 50),
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, Host,
|
||||
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
|
||||
ejabberd_hooks:delete(resend_subscription_requests_hook, HostB,
|
||||
?MODULE, get_in_pending_subscriptions, 50),
|
||||
ejabberd_hooks:delete(webadmin_page_host, Host,
|
||||
ejabberd_hooks:delete(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:delete(webadmin_user, Host,
|
||||
ejabberd_hooks:delete(webadmin_user, HostB,
|
||||
?MODULE, webadmin_user, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
|
||||
|
||||
|
||||
process_iq(From, To, IQ_Rec) ->
|
||||
#jid{ldomain = LServer} = From,
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
true ->
|
||||
process_local_iq(From, To, IQ_Rec);
|
||||
@ -117,8 +119,8 @@ process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
|
||||
|
||||
|
||||
process_iq_get(From, To, IQ_Rec) ->
|
||||
US = {From#jid.lnode, From#jid.ldomain},
|
||||
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
|
||||
US = {exmpp_jid:lnode(From), exmpp_jid:ldomain(From)},
|
||||
case catch ejabberd_hooks:run_fold(roster_get, exmpp_jid:ldomain(To), [], [US]) of
|
||||
Items when is_list(Items) ->
|
||||
XItems = lists:map(fun item_to_xml/1, Items),
|
||||
Result = #xmlel{ns = ?NS_ROSTER, name = 'query',
|
||||
@ -136,13 +138,14 @@ get_user_roster(Acc, {LUser, LServer}) ->
|
||||
true
|
||||
end, Items) ++ Acc.
|
||||
|
||||
get_roster(LUser, LServer) ->
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
case catch odbc_queries:get_roster(LServer, Username) of
|
||||
get_roster(LUser, LServer) when is_binary(LUser), is_binary(LServer)->
|
||||
Username = ejabberd_odbc:escape(binary_to_list(LUser)),
|
||||
DomainString = binary_to_list(LServer),
|
||||
case catch odbc_queries:get_roster(DomainString, Username) of
|
||||
{selected, ["username", "jid", "nick", "subscription", "ask",
|
||||
"askmessage", "server", "subscribe", "type"],
|
||||
Items} when is_list(Items) ->
|
||||
JIDGroups = case catch odbc_queries:get_roster_jid_groups(LServer, Username) of
|
||||
JIDGroups = case catch odbc_queries:get_roster_jid_groups(DomainString, Username) of
|
||||
{selected, ["jid","grp"], JGrps}
|
||||
when is_list(JGrps) ->
|
||||
JGrps;
|
||||
@ -214,7 +217,8 @@ process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
|
||||
process_item_set(From, To, #xmlel{} = El) ->
|
||||
try
|
||||
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
|
||||
#jid{node = User, lnode = LUser, ldomain = LServer} = From,
|
||||
LUser = exmpp_jid:lnode_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
{U0, S0, R0} = LJID = jlib:short_prepd_jid(JID1),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(U0, S0, R0)),
|
||||
@ -229,7 +233,7 @@ process_item_set(From, To, #xmlel{} = El) ->
|
||||
us = {LUser, LServer},
|
||||
jid = LJID};
|
||||
[I] ->
|
||||
R = raw_to_record(LServer, I),
|
||||
R = raw_to_record(exmpp_jid:ldomain(From), I),
|
||||
case R of
|
||||
%% Bad JID in database:
|
||||
error ->
|
||||
@ -257,12 +261,12 @@ process_item_set(From, To, #xmlel{} = El) ->
|
||||
%% If the item exist in shared roster, take the
|
||||
%% subscription information from there:
|
||||
Item3 = ejabberd_hooks:run_fold(roster_process_item,
|
||||
LServer, Item2, [LServer]),
|
||||
exmpp_jid:ldomain(From), Item2, [exmpp_jid:ldomain(From)]),
|
||||
{Item, Item3}
|
||||
end,
|
||||
case odbc_queries:sql_transaction(LServer, F) of
|
||||
{atomic, {OldItem, Item}} ->
|
||||
push_item(User, LServer, To, Item),
|
||||
push_item(exmpp_jid:node(From), exmpp_jid:ldomain(From), To, Item),
|
||||
case Item#roster.subscription of
|
||||
remove ->
|
||||
IsTo = case OldItem#roster.subscription of
|
||||
@ -340,8 +344,8 @@ process_item_els(Item, []) ->
|
||||
Item.
|
||||
|
||||
|
||||
push_item(User, Server, From, Item) ->
|
||||
ejabberd_sm:route(#jid{},
|
||||
push_item(User, Server, From, Item) when is_binary(User), is_binary(Server) ->
|
||||
ejabberd_sm:route(exmpp_jid:make_jid(),
|
||||
exmpp_jid:make_bare_jid(User, Server),
|
||||
#xmlel{name = 'broadcast', children =
|
||||
[{item,
|
||||
@ -362,16 +366,17 @@ push_item(User, Server, Resource, From, Item) ->
|
||||
exmpp_jid:make_jid(User, Server, Resource),
|
||||
ResIQ).
|
||||
|
||||
get_subscription_lists(_, User, Server) ->
|
||||
get_subscription_lists(_, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
case catch odbc_queries:get_roster(LServer, Username) of
|
||||
{selected, ["username", "jid", "nick", "subscription", "ask",
|
||||
"askmessage", "server", "subscribe", "type"],
|
||||
Items} when is_list(Items) ->
|
||||
fill_subscription_lists(LServer, Items, [], []);
|
||||
fill_subscription_lists(Server, Items, [], []);
|
||||
_ ->
|
||||
{[], []}
|
||||
end
|
||||
@ -414,10 +419,11 @@ in_subscription(_, User, Server, JID, Type, Reason) ->
|
||||
out_subscription(User, Server, JID, Type) ->
|
||||
process_subscription(out, User, Server, JID, Type, <<>>).
|
||||
|
||||
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
process_subscription(Direction, User, Server, JID1, Type, Reason)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
{N0,D0,R0} = LJID = jlib:short_prepd_jid(JID1),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(N0,D0,R0)),
|
||||
@ -430,7 +436,7 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
[I]} ->
|
||||
%% raw_to_record can return error, but
|
||||
%% jlib_to_string would fail before this point
|
||||
R = raw_to_record(LServer, I),
|
||||
R = raw_to_record(list_to_binary(LServer), I),
|
||||
Groups =
|
||||
case odbc_queries:get_roster_groups(LServer, Username, SJID) of
|
||||
{selected, ["grp"], JGrps} when is_list(JGrps) ->
|
||||
@ -443,8 +449,8 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
|
||||
["username", "jid", "nick", "subscription", "ask",
|
||||
"askmessage", "server", "subscribe", "type"],
|
||||
[]} ->
|
||||
#roster{usj = {LUser, LServer, LJID},
|
||||
us = {LUser, LServer},
|
||||
#roster{usj = {list_to_binary(LUser), list_to_binary(LServer), LJID},
|
||||
us = {list_to_binary(LUser), list_to_binary(LServer)},
|
||||
jid = LJID}
|
||||
end,
|
||||
NewState = case Direction of
|
||||
@ -619,7 +625,7 @@ in_auto_reply(both, none, unsubscribe) -> unsubscribed;
|
||||
in_auto_reply(_, _, _) -> none.
|
||||
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
@ -705,10 +711,11 @@ process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
|
||||
process_item_attrs_ws(Item, []) ->
|
||||
Item.
|
||||
|
||||
get_in_pending_subscriptions(Ls, User, Server) ->
|
||||
get_in_pending_subscriptions(Ls, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
JID = exmpp_jid:make_bare_jid(User, Server),
|
||||
LUser = JID#jid.lnode,
|
||||
LServer = JID#jid.ldomain,
|
||||
LUser = exmpp_jid:lnode_as_list(JID),
|
||||
LServer = exmpp_jid:ldomain_as_list(JID),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
case catch odbc_queries:get_roster(LServer, Username) of
|
||||
{selected, ["username", "jid", "nick", "subscription", "ask",
|
||||
@ -726,7 +733,7 @@ get_in_pending_subscriptions(Ls, User, Server) ->
|
||||
end,
|
||||
lists:flatmap(
|
||||
fun(I) ->
|
||||
case raw_to_record(LServer, I) of
|
||||
case raw_to_record(exmpp_jid:ldomain(JID), I) of
|
||||
%% Bad JID in database:
|
||||
error ->
|
||||
[];
|
||||
@ -745,12 +752,12 @@ get_in_pending_subscriptions(Ls, User, Server) ->
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% JID is #jid record, because it's used latter on for both short_prepd_jid
|
||||
%% JID is jid() record, because it's used latter on for both short_prepd_jid
|
||||
%% and short_prepd_bare_jid
|
||||
get_jid_info(_, User, Server, JID) ->
|
||||
get_jid_info(_, User, Server, JID) when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
LJID = {N, D, R} = jlib:short_prepd_jid(JID),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(N, D, R)),
|
||||
@ -805,7 +812,7 @@ get_jid_info(_, User, Server, JID) ->
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage,
|
||||
_SServer, _SSubscribe, _SType}) ->
|
||||
_SServer, _SSubscribe, _SType}) when is_binary(LServer) ->
|
||||
try
|
||||
JID = exmpp_jid:list_to_jid(SJID),
|
||||
LJID = jlib:short_prepd_jid(JID),
|
||||
@ -823,8 +830,9 @@ raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage,
|
||||
"I" -> in;
|
||||
_ -> none
|
||||
end,
|
||||
#roster{usj = {User, LServer, LJID},
|
||||
us = {User, LServer},
|
||||
UserB = list_to_binary(User),
|
||||
#roster{usj = {UserB, LServer, LJID},
|
||||
us = {UserB, LServer},
|
||||
jid = LJID,
|
||||
name = Nick,
|
||||
subscription = Subscription,
|
||||
@ -841,7 +849,7 @@ record_to_string(#roster{us = {User, _Server},
|
||||
subscription = Subscription,
|
||||
ask = Ask,
|
||||
askmessage = AskMessage}) ->
|
||||
Username = ejabberd_odbc:escape(User),
|
||||
Username = ejabberd_odbc:escape(binary_to_list(User)),
|
||||
{U, S, R} = JID,
|
||||
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(U, S, R)),
|
||||
Nick = ejabberd_odbc:escape(Name),
|
||||
|
@ -39,35 +39,37 @@
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
start(Host, _Opts) ->
|
||||
ejabberd_hooks:add(user_send_packet, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:add(user_send_packet, HostB,
|
||||
?MODULE, log_user_send, 50),
|
||||
ejabberd_hooks:add(user_receive_packet, Host,
|
||||
ejabberd_hooks:add(user_receive_packet, HostB,
|
||||
?MODULE, log_user_receive, 50),
|
||||
ok.
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(user_send_packet, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(user_send_packet, HostB,
|
||||
?MODULE, log_user_send, 50),
|
||||
ejabberd_hooks:delete(user_receive_packet, Host,
|
||||
ejabberd_hooks:delete(user_receive_packet, HostB,
|
||||
?MODULE, log_user_receive, 50),
|
||||
ok.
|
||||
|
||||
log_user_send(From, To, Packet) ->
|
||||
log_packet(From, To, Packet, From#jid.ldomain).
|
||||
log_packet(From, To, Packet, exmpp_jid:ldomain_as_list(From)).
|
||||
|
||||
log_user_receive(_JID, From, To, Packet) ->
|
||||
log_packet(From, To, Packet, To#jid.ldomain).
|
||||
log_packet(From, To, Packet, exmpp_jid:ldomain_as_list(To)).
|
||||
|
||||
|
||||
log_packet(From, To, Packet, Host) ->
|
||||
Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []),
|
||||
ServerJID = #jid{domain = Host, ldomain = Host},
|
||||
ServerJID = exmpp_jid:make_bare_jid(Host),
|
||||
FixedPacket = exmpp_stanza:set_jids(Packet, From, To),
|
||||
lists:foreach(
|
||||
fun(Logger) ->
|
||||
ejabberd_router:route(
|
||||
ServerJID,
|
||||
#jid{domain = Logger, ldomain = Logger},
|
||||
exmpp_jid:make_bare_jid(Logger),
|
||||
#xmlel{name = 'route', children = [FixedPacket]})
|
||||
end, Loggers).
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
-record(sr_user, {us, group_host}).
|
||||
|
||||
start(Host, _Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
mnesia:create_table(sr_group,
|
||||
[{disc_copies, [node()]},
|
||||
{attributes, record_info(fields, sr_group)}]),
|
||||
@ -68,47 +69,48 @@ start(Host, _Opts) ->
|
||||
{type, bag},
|
||||
{attributes, record_info(fields, sr_user)}]),
|
||||
mnesia:add_table_index(sr_user, group_host),
|
||||
ejabberd_hooks:add(webadmin_menu_host, Host,
|
||||
ejabberd_hooks:add(webadmin_menu_host, HostB,
|
||||
?MODULE, webadmin_menu, 70),
|
||||
ejabberd_hooks:add(webadmin_page_host, Host,
|
||||
ejabberd_hooks:add(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:add(roster_get, Host,
|
||||
ejabberd_hooks:add(roster_get, HostB,
|
||||
?MODULE, get_user_roster, 70),
|
||||
ejabberd_hooks:add(roster_in_subscription, Host,
|
||||
ejabberd_hooks:add(roster_in_subscription, HostB,
|
||||
?MODULE, in_subscription, 30),
|
||||
ejabberd_hooks:add(roster_out_subscription, Host,
|
||||
ejabberd_hooks:add(roster_out_subscription, HostB,
|
||||
?MODULE, out_subscription, 30),
|
||||
ejabberd_hooks:add(roster_get_subscription_lists, Host,
|
||||
ejabberd_hooks:add(roster_get_subscription_lists, HostB,
|
||||
?MODULE, get_subscription_lists, 70),
|
||||
ejabberd_hooks:add(roster_get_jid_info, Host,
|
||||
ejabberd_hooks:add(roster_get_jid_info, HostB,
|
||||
?MODULE, get_jid_info, 70),
|
||||
ejabberd_hooks:add(roster_process_item, Host,
|
||||
ejabberd_hooks:add(roster_process_item, HostB,
|
||||
?MODULE, process_item, 50),
|
||||
ejabberd_hooks:add(user_registered, Host,
|
||||
ejabberd_hooks:add(user_registered, HostB,
|
||||
?MODULE, user_registered, 50).
|
||||
%%ejabberd_hooks:add(remove_user, Host,
|
||||
%%ejabberd_hooks:add(remove_user, HostB,
|
||||
%% ?MODULE, remove_user, 50),
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(webadmin_menu_host, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(webadmin_menu_host, HostB,
|
||||
?MODULE, webadmin_menu, 70),
|
||||
ejabberd_hooks:delete(webadmin_page_host, Host,
|
||||
ejabberd_hooks:delete(webadmin_page_host, HostB,
|
||||
?MODULE, webadmin_page, 50),
|
||||
ejabberd_hooks:delete(roster_get, Host,
|
||||
ejabberd_hooks:delete(roster_get, HostB,
|
||||
?MODULE, get_user_roster, 70),
|
||||
ejabberd_hooks:delete(roster_in_subscription, Host,
|
||||
ejabberd_hooks:delete(roster_in_subscription, HostB,
|
||||
?MODULE, in_subscription, 30),
|
||||
ejabberd_hooks:delete(roster_out_subscription, Host,
|
||||
ejabberd_hooks:delete(roster_out_subscription, HostB,
|
||||
?MODULE, out_subscription, 30),
|
||||
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
|
||||
ejabberd_hooks:delete(roster_get_subscription_lists, HostB,
|
||||
?MODULE, get_subscription_lists, 70),
|
||||
ejabberd_hooks:delete(roster_get_jid_info, Host,
|
||||
ejabberd_hooks:delete(roster_get_jid_info, HostB,
|
||||
?MODULE, get_jid_info, 70),
|
||||
ejabberd_hooks:delete(roster_process_item, Host,
|
||||
ejabberd_hooks:delete(roster_process_item, HostB,
|
||||
?MODULE, process_item, 50),
|
||||
ejabberd_hooks:delete(user_registered, Host,
|
||||
ejabberd_hooks:delete(user_registered, HostB,
|
||||
?MODULE, user_registered, 50).
|
||||
%%ejabberd_hooks:delete(remove_user, Host,
|
||||
%%ejabberd_hooks:delete(remove_user, HostB,
|
||||
%% ?MODULE, remove_user, 50),
|
||||
|
||||
|
||||
@ -252,10 +254,11 @@ set_item(User, Server, Resource, Item) ->
|
||||
ResIQ).
|
||||
|
||||
|
||||
get_subscription_lists({F, T}, User, Server) ->
|
||||
get_subscription_lists({F, T}, User, Server)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
US = {LUser, LServer},
|
||||
DisplayedGroups = get_user_displayed_groups(US),
|
||||
SRUsers =
|
||||
@ -271,10 +274,11 @@ get_subscription_lists({F, T}, User, Server) ->
|
||||
{[], []}
|
||||
end.
|
||||
|
||||
get_jid_info({Subscription, Groups}, User, Server, JID) ->
|
||||
get_jid_info({Subscription, Groups}, User, Server, JID)
|
||||
when is_binary(User), is_binary(Server) ->
|
||||
try
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
LUser = binary_to_list(User),
|
||||
LServer = binary_to_list(Server),
|
||||
US = {LUser, LServer},
|
||||
{U1, S1, _} = jlib:short_prepd_jid(JID),
|
||||
US1 = {U1, S1},
|
||||
@ -574,7 +578,7 @@ push_item(User, Server, From, Item) ->
|
||||
fun(Resource) ->
|
||||
JID = exmpp_jid:make_jid(User, Server, Resource),
|
||||
ejabberd_router:route(JID, JID, Stanza)
|
||||
end, ejabberd_sm:get_user_resources(User, Server)).
|
||||
end, ejabberd_sm:get_user_resources(list_to_binary(User), list_to_binary(Server))).
|
||||
|
||||
item_to_xml(Item) ->
|
||||
{U, S, R} = Item#roster.jid,
|
||||
@ -807,7 +811,7 @@ shared_roster_group_parse_query(Host, Group, Query) ->
|
||||
_ ->
|
||||
try
|
||||
JID = exmpp_jid:list_to_jid(SJID),
|
||||
[{JID#jid.lnode, JID#jid.ldomain} | USs]
|
||||
[{exmpp_jid:lnode_as_list(JID), exmpp_jid:ldomain_as_list(JID)} | USs]
|
||||
catch
|
||||
_ ->
|
||||
error
|
||||
|
@ -49,7 +49,7 @@ process_local_iq(_From, To, #iq{type = get,
|
||||
Node = string:tokens(exmpp_xml:get_attribute(SubEl, 'node', ""), "/"),
|
||||
Names = get_names(exmpp_xml:get_child_elements(SubEl), []),
|
||||
|
||||
case get_local_stats(To#jid.domain, Node, Names) of
|
||||
case get_local_stats(exmpp_jid:domain_as_list(To), Node, Names) of
|
||||
{result, Res} ->
|
||||
Result = #xmlel{ns = XMLNS, name = 'query', children = Res},
|
||||
exmpp_iq:result(IQ_Rec, Result);
|
||||
@ -130,7 +130,7 @@ get_local_stats(_Server, _, _) ->
|
||||
|
||||
|
||||
get_local_stat(Server, [], Name) when Name == "users/online" ->
|
||||
case catch ejabberd_sm:get_vh_session_list(Server) of
|
||||
case catch ejabberd_sm:get_vh_session_list(list_to_binary(Server)) of
|
||||
{'EXIT', _Reason} ->
|
||||
?STATERR("500", "Internal Server Error");
|
||||
Users ->
|
||||
|
@ -62,6 +62,7 @@
|
||||
-define(PROCNAME, ejabberd_mod_vcard).
|
||||
|
||||
start(Host, Opts) ->
|
||||
HostB = list_to_binary(Host),
|
||||
mnesia:create_table(vcard, [{disc_only_copies, [node()]},
|
||||
{attributes, record_info(fields, vcard)}]),
|
||||
mnesia:create_table(vcard_search,
|
||||
@ -81,14 +82,14 @@ start(Host, Opts) ->
|
||||
mnesia:add_table_index(vcard_search, lorgname),
|
||||
mnesia:add_table_index(vcard_search, lorgunit),
|
||||
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
|
||||
?MODULE, process_local_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
||||
?MODULE, process_sm_iq, IQDisc),
|
||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
|
||||
MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"),
|
||||
Search = gen_mod:get_opt(search, Opts, true),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
@ -122,13 +123,14 @@ loop(Host, ServerHost) ->
|
||||
end.
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
||||
?NS_VCARD),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||
?NS_VCARD),
|
||||
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
Proc ! stop,
|
||||
{wait, Proc}.
|
||||
@ -167,7 +169,8 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
|
||||
|
||||
|
||||
process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = To,
|
||||
LUser = exmpp_jid:lnode_as_list(To),
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
US = {LUser, LServer},
|
||||
F = fun() ->
|
||||
mnesia:read({vcard, US})
|
||||
@ -187,7 +190,8 @@ process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
|
||||
exmpp_iq:result(IQ_Rec)
|
||||
end;
|
||||
process_sm_iq(From, _To, #iq{type = set, payload = Request} = IQ_Rec) ->
|
||||
#jid{node = User, ldomain = LServer} = From,
|
||||
User = exmpp_jid:node_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
true ->
|
||||
set_vcard(User, LServer, Request),
|
||||
@ -307,7 +311,8 @@ set_vcard(User, LServer, VCARD) ->
|
||||
|
||||
|
||||
do_route(ServerHost, From, To, Packet) ->
|
||||
#jid{node = User, resource = Resource} = To,
|
||||
User = exmpp_jid:node(To),
|
||||
Resource = exmpp_jid:resource(To),
|
||||
if
|
||||
(User /= undefined) or (Resource /= undefined) ->
|
||||
Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),
|
||||
@ -651,7 +656,7 @@ reindex_vcards() ->
|
||||
mnesia:transaction(F).
|
||||
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
US = {LUser, LServer},
|
||||
|
@ -155,7 +155,7 @@ terminate(_Reason, State) ->
|
||||
Host = State#state.serverhost,
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
|
||||
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:delete(disco_sm_features, list_to_binary(Host), ?MODULE, get_sm_features, 50),
|
||||
case State#state.search of
|
||||
true ->
|
||||
ejabberd_router:unregister_route(State#state.myhost);
|
||||
@ -174,7 +174,8 @@ init([Host, Opts]) ->
|
||||
?MODULE, process_local_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
||||
?MODULE, process_sm_iq, IQDisc),
|
||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:add(disco_sm_features,
|
||||
list_to_binary(Host), ?MODULE, get_sm_features, 50),
|
||||
eldap_pool:start_link(State#state.eldap_id,
|
||||
State#state.servers,
|
||||
State#state.backups,
|
||||
@ -234,7 +235,8 @@ process_local_iq(_From, _To, #iq{type = get, lang = Lang} = IQ_Rec) ->
|
||||
process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
|
||||
exmpp_iq:error(IQ_Rec, 'not-allowed').
|
||||
|
||||
process_sm_iq(_From, #jid{ldomain=LServer} = To, #iq{} = IQ_Rec) ->
|
||||
process_sm_iq(_From, To, #iq{} = IQ_Rec) ->
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
case catch process_vcard_ldap(To, IQ_Rec, LServer) of
|
||||
{'EXIT', _} ->
|
||||
exmpp_iq:error(IQ_Rec, 'internal-server-error');
|
||||
@ -248,7 +250,7 @@ process_vcard_ldap(To, IQ_Rec, Server) ->
|
||||
set ->
|
||||
exmpp_iq:error(IQ_Rec, 'not-allowed');
|
||||
get ->
|
||||
#jid{lnode = LUser} = To,
|
||||
LUser = exmpp_jid:lnode_as_list(To),
|
||||
LServer = State#state.serverhost,
|
||||
case ejabberd_auth:is_user_exists(LUser, LServer) of
|
||||
true ->
|
||||
@ -402,7 +404,8 @@ do_route(State, From, To, Packet) ->
|
||||
spawn(?MODULE, route, [State, From, To, Packet]).
|
||||
|
||||
route(State, From, To, Packet) ->
|
||||
#jid{node = User, resource = Resource} = To,
|
||||
User = exmpp_jid:node(To),
|
||||
Resource = exmpp_jid:resource(To),
|
||||
if
|
||||
(User /= undefined) or (Resource /= undefined) ->
|
||||
Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),
|
||||
|
@ -45,14 +45,15 @@
|
||||
-define(PROCNAME, ejabberd_mod_vcard).
|
||||
|
||||
start(Host, Opts) ->
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:add(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
|
||||
?MODULE, process_local_iq, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
|
||||
?MODULE, process_sm_iq, IQDisc),
|
||||
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
|
||||
MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"),
|
||||
Search = gen_mod:get_opt(search, Opts, true),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
@ -86,11 +87,12 @@ loop(Host, ServerHost) ->
|
||||
end.
|
||||
|
||||
stop(Host) ->
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
HostB = list_to_binary(Host),
|
||||
ejabberd_hooks:delete(remove_user, HostB,
|
||||
?MODULE, remove_user, 50),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
|
||||
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
||||
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
Proc ! stop,
|
||||
{wait, Proc}.
|
||||
@ -129,12 +131,14 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
|
||||
|
||||
|
||||
process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
|
||||
#jid{lnode = LUser, ldomain = LServer} = To,
|
||||
LUser = exmpp_jid:lnode_as_list(To),
|
||||
LServer = exmpp_jid:ldomain_as_list(To),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
case catch odbc_queries:get_vcard(LServer, Username) of
|
||||
{selected, ["vcard"], [{SVCARD}]} ->
|
||||
try exmpp_xml:parse_document(SVCARD,
|
||||
[names_as_atom]) of
|
||||
[names_as_atom, {check_elems, xmpp},
|
||||
{check_nss,xmpp}, {check_attrs,xmpp}]) of
|
||||
[VCARD] ->
|
||||
exmpp_iq:result(IQ_Rec, VCARD)
|
||||
catch
|
||||
@ -148,7 +152,8 @@ process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
|
||||
exmpp_iq:error(IQ_Rec, 'internal-server-error')
|
||||
end;
|
||||
process_sm_iq(From, _To, #iq{type = set, payload = Request} = IQ_Rec) ->
|
||||
#jid{node = User, ldomain = LServer} = From,
|
||||
User = exmpp_jid:node_as_list(From),
|
||||
LServer = exmpp_jid:ldomain_as_list(From),
|
||||
case lists:member(LServer, ?MYHOSTS) of
|
||||
true ->
|
||||
set_vcard(User, LServer, Request),
|
||||
@ -277,7 +282,8 @@ set_vcard(User, LServer, VCARD) ->
|
||||
]}]).
|
||||
|
||||
do_route(ServerHost, From, To, Packet) ->
|
||||
#jid{node = User, resource = Resource} = To,
|
||||
User = exmpp_jid:node(To),
|
||||
Resource = exmpp_jid:resource(To),
|
||||
if
|
||||
(User /= undefined) or (Resource /= undefined) ->
|
||||
Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),
|
||||
@ -615,7 +621,7 @@ make_val(Match, Field, Val) ->
|
||||
% mnesia:transaction(F).
|
||||
|
||||
|
||||
remove_user(User, Server) ->
|
||||
remove_user(User, Server) when is_binary(User), is_binary(server) ->
|
||||
LUser = exmpp_stringprep:nodeprep(User),
|
||||
LServer = exmpp_stringprep:nameprep(Server),
|
||||
Username = ejabberd_odbc:escape(LUser),
|
||||
|
@ -53,7 +53,7 @@ process_local_iq(_From, To, #iq{type = Type} = IQ_Rec) ->
|
||||
set ->
|
||||
exmpp_iq:error(IQ_Rec, 'not-allowed');
|
||||
get ->
|
||||
Host = To#jid.domain,
|
||||
Host = exmpp_jid:domain_as_list(To),
|
||||
OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, true) of
|
||||
true -> [get_os()];
|
||||
false -> []
|
||||
|
Loading…
Reference in New Issue
Block a user