diff --git a/apps/ejabberd/src/mod_blocking.erl b/apps/ejabberd/src/mod_blocking.erl index 29f318c50a5..6a755be3b66 100644 --- a/apps/ejabberd/src/mod_blocking.erl +++ b/apps/ejabberd/src/mod_blocking.erl @@ -89,7 +89,7 @@ process_iq_set(Val, _, _, _) -> %% -spec process_blocking_iq_set(Type :: block | unblock, LUser:: binary(), LServer:: binary(), CurrList :: [listitem()], Users :: [binary()]) -> - {ok, [binary()], [listitem()], block | unblock} + {ok, [binary()], [listitem()], block | unblock | unblock_all} | {error, jlib:xmlel()}. %% fail if current default list could not be retrieved process_blocking_iq_set(_, _, _, {error, _}, _) -> @@ -99,14 +99,14 @@ process_blocking_iq_set(block, _, _, _, []) -> {error, ?ERR_BAD_REQUEST}; process_blocking_iq_set(Type, LUser, LServer, CurrList, Usrs) -> %% check who is being added / removed - {Changed, NewList} = blocking_list_modify(Type, Usrs, CurrList), + {NType, Changed, NewList} = blocking_list_modify(Type, Usrs, CurrList), case ?BACKEND:replace_privacy_list(LUser, LServer, <<"blocking">>, NewList) of {error, E} -> {error, E}; ok -> case ?BACKEND:set_default_list(LUser, LServer, <<"blocking">>) of ok -> - {ok, Changed, NewList, Type}; + {ok, Changed, NewList, NType}; {error, not_found} -> {error, ?ERR_ITEM_NOT_FOUND}; {error, _Reason} -> @@ -125,21 +125,21 @@ complete_iq_set(blocking_command, LUser, LServer, {ok, Changed, List, Type}) -> %% {result, []}. -spec blocking_list_modify(Type :: block | unblock, New :: [binary()], Old :: [listitem()]) -> - {[binary()], [listitem()]}. + {block|unblock|unblock_all, [binary()], [listitem()]}. blocking_list_modify(block, Change, Old) -> N = make_blocking_list(Change), {_, O} = remove_from(Change, Old), %% we treat all items on the "to block" list as changed becase they might have been present on the %% old list with different settings %% and we need to set order numbers, doesn't matter how but it has to be unique - {Change, set_order(N ++ O)}; + {block, Change, set_order(N ++ O)}; blocking_list_modify(unblock, [], Old) -> %% unblock with empty list means unblocking all contacts Rem = [jid:to_binary(J#listitem.value) || J <- Old], - {Rem,[]}; + {unblock_all, Rem,[]}; blocking_list_modify(unblock, Change, Old) -> {Removed, O} = remove_from(Change, Old), - {Removed, O}. + {unblock, Removed, O}. set_order(L) -> set_order(1, [], L). @@ -189,6 +189,9 @@ make_blocking_list_entry(J) -> end. %% @doc send iq confirmation to all of the user's resources +%% if we unblock all contacts then we don't list who's been unblocked +broadcast_blocking_command(LUser, LServer, _Changed, unblock_all) -> + broadcast_blocking_command(LUser, LServer, [], unblock); broadcast_blocking_command(LUser, LServer, Changed, Type) -> case jid:make(LUser, LServer, <<>>) of error -> diff --git a/test/ejabberd_tests/tests/mod_blocking_SUITE.erl b/test/ejabberd_tests/tests/mod_blocking_SUITE.erl index 2417c20eaa8..e2fe33619aa 100644 --- a/test/ejabberd_tests/tests/mod_blocking_SUITE.erl +++ b/test/ejabberd_tests/tests/mod_blocking_SUITE.erl @@ -136,8 +136,6 @@ get_block_list(Config) -> Config, [{alice, 1}], fun(User1) -> Result = get_blocklist(User1), -%% io:format("Received stanza is ~n~p~n",[Result]), -%% ct:pal("RESULT ~p", [Result]), escalus:assert(is_iq_result, Result), escalus:assert(fun is_blocklist_result_empty/1, Result) end). @@ -321,7 +319,6 @@ blocking_and_relogin_many(Config) -> client_gets_blocking_error(User1), message_is_delivered(User1, [User2], <<"House of th rising sun">>), BlockList = get_blocklist(User1), -%% ct:pal("blocklist ~p", [BlockList ]), blocklist_contains_jid(BlockList, User3) end). @@ -381,7 +378,6 @@ notify_blockee(Config) -> %% get_blocklist(User) -> IQGet = get_blocklist_stanza(), -%% ct:pal("SEND ~p", [IQGet]), escalus_client:send(User, IQGet), escalus_client:wait_for_stanza(User). @@ -501,6 +497,11 @@ is_xep191_push(Type, #xmlel{attrs = A, children = [#xmlel{name = Type, {<<"xmlns">>, ?NS_BLOCKING} = lists:keyfind(<<"xmlns">>, 1, Attrs), true. +is_xep191_push(Type, [], #xmlel{children = [#xmlel{name = Type, children = []}]}=Stanza) -> + is_xep191_push(Type, Stanza); +is_xep191_push(Type, [], #xmlel{children = [#xmlel{name = Type, children = Items}]}) -> + ct:pal("JIDs: should be empty contains, ~p", [Items]), + false; is_xep191_push(Type, JIDs, #xmlel{attrs = A, children = [#xmlel{name = Type, attrs = Attrs, children = Items}]}=Stanza) -> true = escalus_pred:is_iq_set(Stanza), @@ -529,10 +530,8 @@ get_blocklist_items(Items) -> user_blocks(Blocker, Blockees) when is_list(Blockees) -> BlockeeJIDs = [ escalus_utils:jid_to_lower(escalus_client:short_jid(B)) || B <- Blockees ], AddStanza = block_users_stanza(BlockeeJIDs), - ct:pal("add stanza ~p", [AddStanza]), escalus_client:send(Blocker, AddStanza), Res = escalus:wait_for_stanzas(Blocker, 2), - ct:pal("Two stanzas: ~p", [Res]), CheckPush = fun(E) -> is_xep191_push(<<"block">>, BlockeeJIDs, E) end, Preds = [is_iq_result, CheckPush], %% why it sends additional presence from alice to alice, I don't know escalus:assert_many(Preds, Res). @@ -556,23 +555,23 @@ user_unblocks(Unblocker, Unblockees) when is_list(Unblockees) -> user_unblocks(Unblocker, Unblockee) -> JID = escalus_utils:jid_to_lower(escalus_client:short_jid(Unblockee)), escalus_client:send(Unblocker, unblock_user_stanza(JID)), - user_gets_remove_result(Unblocker). + user_gets_remove_result(Unblocker, [JID]). blocklist_doesnt_contain_jid(BlockList, Client) -> JID = escalus_utils:jid_to_lower(escalus_client:short_jid(Client)), escalus:assert(is_iq_result, BlockList), ?assertNot(blocklist_result_has(JID, BlockList)). -user_gets_remove_result(Client) -> +user_gets_remove_result(Client, ContactList) -> RemoveResult = escalus:wait_for_stanzas(Client, 2), - CheckPush = fun(E) -> is_xep191_push(<<"unblock">>, E) end, + CheckPush = fun(E) -> is_xep191_push(<<"unblock">>, ContactList, E) end, Preds = [is_iq_result, CheckPush], escalus:assert_many(Preds, RemoveResult). user_unblocks_all(User) -> escalus_client:send(User, unblock_all_stanza()), - user_gets_remove_result(User). + user_gets_remove_result(User, []). message(From, To, MsgTxt) -> escalus_client:send(From, escalus_stanza:chat_to(To, MsgTxt)). @@ -603,7 +602,6 @@ client_has_no_messages(C) -> escalus_assert:has_no_stanzas(C). client_gets_blocking_error(C) -> Stanza = escalus_client:wait_for_stanza(C), - ct:pal("Stanza ~p", [Stanza]), escalus:assert(fun is_xep191_not_available/1, [], Stanza). client_gets_block_iq(C) ->