mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-28 16:34:13 +01:00
Merge branch 'master' of github.com:processone/ejabberd
This commit is contained in:
commit
945c58d3db
@ -114,10 +114,16 @@ anonymous_user_exist(User, Server) ->
|
|||||||
%% Register connection
|
%% Register connection
|
||||||
-spec register_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
|
-spec register_connection(ejabberd_sm:sid(), jid(), ejabberd_sm:info()) -> ok.
|
||||||
register_connection(_SID,
|
register_connection(_SID,
|
||||||
#jid{luser = LUser, lserver = LServer}, Info) ->
|
#jid{luser = LUser, lserver = LServer, lresource = LResource}, Info) ->
|
||||||
case proplists:get_value(auth_module, Info) of
|
case proplists:get_value(auth_module, Info) of
|
||||||
?MODULE ->
|
?MODULE ->
|
||||||
ejabberd_hooks:run(register_user, LServer, [LUser, LServer]);
|
% Register user only if we are first resource
|
||||||
|
case ejabberd_sm:get_user_resources(LUser, LServer) of
|
||||||
|
[LResource] ->
|
||||||
|
ejabberd_hooks:run(register_user, LServer, [LUser, LServer]);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
@ -128,7 +134,13 @@ unregister_connection(_SID,
|
|||||||
#jid{luser = LUser, lserver = LServer}, Info) ->
|
#jid{luser = LUser, lserver = LServer}, Info) ->
|
||||||
case proplists:get_value(auth_module, Info) of
|
case proplists:get_value(auth_module, Info) of
|
||||||
?MODULE ->
|
?MODULE ->
|
||||||
ejabberd_hooks:run(remove_user, LServer, [LUser, LServer]);
|
% Remove user data only if there is no more resources around
|
||||||
|
case ejabberd_sm:get_user_resources(LUser, LServer) of
|
||||||
|
[] ->
|
||||||
|
ejabberd_hooks:run(remove_user, LServer, [LUser, LServer]);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
@ -250,11 +250,8 @@ reload(Host, NewOpts, OldOpts) ->
|
|||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
depends(_Host, Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
case proplists:get_bool(user_mucsub_from_muc_archive, Opts) of
|
[].
|
||||||
true -> [{mod_muc, hard}, {mod_muc_admin, hard}];
|
|
||||||
false -> []
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec register_iq_handlers(binary()) -> ok.
|
-spec register_iq_handlers(binary()) -> ok.
|
||||||
register_iq_handlers(Host) ->
|
register_iq_handlers(Host) ->
|
||||||
|
@ -758,6 +758,10 @@ get_subscribed_rooms(Host, User) ->
|
|||||||
ServerHost = ejabberd_router:host_of_route(Host),
|
ServerHost = ejabberd_router:host_of_route(Host),
|
||||||
get_subscribed_rooms(ServerHost, Host, User).
|
get_subscribed_rooms(ServerHost, Host, User).
|
||||||
|
|
||||||
|
-record(subscriber, {jid :: jid(),
|
||||||
|
nick = <<>> :: binary(),
|
||||||
|
nodes = [] :: [binary()]}).
|
||||||
|
|
||||||
-spec get_subscribed_rooms(binary(), binary(), jid()) ->
|
-spec get_subscribed_rooms(binary(), binary(), jid()) ->
|
||||||
{ok, [{jid(), [binary()]}]} | {error, any()}.
|
{ok, [{jid(), [binary()]}]} | {error, any()}.
|
||||||
get_subscribed_rooms(ServerHost, Host, From) ->
|
get_subscribed_rooms(ServerHost, Host, From) ->
|
||||||
@ -768,7 +772,15 @@ get_subscribed_rooms(ServerHost, Host, From) ->
|
|||||||
false ->
|
false ->
|
||||||
Rooms = get_online_rooms(ServerHost, Host),
|
Rooms = get_online_rooms(ServerHost, Host),
|
||||||
{ok, lists:flatmap(
|
{ok, lists:flatmap(
|
||||||
fun({Name, _, Pid}) ->
|
fun({Name, _, Pid}) when Pid == self() ->
|
||||||
|
USR = jid:split(BareFrom),
|
||||||
|
case erlang:get(muc_subscribers) of
|
||||||
|
#{USR := #subscriber{nodes = Nodes}} ->
|
||||||
|
[{jid:make(Name, Host), Nodes}];
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end;
|
||||||
|
({Name, _, Pid}) ->
|
||||||
case p1_fsm:sync_send_all_state_event(
|
case p1_fsm:sync_send_all_state_event(
|
||||||
Pid, {is_subscribed, BareFrom}) of
|
Pid, {is_subscribed, BareFrom}) of
|
||||||
{true, Nodes} ->
|
{true, Nodes} ->
|
||||||
|
@ -538,6 +538,7 @@ handle_sync_event({change_config, Config}, _From,
|
|||||||
{reply, {ok, NSD#state.config}, StateName, NSD};
|
{reply, {ok, NSD#state.config}, StateName, NSD};
|
||||||
handle_sync_event({change_state, NewStateData}, _From,
|
handle_sync_event({change_state, NewStateData}, _From,
|
||||||
StateName, _StateData) ->
|
StateName, _StateData) ->
|
||||||
|
erlang:put(muc_subscribers, NewStateData#state.subscribers),
|
||||||
{reply, {ok, NewStateData}, StateName, NewStateData};
|
{reply, {ok, NewStateData}, StateName, NewStateData};
|
||||||
handle_sync_event({process_item_change, Item, UJID}, _From, StateName, StateData) ->
|
handle_sync_event({process_item_change, Item, UJID}, _From, StateName, StateData) ->
|
||||||
case process_item_change(Item, StateData, UJID) of
|
case process_item_change(Item, StateData, UJID) of
|
||||||
@ -4373,6 +4374,7 @@ store_room(StateData) ->
|
|||||||
store_room(StateData, []).
|
store_room(StateData, []).
|
||||||
store_room(StateData, ChangesHints) ->
|
store_room(StateData, ChangesHints) ->
|
||||||
% Let store persistent rooms or on those backends that have get_subscribed_rooms
|
% Let store persistent rooms or on those backends that have get_subscribed_rooms
|
||||||
|
erlang:put(muc_subscribers, StateData#state.subscribers),
|
||||||
ShouldStore = case (StateData#state.config)#config.persistent of
|
ShouldStore = case (StateData#state.config)#config.persistent of
|
||||||
true ->
|
true ->
|
||||||
true;
|
true;
|
||||||
|
@ -195,7 +195,7 @@ store_offline_msg(#offline_msg{us = {User, Server}, packet = Pkt} = Msg) ->
|
|||||||
infinity ->
|
infinity ->
|
||||||
Mod:store_message(Msg);
|
Mod:store_message(Msg);
|
||||||
Limit ->
|
Limit ->
|
||||||
Num = count_offline_messages(User, Server),
|
Num = count_messages_in_db(User, Server),
|
||||||
if Num < Limit ->
|
if Num < Limit ->
|
||||||
Mod:store_message(Msg);
|
Mod:store_message(Msg);
|
||||||
true ->
|
true ->
|
||||||
@ -405,31 +405,38 @@ need_to_store(_LServer, #message{type = error}) -> false;
|
|||||||
need_to_store(LServer, #message{type = Type} = Packet) ->
|
need_to_store(LServer, #message{type = Type} = Packet) ->
|
||||||
case xmpp:has_subtag(Packet, #offline{}) of
|
case xmpp:has_subtag(Packet, #offline{}) of
|
||||||
false ->
|
false ->
|
||||||
case check_store_hint(Packet) of
|
case misc:unwrap_mucsub_message(Packet) of
|
||||||
store ->
|
#message{type = groupchat} = Msg ->
|
||||||
true;
|
need_to_store(LServer, Msg#message{type = chat});
|
||||||
no_store ->
|
#message{} = Msg ->
|
||||||
false;
|
need_to_store(LServer, Msg);
|
||||||
none ->
|
_ ->
|
||||||
Store = case Type of
|
case check_store_hint(Packet) of
|
||||||
groupchat ->
|
store ->
|
||||||
gen_mod:get_module_opt(
|
|
||||||
LServer, ?MODULE, store_groupchat);
|
|
||||||
headline ->
|
|
||||||
false;
|
|
||||||
_ ->
|
|
||||||
true
|
|
||||||
end,
|
|
||||||
case {Store, gen_mod:get_module_opt(
|
|
||||||
LServer, ?MODULE, store_empty_body)} of
|
|
||||||
{false, _} ->
|
|
||||||
false;
|
|
||||||
{_, true} ->
|
|
||||||
true;
|
true;
|
||||||
{_, false} ->
|
no_store ->
|
||||||
Packet#message.body /= [];
|
false;
|
||||||
{_, unless_chat_state} ->
|
none ->
|
||||||
not misc:is_standalone_chat_state(Packet)
|
Store = case Type of
|
||||||
|
groupchat ->
|
||||||
|
gen_mod:get_module_opt(
|
||||||
|
LServer, ?MODULE, store_groupchat);
|
||||||
|
headline ->
|
||||||
|
false;
|
||||||
|
_ ->
|
||||||
|
true
|
||||||
|
end,
|
||||||
|
case {Store, gen_mod:get_module_opt(
|
||||||
|
LServer, ?MODULE, store_empty_body)} of
|
||||||
|
{false, _} ->
|
||||||
|
false;
|
||||||
|
{_, true} ->
|
||||||
|
true;
|
||||||
|
{_, false} ->
|
||||||
|
Packet#message.body /= [];
|
||||||
|
{_, unless_chat_state} ->
|
||||||
|
not misc:is_standalone_chat_state(Packet)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
true ->
|
true ->
|
||||||
@ -1046,10 +1053,14 @@ count_offline_messages(User, Server) ->
|
|||||||
Res = read_db_messages(LUser, LServer),
|
Res = read_db_messages(LUser, LServer),
|
||||||
count_mam_messages(LUser, LServer, Res);
|
count_mam_messages(LUser, LServer, Res);
|
||||||
_ ->
|
_ ->
|
||||||
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
count_messages_in_db(LUser, LServer)
|
||||||
Mod:count_messages(LUser, LServer)
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec count_messages_in_db(binary(), binary()) -> non_neg_integer().
|
||||||
|
count_messages_in_db(LUser, LServer) ->
|
||||||
|
Mod = gen_mod:db_mod(LServer, ?MODULE),
|
||||||
|
Mod:count_messages(LUser, LServer).
|
||||||
|
|
||||||
-spec add_delay_info(message(), binary(),
|
-spec add_delay_info(message(), binary(),
|
||||||
undefined | erlang:timestamp()) -> message().
|
undefined | erlang:timestamp()) -> message().
|
||||||
add_delay_info(Packet, LServer, TS) ->
|
add_delay_info(Packet, LServer, TS) ->
|
||||||
|
@ -100,6 +100,7 @@ request(Server, Method, Path, Params, Mime, Data) ->
|
|||||||
{URI, Hdrs}
|
{URI, Hdrs}
|
||||||
end,
|
end,
|
||||||
Begin = os:timestamp(),
|
Begin = os:timestamp(),
|
||||||
|
ejabberd_hooks:run(backend_api_call, Server, [Server, Method, Path]),
|
||||||
Result = try httpc:request(Method, Req, HttpOpts, [{body_format, binary}]) of
|
Result = try httpc:request(Method, Req, HttpOpts, [{body_format, binary}]) of
|
||||||
{ok, {{_, Code, _}, RetHdrs, Body}} ->
|
{ok, {{_, Code, _}, RetHdrs, Body}} ->
|
||||||
try decode_json(Body) of
|
try decode_json(Body) of
|
||||||
@ -118,7 +119,6 @@ request(Server, Method, Path, Params, Mime, Data) ->
|
|||||||
exit:Reason ->
|
exit:Reason ->
|
||||||
{error, {http_error, {error, Reason}}}
|
{error, {http_error, {error, Reason}}}
|
||||||
end,
|
end,
|
||||||
ejabberd_hooks:run(backend_api_call, Server, [Server, Method, Path]),
|
|
||||||
case Result of
|
case Result of
|
||||||
{error, {http_error, {error, timeout}}} ->
|
{error, {http_error, {error, timeout}}} ->
|
||||||
ejabberd_hooks:run(backend_api_timeout, Server,
|
ejabberd_hooks:run(backend_api_timeout, Server,
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-import(suite, [send/2, disconnect/1, my_jid/1, send_recv/2, recv_message/1,
|
-import(suite, [send/2, disconnect/1, my_jid/1, send_recv/2, recv_message/1,
|
||||||
get_features/1, recv/1, get_event/1, server_jid/1,
|
get_features/1, recv/1, get_event/1, server_jid/1,
|
||||||
wait_for_master/1, wait_for_slave/1]).
|
wait_for_master/1, wait_for_slave/1,
|
||||||
|
connect/1, open_session/1, bind/1, auth/1]).
|
||||||
-include("suite.hrl").
|
-include("suite.hrl").
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
@ -147,7 +148,9 @@ master_slave_cases(DB) ->
|
|||||||
master_slave_test(send_all)] ++
|
master_slave_test(send_all)] ++
|
||||||
case DB of
|
case DB of
|
||||||
riak -> [];
|
riak -> [];
|
||||||
_ -> [master_slave_test(from_mam)]
|
_ -> [
|
||||||
|
master_slave_test(from_mam),
|
||||||
|
master_slave_test(mucsub_mam)]
|
||||||
end
|
end
|
||||||
}.
|
}.
|
||||||
|
|
||||||
@ -194,6 +197,80 @@ from_mam_slave(Config) ->
|
|||||||
C4 = lists:keydelete(mam_enabled, 1, C3),
|
C4 = lists:keydelete(mam_enabled, 1, C3),
|
||||||
mam_tests:clean(C4).
|
mam_tests:clean(C4).
|
||||||
|
|
||||||
|
mucsub_mam_master(Config) ->
|
||||||
|
Room = suite:muc_room_jid(Config),
|
||||||
|
Peer = ?config(peer, Config),
|
||||||
|
wait_for_slave(Config),
|
||||||
|
ct:comment("Joining muc room"),
|
||||||
|
ok = muc_tests:join_new(Config),
|
||||||
|
|
||||||
|
ct:comment("Enabling mam in room"),
|
||||||
|
CfgOpts = muc_tests:get_config(Config),
|
||||||
|
%% Find the MAM field in the config
|
||||||
|
?match(true, proplists:is_defined(mam, CfgOpts)),
|
||||||
|
?match(true, proplists:is_defined(allow_subscription, CfgOpts)),
|
||||||
|
%% Enable MAM
|
||||||
|
[104] = muc_tests:set_config(Config, [{mam, true}, {allow_subscription, true}]),
|
||||||
|
|
||||||
|
ct:comment("Subscribing peer to room"),
|
||||||
|
?send_recv(#iq{to = Room, type = set, sub_els = [
|
||||||
|
#muc_subscribe{jid = Peer, nick = <<"peer">>,
|
||||||
|
events = [?NS_MUCSUB_NODES_MESSAGES]}
|
||||||
|
]}, #iq{type = result}),
|
||||||
|
|
||||||
|
?match(#message{type = groupchat},
|
||||||
|
send_recv(Config, #message{type = groupchat, to = Room, body = xmpp:mk_text(<<"1">>)})),
|
||||||
|
?match(#message{type = groupchat},
|
||||||
|
send_recv(Config, #message{type = groupchat, to = Room, body = xmpp:mk_text(<<"2">>),
|
||||||
|
sub_els = [#hint{type = 'no-store'}]})),
|
||||||
|
?match(#message{type = groupchat},
|
||||||
|
send_recv(Config, #message{type = groupchat, to = Room, body = xmpp:mk_text(<<"3">>)})),
|
||||||
|
|
||||||
|
ct:comment("Cleaning up"),
|
||||||
|
suite:put_event(Config, ready),
|
||||||
|
ready = get_event(Config),
|
||||||
|
muc_tests:leave(Config),
|
||||||
|
mam_tests:clean(clean(disconnect(Config))).
|
||||||
|
|
||||||
|
mucsub_mam_slave(Config) ->
|
||||||
|
Server = ?config(server, Config),
|
||||||
|
gen_mod:update_module_opts(Server, mod_offline, [{use_mam_for_storage, true}]),
|
||||||
|
gen_mod:update_module_opts(Server, mod_mam, [{user_mucsub_from_muc_archive, true}]),
|
||||||
|
|
||||||
|
Room = suite:muc_room_jid(Config),
|
||||||
|
MyJID = my_jid(Config),
|
||||||
|
MyJIDBare = jid:remove_resource(MyJID),
|
||||||
|
ok = mam_tests:set_default(Config, always),
|
||||||
|
#presence{} = send_recv(Config, #presence{}),
|
||||||
|
send(Config, #presence{type = unavailable}),
|
||||||
|
|
||||||
|
wait_for_master(Config),
|
||||||
|
ready = get_event(Config),
|
||||||
|
ct:sleep(100),
|
||||||
|
|
||||||
|
ct:comment("Receiving offline messages"),
|
||||||
|
|
||||||
|
?match(#presence{}, suite:send_recv(Config, #presence{})),
|
||||||
|
|
||||||
|
lists:foreach(
|
||||||
|
fun(N) ->
|
||||||
|
Body = xmpp:mk_text(integer_to_binary(N)),
|
||||||
|
Msg = ?match(#message{from = Room, type = normal} = Msg, recv_message(Config), Msg),
|
||||||
|
PS = ?match(#ps_event{items = #ps_items{node = ?NS_MUCSUB_NODES_MESSAGES, items = [
|
||||||
|
#ps_item{} = PS
|
||||||
|
]}}, xmpp:get_subtag(Msg, #ps_event{}), PS),
|
||||||
|
?match(#message{type = groupchat, body = Body}, xmpp:get_subtag(PS, #message{}))
|
||||||
|
end, [1, 3]),
|
||||||
|
|
||||||
|
% Unsubscribe yourself
|
||||||
|
?send_recv(#iq{to = Room, type = set, sub_els = [
|
||||||
|
#muc_unsubscribe{}
|
||||||
|
]}, #iq{type = result}),
|
||||||
|
suite:put_event(Config, ready),
|
||||||
|
mam_tests:clean(clean(disconnect(Config))),
|
||||||
|
gen_mod:update_module_opts(Server, mod_offline, [{use_mam_for_storage, false}]),
|
||||||
|
gen_mod:update_module_opts(Server, mod_mam, [{user_mucsub_from_muc_archive, false}]).
|
||||||
|
|
||||||
send_all_master(Config) ->
|
send_all_master(Config) ->
|
||||||
wait_for_slave(Config),
|
wait_for_slave(Config),
|
||||||
Peer = ?config(peer, Config),
|
Peer = ?config(peer, Config),
|
||||||
|
Loading…
Reference in New Issue
Block a user