Skip to content

Commit

Permalink
Implement remove marker on user leaves room
Browse files Browse the repository at this point in the history
  • Loading branch information
NelsonVides committed Feb 16, 2022
1 parent 7d1fc5d commit 8182a6c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
18 changes: 18 additions & 0 deletions big_tests/tests/smart_markers_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ groups() ->
{muclight, [],
[
marker_is_stored_for_room,
marker_is_removed_when_user_leaves_room,
markers_are_removed_when_room_is_removed
]}
].
Expand Down Expand Up @@ -107,6 +108,23 @@ marker_is_stored_for_room(Config) ->
fun() -> length(fetch_markers_for_users(BobJid, jid:from_binary(RoomBinJid))) > 0 end, true)
end).

marker_is_removed_when_user_leaves_room(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}],
fun(Alice, Bob) ->
Users = [Alice, Bob],
RoomId = create_room(Alice, [Bob], Config),
RoomBinJid = muc_light_helper:room_bin_jid(RoomId),
RoomJid = jid:from_binary(RoomBinJid),
one_marker_in_room(Users, RoomBinJid, Alice, Bob),
BobJid = jid:from_binary(escalus_client:full_jid(Bob)),
mongoose_helper:wait_until(
fun() -> length(fetch_markers_for_users(BobJid, RoomJid)) > 0 end, true),
% Remove Bob from the room
muc_light_helper:user_leave(RoomId, Bob, [Alice]),
mongoose_helper:wait_until(
fun() -> length(fetch_markers_for_users(BobJid, RoomJid)) end, 0)
end).

markers_are_removed_when_room_is_removed(Config) ->
escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) ->
Users = [Alice, Bob],
Expand Down
31 changes: 28 additions & 3 deletions src/smart_markers/mod_smart_markers.erl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
-module(mod_smart_markers).

-include("jlib.hrl").
-include("mod_muc_light.hrl").

-xep([{xep, 333}, {version, "0.3"}]).
-behaviour(gen_mod).
Expand All @@ -69,8 +70,10 @@
-export([get_chat_markers/3]).

%% Hook handlers
-export([user_send_packet/4, remove_user/3, remove_domain/3, forget_room/4]).
-ignore_xref([user_send_packet/4, remove_user/3, remove_domain/3, forget_room/4]).
-export([user_send_packet/4, remove_user/3, remove_domain/3,
forget_room/4, room_new_affiliations/4]).
-ignore_xref([user_send_packet/4, remove_user/3, remove_domain/3,
forget_room/4, room_new_affiliations/4]).

%%--------------------------------------------------------------------
%% Type declarations
Expand Down Expand Up @@ -111,7 +114,8 @@ hooks(HostType) ->
[{user_send_packet, HostType, ?MODULE, user_send_packet, 90},
{remove_user, HostType, ?MODULE, remove_user, 60},
{remove_domain, HostType, ?MODULE, remove_domain, 60},
{forget_room, HostType, ?MODULE, forget_room, 85}
{forget_room, HostType, ?MODULE, forget_room, 85},
{room_new_affiliations, HostType, ?MODULE, room_new_affiliations, 60}
].

-spec user_send_packet(mongoose_acc:t(), jid:jid(), jid:jid(), exml:element()) ->
Expand Down Expand Up @@ -143,6 +147,27 @@ forget_room(Acc, HostType, RoomS, RoomU) ->
mod_smart_markers_backend:remove_to(HostType, jid:make_noprep(RoomU, RoomS, <<>>)),
Acc.

%% The new affs can be found in the Acc:element, where we can scan for 'none' ones
-spec room_new_affiliations(mongoose_acc:t(), jid:jid(), mod_muc_light:aff_users(), binary()) ->
mongoose_acc:t().
room_new_affiliations(Acc, RoomJid, _NewAffs, _NewVersion) ->
HostType = mod_muc_light_utils:acc_to_host_type(Acc),
case mongoose_acc:element(Acc) of
undefined -> Acc;
Packet ->
case exml_query:paths(Packet, [{element_with_ns, ?NS_MUC_LIGHT_AFFILIATIONS},
{element_with_attr, <<"affiliation">>, <<"none">>},
cdata]) of
[] -> Acc;
Users ->
[begin
FromJid = jid:to_bare(jid:from_binary(User)),
mod_smart_markers_backend:remove_to_for_user(HostType, FromJid, RoomJid)
end || User <- Users ],
Acc
end
end.

%%--------------------------------------------------------------------
%% Other API
%%--------------------------------------------------------------------
Expand Down
10 changes: 10 additions & 0 deletions src/smart_markers/mod_smart_markers_backend.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
-export([remove_domain/2]).
-export([remove_user/2]).
-export([remove_to/2]).
-export([remove_to_for_user/3]).

%%--------------------------------------------------------------------
%% DB backend behaviour definition
Expand All @@ -34,6 +35,8 @@

-callback remove_to(mongooseim:host_type(), jid:jid()) -> term().

-callback remove_to_for_user(mongooseim:host_type(), From :: jid:jid(), To :: jid:jid()) -> term().

-spec init(mongooseim:host_type(), gen_mod:module_opts()) -> ok.
init(HostType, Opts) ->
FOpts = add_default_backend(Opts),
Expand Down Expand Up @@ -76,6 +79,13 @@ remove_to(HostType, To) ->
Args = [HostType, To],
mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args).

%% @doc remove markers a user sent to a given other
%% Useful for when a user leaves a room, but the room still exists
-spec remove_to_for_user(mongooseim:host_type(), From :: jid:jid(), To :: jid:jid()) -> term().
remove_to_for_user(HostType, From, To) ->
Args = [HostType, From, To],
mongoose_backend:call(HostType, ?MAIN_MODULE, ?FUNCTION_NAME, Args).

add_default_backend(Opts) ->
case lists:keyfind(backend, 2, Opts) of
false -> [{backend, rdbms} | Opts];
Expand Down
10 changes: 9 additions & 1 deletion src/smart_markers/mod_smart_markers_rdbms.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
-include("jlib.hrl").

-export([init/2, update_chat_marker/2, get_chat_markers/4]).
-export([remove_domain/2, remove_user/2, remove_to/2]).
-export([remove_domain/2, remove_user/2, remove_to/2, remove_to_for_user/3]).

%%--------------------------------------------------------------------
%% API
Expand All @@ -33,6 +33,9 @@ init(HostType, _) ->
[lserver, from_luser], <<"DELETE FROM smart_markers WHERE lserver=? AND from_luser=?">>),
mongoose_rdbms:prepare(markers_remove_to, smart_markers,
[to_jid], <<"DELETE FROM smart_markers WHERE to_jid=?">>),
mongoose_rdbms:prepare(markers_remove_to_for_user, smart_markers,
[lserver, from_luser, to_jid],
<<"DELETE FROM smart_markers WHERE lserver=? AND from_luser=? AND to_jid=?">>),
ok.

%%% @doc
Expand Down Expand Up @@ -89,6 +92,11 @@ remove_user(HostType, #jid{luser = LU, lserver = LS}) ->
remove_to(HostType, To) ->
mongoose_rdbms:execute_successfully(HostType, markers_remove_to, [encode_jid(To)]).

-spec remove_to_for_user(mongooseim:host_type(), From :: jid:jid(), To :: jid:jid()) ->
mongoose_rdbms:query_result().
remove_to_for_user(HostType, #jid{luser = LU, lserver = LS}, To) ->
mongoose_rdbms:execute_successfully(HostType, markers_remove_to_for_user, [LS, LU, encode_jid(To)]).

%%--------------------------------------------------------------------
%% local functions
%%--------------------------------------------------------------------
Expand Down

0 comments on commit 8182a6c

Please sign in to comment.