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