1: %%============================================================================== 2: %% Copyright 2010 Erlang Solutions Ltd. 3: %% 4: %% Licensed under the Apache License, Version 2.0 (the "License"); 5: %% you may not use this file except in compliance with the License. 6: %% You may obtain a copy of the License at 7: %% 8: %% http://www.apache.org/licenses/LICENSE-2.0 9: %% 10: %% Unless required by applicable law or agreed to in writing, software 11: %% distributed under the License is distributed on an "AS IS" BASIS, 12: %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13: %% See the License for the specific language governing permissions and 14: %% limitations under the License. 15: %%============================================================================== 16: 17: -module(privacy_SUITE). 18: -compile([export_all, nowarn_export_all]). 19: 20: -include_lib("exml/include/exml.hrl"). 21: -include_lib("escalus/include/escalus.hrl"). 22: -include_lib("common_test/include/ct.hrl"). 23: -include_lib("escalus/include/escalus_xmlns.hrl"). 24: 25: -define(SLEEP_TIME, 50). 26: 27: %%-------------------------------------------------------------------- 28: %% Suite configuration 29: %%-------------------------------------------------------------------- 30: 31: all() -> 32: [ 33: {group, management}, 34: {group, blocking}, 35: {group, allowing} 36: ]. 37: 38: groups() -> 39: [ 40: {management, [parallel], management_test_cases()}, 41: {blocking, [parallel], blocking_test_cases()}, 42: {allowing, [parallel], allowing_test_cases()} 43: ]. 44: 45: management_test_cases() -> 46: [ 47: discover_support, 48: get_all_lists, 49: get_existing_list, 50: get_many_lists, 51: get_nonexistent_list, 52: set_list, 53: activate, 54: activate_nonexistent, 55: deactivate, 56: default, 57: %default_conflict, % fails, as of bug #7073 58: default_nonexistent, 59: no_default, 60: remove_list, 61: get_all_lists_with_active, 62: get_all_lists_with_default 63: ]. 64: 65: blocking_test_cases() -> 66: [ 67: block_jid_message, 68: block_group_message, 69: block_subscription_message, 70: block_all_message, 71: block_jid_presence_in, 72: block_jid_presence_out, 73: block_jid_iq, 74: block_jid_all, 75: block_jid_message_but_not_presence, 76: newly_blocked_presense_jid_by_new_list, 77: newly_blocked_presense_jid_by_list_change, 78: newly_blocked_presence_not_notify_self, 79: iq_reply_doesnt_crash_user_process 80: ]. 81: 82: allowing_test_cases() -> 83: [allow_subscription_to_from_message, 84: allow_subscription_both_message]. 85: 86: suite() -> 87: escalus:suite(). 88: 89: %%-------------------------------------------------------------------- 90: %% Init & teardown 91: %%-------------------------------------------------------------------- 92: 93: init_per_suite(Config0) -> 94: HostType = domain_helper:host_type(), 95: Config1 = dynamic_modules:save_modules(HostType, Config0), 96: Backend = mongoose_helper:get_backend_mnesia_rdbms(HostType), 97: ModConfig = [{mod_privacy, set_opts(Backend)}], 98: dynamic_modules:ensure_modules(HostType, ModConfig), 99: [{escalus_no_stanzas_after_story, true}, 100: {backend, Backend} | 101: escalus:init_per_suite(Config1)]. 102: 103: set_opts(Backend) -> 104: config_parser_helper:mod_config(mod_privacy, #{backend => Backend}). 105: 106: end_per_suite(Config) -> 107: escalus_fresh:clean(), 108: dynamic_modules:restore_modules(Config), 109: escalus:end_per_suite(Config). 110: 111: init_per_group(_GroupName, Config) -> 112: Config. 113: 114: end_per_group(_GroupName, Config) -> 115: Config. 116: 117: init_per_testcase(CaseName, Config) -> 118: escalus:init_per_testcase(CaseName, Config). 119: 120: end_per_testcase(CaseName, Config) -> 121: escalus:end_per_testcase(CaseName, Config). 122: 123: %%-------------------------------------------------------------------- 124: %% Tests 125: %%-------------------------------------------------------------------- 126: 127: %% In terms of server response to blocked communication, we strive to implement the following 128: %% as defined in XEP-0016: 129: %% If someone I block tries to communicate with me, then the following rules apply: 130: %% * For presence stanzas (including notifications, subscriptions, and probes), the server MUST NOT respond and MUST NOT 131: %% return an error. 132: %% * For message stanzas, the server SHOULD return an error, which SHOULD be <service-unavailable/>. 133: %% * For IQ stanzas of type "get" or "set", the server MUST return an error, which SHOULD be <service-unavailable/>. IQ 134: %% stanzas of other types MUST be silently dropped by the server. 135: %% If I want to communicate with someone I block, then: 136: %% * If the user attempts to send an outbound stanza to a contact and that stanza type is blocked, the user's server MUST 137: %% NOT route the stanza to the contact but instead MUST return a <not-acceptable/> error: 138: 139: 140: %% TODO: 141: %% x get all privacy lists 142: %% x get single privacy list 143: %% x that exists 144: %% x that doesn't exist (ensure server returns item-not-found) 145: %% x request more than one at a time (ensure server returns bad-request) 146: %% x set new/edit privacy list (ensure server pushes notifications 147: %% to all resources) 148: %% - remove existing list 149: %% x remove existing list (ensure server push) 150: %% - remove, but check conflict case 151: %% x manage active list(s) 152: %% x activate 153: %% x activate nonexistent (ensure item-not-found) 154: %% x deactivate by sending empty <active /> 155: %% - manage default list 156: %% x set default 157: %% - set default, but check the conflict case, i.e.: 158: %% "Client attempts to change the default list but that list is in use 159: %% by another resource", 160: %% !!! ejabberd doesn't support this, bug filed (#7073) 161: %% x set nonexistent default list 162: %% x use domain's routing, i.e. no default list -> send empty <default /> 163: %% - set no default list, but check conflict case, 164: %% when a resource currently uses the default list 165: %% 166: %% TODO later: 167: %% - big picture: 168: %% - blocking can be done on jids, roster groups, 169: %% subscription type or globally 170: %% - a blocking rule may block one or more of {message, presence-in, 171: %% presence-out, iqs} by specifying these as children to the list item 172: %% or block all of them, when the item has no children 173: %% - blocking: messages, presence (in/out), iqs, all 174: 175: discover_support(Config) -> 176: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 177: Server = escalus_client:server(Alice), 178: IqGet = escalus_stanza:disco_info(Server), 179: Result = escalus:send_iq_and_wait_for_result(Alice, IqGet), 180: escalus:assert(has_feature, [?NS_PRIVACY], Result) 181: end). 182: 183: get_all_lists(Config) -> 184: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 185: 186: escalus:send(Alice, escalus_stanza:privacy_get_all()), 187: escalus:assert(is_privacy_result, escalus:wait_for_stanza(Alice)) 188: 189: end). 190: 191: get_all_lists_with_active(Config) -> 192: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 193: 194: privacy_helper:set_and_activate(Alice, {<<"deny_client">>, Bob}), 195: 196: escalus:send(Alice, escalus_stanza:privacy_get_all()), 197: escalus:assert(is_privacy_result_with_active, [<<"deny_client">>], 198: escalus:wait_for_stanza(Alice)) 199: 200: end). 201: 202: get_all_lists_with_default(Config) -> 203: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 204: 205: privacy_helper:set_list(Alice, {<<"deny_client">>, Bob}), 206: privacy_helper:set_list(Alice, {<<"allow_client">>, Bob}), 207: privacy_helper:set_default_list(Alice, <<"allow_client">>), 208: 209: escalus:send(Alice, escalus_stanza:privacy_get_all()), 210: escalus:assert(is_privacy_result_with_default, 211: escalus:wait_for_stanza(Alice)) 212: 213: end). 214: 215: get_nonexistent_list(Config) -> 216: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 217: 218: escalus_client:send(Alice, 219: escalus_stanza:privacy_get_lists([<<"public">>])), 220: escalus_assert:is_privacy_list_nonexistent_error( 221: escalus_client:wait_for_stanza(Alice)) 222: 223: end). 224: 225: get_many_lists(Config) -> 226: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 227: 228: Request = escalus_stanza:privacy_get_lists([<<"public">>, <<"private">>]), 229: escalus_client:send(Alice, Request), 230: Response = escalus_client:wait_for_stanza(Alice), 231: escalus_assert:is_error(Response, <<"modify">>, <<"bad-request">>) 232: 233: end). 234: 235: get_existing_list(Config) -> 236: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 237: 238: privacy_helper:set_list(Alice, {<<"deny_client">>, Bob}), 239: 240: escalus:send(Alice, escalus_stanza:privacy_get_lists([<<"deny_client">>])), 241: Response = escalus:wait_for_stanza(Alice), 242: 243: <<"deny_client">> = exml_query:path(Response, [{element, <<"query">>}, 244: {element, <<"list">>}, 245: {attr, <<"name">>}]) 246: 247: end). 248: 249: activate(Config) -> 250: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 251: 252: privacy_helper:set_list(Alice, {<<"deny_client">>, Bob}), 253: 254: Request = escalus_stanza:privacy_activate(<<"deny_client">>), 255: escalus_client:send(Alice, Request), 256: 257: Response = escalus_client:wait_for_stanza(Alice), 258: escalus:assert(is_iq_result, Response) 259: 260: end). 261: 262: activate_nonexistent(Config) -> 263: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 264: 265: Request = escalus_stanza:privacy_activate(<<"some_list">>), 266: escalus_client:send(Alice, Request), 267: 268: Response = escalus_client:wait_for_stanza(Alice), 269: escalus:assert(is_error, [<<"cancel">>, <<"item-not-found">>], Response) 270: 271: end). 272: 273: deactivate(Config) -> 274: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 275: 276: Request = escalus_stanza:privacy_deactivate(), 277: escalus_client:send(Alice, Request), 278: 279: Response = escalus_client:wait_for_stanza(Alice), 280: escalus:assert(is_iq_result, Response) 281: 282: end). 283: 284: default(Config) -> 285: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 286: 287: privacy_helper:set_list(Alice, {<<"deny_client">>, Bob}), 288: 289: Request = escalus_stanza:privacy_set_default(<<"deny_client">>), 290: escalus_client:send(Alice, Request), 291: 292: Response = escalus_client:wait_for_stanza(Alice), 293: escalus:assert(is_iq_result, Response) 294: 295: end). 296: 297: default_conflict(Config) -> 298: escalus:fresh_story(Config, [{alice, 2}, {bob, 1}], fun(Alice, Alice2, Bob) -> 299: 300: %% testcase setup 301: %% setup list on server 302: privacy_helper:send_set_list(Alice, {<<"deny_client">>, Bob}), 303: privacy_helper:send_set_list(Alice, {<<"allow_client">>, Bob}), 304: %% skip responses 305: escalus_client:wait_for_stanzas(Alice, 4), 306: %% make a default list for Alice2 307: R1 = escalus_stanza:privacy_set_default(Alice2, <<"deny_client">>), 308: escalus_client:send(Alice2, R1), 309: escalus:assert_many([is_privacy_set, is_privacy_set, is_iq_result], 310: escalus_client:wait_for_stanzas(Alice2, 3)), 311: %% setup done 312: 313: Request = escalus_stanza:privacy_set_default(<<"allow_client">>), 314: escalus_client:send(Alice, Request), 315: 316: Response = escalus_client:wait_for_stanza(Alice), 317: %% TODO: should fail on this (result) and receive error 318: %% this is a bug and was filed to the esl redmine as Bug #7073 319: %true = exmpp_iq:is_result(Response), 320: %% but this should pass just fine 321: escalus:assert(is_error, [<<"cancel">>, <<"conflict">>], Response) 322: 323: end). 324: 325: default_nonexistent(Config) -> 326: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 327: 328: Request = escalus_stanza:privacy_set_default(<<"some_list">>), 329: escalus_client:send(Alice, Request), 330: 331: Response = escalus_client:wait_for_stanza(Alice), 332: escalus_assert:is_error(Response, <<"cancel">>, <<"item-not-found">>) 333: 334: end). 335: 336: no_default(Config) -> 337: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 338: 339: Request = escalus_stanza:privacy_no_default(), 340: escalus_client:send(Alice, Request), 341: 342: Response = escalus_client:wait_for_stanza(Alice), 343: escalus:assert(is_iq_result, Response) 344: 345: end). 346: 347: set_list(Config) -> 348: escalus:fresh_story(Config, [{alice, 3}, {bob, 1}], fun(Alice, Alice2, Alice3, Bob) -> 349: 350: privacy_helper:send_set_list(Alice, {<<"deny_client">>, Bob}), 351: 352: %% Verify that original Alice gets iq result and notification. 353: %% It's a bit quirky as these come in undefined order 354: %% (actually, they always came with 'push' first and then 'result', 355: %% but I suppose it's not mandatory). 356: AliceResponses = escalus_client:wait_for_stanzas(Alice, 2), 357: escalus:assert_many([ 358: fun escalus_pred:is_iq_result/1, 359: fun privacy_helper:is_privacy_list_push/1 360: ], AliceResponses), 361: 362: %% Verify that other resources also get the push. 363: escalus:assert(fun privacy_helper:is_privacy_list_push/1, 364: escalus:wait_for_stanza(Alice2)), 365: escalus:assert(fun privacy_helper:is_privacy_list_push/1, 366: escalus:wait_for_stanza(Alice3)) 367: 368: %% All in all, the spec requires the resources to reply 369: %% (as to every iq), but it's omitted here. 370: 371: end). 372: 373: remove_list(Config) -> 374: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 375: 376: privacy_helper:send_set_list(Alice, {<<"deny_client">>, Bob}), 377: 378: %% These are the pushed notification and iq result. 379: escalus_client:wait_for_stanzas(Alice, 2), 380: 381: %% Request list deletion by sending an empty list. 382: RemoveRequest = escalus_stanza:privacy_set_list( 383: escalus_stanza:privacy_list(<<"someList">>, [])), 384: escalus_client:send(Alice, RemoveRequest), 385: 386: %% These too are the pushed notification and iq result. 387: escalus:assert_many([ 388: fun privacy_helper:is_privacy_list_push/1, 389: is_iq_result 390: ], escalus_client:wait_for_stanzas(Alice, 2)), 391: 392: escalus_client:send(Alice, 393: escalus_stanza:privacy_get_lists([<<"someList">>])), 394: 395: %% Finally ensure that the list doesn't exist anymore. 396: escalus_assert:is_privacy_list_nonexistent_error( 397: escalus_client:wait_for_stanza(Alice)) 398: 399: end). 400: 401: block_jid_message(Config) -> 402: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 403: 404: %% Alice should receive message 405: escalus_client:send(Bob, 406: escalus_stanza:chat_to(Alice, <<"Hi! What's your name?">>)), 407: escalus_assert:is_chat_message(<<"Hi! What's your name?">>, 408: escalus_client:wait_for_stanza(Alice)), 409: 410: %% set the list on server and make it active 411: privacy_helper:set_and_activate(Alice, {<<"deny_client_message">>, Bob}), 412: 413: %% Alice should NOT receive message, while Bob gets error message 414: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi, Alice!">>)), 415: privacy_helper:gets_error(Bob, <<"service-unavailable">>), 416: timer:sleep(?SLEEP_TIME), 417: escalus_assert:has_no_stanzas(Alice), 418: 419: %% Blocking only applies to incoming messages, so Alice can still send 420: %% Bob a message 421: %% and Bob gets nothing 422: escalus_client:send(Alice, escalus_stanza:chat_to( 423: Bob, <<"Hi, Bobbb!">>)), 424: escalus_assert:is_chat_message(<<"Hi, Bobbb!">>, 425: escalus_client:wait_for_stanza(Bob)) 426: 427: end). 428: 429: block_group_message(Config) -> 430: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 431: 432: %% Alice should receive message 433: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi!">>)), 434: escalus_assert:is_chat_message(<<"Hi!">>, 435: escalus_client:wait_for_stanza(Alice)), 436: 437: %% add Bob to Alices' group 'ignored' 438: add_sample_contact(Alice, Bob, [<<"ignored">>], <<"Ugly Bastard">>), 439: 440: %% set the list on server and make it active 441: privacy_helper:set_and_activate(Alice, <<"deny_group_message">>), 442: 443: %% Alice should NOT receive message 444: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi, blocked group!">>)), 445: timer:sleep(?SLEEP_TIME), 446: escalus_assert:has_no_stanzas(Alice), 447: privacy_helper:gets_error(Bob, <<"service-unavailable">>) 448: 449: end). 450: 451: block_subscription_message(Config) -> 452: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 453: 454: %% Alice should receive message 455: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi!">>)), 456: escalus_assert:is_chat_message(<<"Hi!">>, 457: escalus_client:wait_for_stanza(Alice)), 458: 459: %% Alice sends unsubscribe 460: Stanza = escalus_stanza:presence_direct(escalus_utils:get_short_jid(Bob), 461: <<"unsubscribe">>), 462: escalus_client:send(Alice, Stanza), 463: 464: %% set the list on server and make it active 465: privacy_helper:set_and_activate(Alice, <<"deny_unsubscribed_message">>), 466: 467: %% Alice should NOT receive message 468: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi!">>)), 469: timer:sleep(?SLEEP_TIME), 470: escalus_assert:has_no_stanzas(Alice), 471: privacy_helper:gets_error(Bob, <<"service-unavailable">>) 472: 473: end). 474: 475: allow_subscription_to_from_message(Config) -> 476: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 477: %% deny all message but not from subscribed "to" 478: privacy_helper:set_and_activate(Alice, <<"deny_all_message_but_subscription_to">>), 479: 480: %% deny all message but not from subscribed "from" 481: privacy_helper:set_and_activate(Bob, <<"deny_all_message_but_subscription_from">>), 482: 483: %% Bob and Alice cannot sent to each other now 484: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi, Alice XYZ!">>)), 485: escalus_client:send(Alice, escalus_stanza:chat_to(Bob, <<"Hi, Bob XYZ!">>)), 486: 487: ct:sleep(?SLEEP_TIME), 488: %% they received just rejection msgs 489: privacy_helper:gets_error(Alice, <<"service-unavailable">>), 490: escalus_assert:has_no_stanzas(Alice), 491: privacy_helper:gets_error(Bob, <<"service-unavailable">>), 492: escalus_assert:has_no_stanzas(Bob), 493: 494: %% Alice subscribes to Bob 495: subscribe_from_to(Alice, Bob, false), 496: 497: %% Now Alice is subscribed "to" Bob 498: %% And Bob is subscribed "from" Alice 499: 500: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi, Alice XYZ!">>)), 501: escalus_assert:is_chat_message(<<"Hi, Alice XYZ!">>, 502: escalus_client:wait_for_stanza(Alice)), 503: 504: escalus_client:send(Alice, escalus_stanza:chat_to(Bob, <<"Hi, Bob XYZ!">>)), 505: escalus_assert:is_chat_message(<<"Hi, Bob XYZ!">>, 506: escalus_client:wait_for_stanza(Bob)) 507: 508: end). 509: 510: allow_subscription_both_message(Config) -> 511: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 512: 513: %% Alice subscribes to Bob 514: subscribe_from_to(Alice, Bob, false), 515: 516: %% deny all message but not from subscribed "to" 517: privacy_helper:set_and_activate(Alice, <<"deny_all_message_but_subscription_both">>), 518: 519: %% deny all message but not from subscribed "from" 520: privacy_helper:set_and_activate(Bob, <<"deny_all_message_but_subscription_both">>), 521: 522: %% Bob and Alice cannot write to each other now 523: %% Even though they are in subscription "to" and "from" respectively 524: escalus_client:send(Bob, escalus_stanza:chat_to( 525: Alice, <<"Hi, Alice XYZ!">>)), 526: escalus_client:send(Alice, escalus_stanza:chat_to( 527: Bob, <<"Hi, Bob XYZ 1!">>)), 528: 529: privacy_helper:gets_error(Alice, <<"service-unavailable">>), 530: privacy_helper:gets_error(Bob, <<"service-unavailable">>), 531: escalus_assert:has_no_stanzas(Alice), 532: escalus_assert:has_no_stanzas(Bob), 533: 534: %% Bob subscribes to Alice 535: subscribe_from_to(Bob, Alice, true), 536: 537: %% Now their subscription is in state "both" 538: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi, Alice XYZ!">>)), 539: escalus_assert:is_chat_message(<<"Hi, Alice XYZ!">>, 540: escalus_client:wait_for_stanza(Alice)), 541: 542: escalus_client:send(Alice, escalus_stanza:chat_to(Bob, <<"Hi, Bob XYZ! 2">>)), 543: escalus_assert:is_chat_message(<<"Hi, Bob XYZ! 2">>, 544: escalus_client:wait_for_stanza(Bob)) 545: 546: end). 547: 548: block_all_message(Config) -> 549: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 550: 551: %% Alice should receive message 552: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi!">>)), 553: escalus_assert:is_chat_message(<<"Hi!">>, 554: escalus_client:wait_for_stanza(Alice)), 555: 556: %% set the list on server and make it active 557: privacy_helper:set_and_activate(Alice, <<"deny_all_message">>), 558: 559: %% Alice should NOT receive message 560: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi!">>)), 561: timer:sleep(?SLEEP_TIME), 562: escalus_assert:has_no_stanzas(Alice), 563: privacy_helper:gets_error(Bob, <<"service-unavailable">>) 564: 565: end). 566: 567: block_jid_presence_in(Config) -> 568: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 569: 570: %% Alice should receive presence in 571: Presence1 = escalus_stanza:presence_direct(escalus_utils:get_short_jid(Alice), 572: <<"available">>), 573: escalus_client:send(Bob, Presence1), 574: Received = escalus_client:wait_for_stanza(Alice), 575: escalus:assert(is_presence, Received), 576: escalus_assert:is_stanza_from(Bob, Received), 577: 578: privacy_helper:set_and_activate(Alice, {<<"deny_client_presence_in">>, Bob}), 579: 580: %% Alice should NOT receive presence in 581: Presence2 = escalus_stanza:presence_direct(escalus_utils:get_short_jid(Alice), 582: <<"available">>), 583: escalus_client:send(Bob, Presence2), 584: timer:sleep(?SLEEP_TIME), 585: escalus_assert:has_no_stanzas(Alice), 586: %% and Bob should NOT receive any response 587: escalus_assert:has_no_stanzas(Bob) 588: 589: 590: end). 591: 592: block_jid_presence_out(Config) -> 593: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 594: 595: BobBareJID = escalus_utils:get_short_jid(Bob), 596: 597: %% Bob should receive presence in 598: Presence1 = escalus_stanza:presence_direct(BobBareJID, <<"available">>), 599: escalus_client:send(Alice, Presence1), 600: 601: Received = escalus_client:wait_for_stanza(Bob), 602: escalus:assert(is_presence, Received), 603: escalus_assert:is_stanza_from(Alice, Received), 604: 605: privacy_helper:set_and_activate(Alice, {<<"deny_client_presence_out">>, Bob}), 606: 607: %% Bob should NOT receive presence in 608: Presence2 = escalus_stanza:presence_direct(BobBareJID, <<"available">>), 609: escalus_client:send(Alice, Presence2), 610: 611: %% Alice gets an error back from mod_privacy 612: ErrorPresence = escalus_client:wait_for_stanza(Alice), 613: escalus:assert(is_presence_with_type, [<<"error">>], ErrorPresence), 614: 615: timer:sleep(?SLEEP_TIME), 616: escalus_assert:has_no_stanzas(Bob) 617: 618: end). 619: 620: version_iq(Type, From, To) -> 621: Req = escalus_stanza:iq(Type, [escalus_stanza:query_el(<<"jabber:iq:version">>, [])]), 622: Req1 = escalus_stanza:to(Req, To), 623: Req2= escalus_stanza:from(Req1, From), 624: Req2. 625: 626: iq_reply_doesnt_crash_user_process(Config) -> 627: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 628: 629: QueryWithPrivacyNS = escalus_stanza:query_el(?NS_PRIVACY, []), 630: %% Send IQ reply with privacy ns 631: %% Send message to check user process still alive 632: privacy_helper:does_user_process_crash(Alice, 633: Bob, 634: <<"error">>, 635: QueryWithPrivacyNS, 636: <<"Hello, Bob">>), 637: 638: privacy_helper:does_user_process_crash(Bob, 639: Alice, 640: <<"result">>, 641: QueryWithPrivacyNS, 642: <<"Hello, Alice">>) 643: end). 644: 645: block_jid_iq(Config) -> 646: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 647: 648: LServer = escalus_utils:get_server(Bob), 649: privacy_helper:set_list(Alice, {<<"deny_server_iq">>, LServer}), 650: %% activate it 651: Stanza = escalus_stanza:privacy_activate(<<"deny_server_iq">>), 652: escalus_client:send(Alice, Stanza), 653: timer:sleep(500), %% we must let it sink in 654: 655: %% bob queries for version and gets an error, Alice doesn't receive the query 656: escalus_client:send(Bob, version_iq(<<"get">>, Bob, Alice)), 657: timer:sleep(?SLEEP_TIME), 658: escalus_assert:has_no_stanzas(Alice), 659: privacy_helper:gets_error(Bob, <<"service-unavailable">>), 660: %% this stanza does not make much sense, but is routed and rejected correctly 661: escalus_client:send(Bob, version_iq(<<"set">>, Bob, Alice)), 662: timer:sleep(?SLEEP_TIME), 663: escalus_assert:has_no_stanzas(Alice), 664: privacy_helper:gets_error(Bob, <<"service-unavailable">>), 665: %% but another type, like result, is silently dropped 666: escalus_client:send(Bob, version_iq(<<"result">>, Bob, Alice)), 667: timer:sleep(?SLEEP_TIME), 668: escalus_assert:has_no_stanzas(Alice), 669: escalus_assert:has_no_stanzas(Bob) 670: 671: end). 672: 673: block_jid_all(Config) -> 674: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 675: 676: privacy_helper:set_list(Alice, {<<"deny_jid_all">>, Bob}), 677: 678: %% Alice blocks Bob 679: Stanza = escalus_stanza:privacy_activate(<<"deny_jid_all">>), 680: escalus_client:send(Alice, Stanza), 681: 682: %% IQ response is blocked; 683: %% do magic wait for the request to take effect 684: timer:sleep(200), 685: 686: %% From now on nothing whatsoever sent by Bob should reach Alice. 687: 688: %% Alice should NOT receive message, Bob receives err msg 689: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi!">>)), 690: privacy_helper:gets_error(Bob, <<"service-unavailable">>), 691: 692: %% Alice should NOT receive presence-in from Bob, no err msg 693: AliceBareJID = escalus_utils:get_short_jid(Alice), 694: Presence1 = escalus_stanza:presence_direct(AliceBareJID, <<"available">>), 695: escalus_client:send(Bob, Presence1), 696: timer:sleep(?SLEEP_TIME), 697: escalus_assert:has_no_stanzas(Bob), 698: 699: %% Bob should NOT receive presence-in from Alice, Alice receives err msg 700: BobBareJID = escalus_utils:get_short_jid(Bob), 701: Presence2 = escalus_stanza:presence_direct(BobBareJID, <<"available">>), 702: escalus_client:send(Alice, Presence2), 703: timer:sleep(?SLEEP_TIME), 704: privacy_helper:gets_error(Alice, <<"not-acceptable">>), 705: 706: %% Just set the toy list and en~sure that only 707: %% the notification push comes back. 708: privacy_helper:send_set_list(Alice, {<<"deny_client">>, Bob}), 709: 710: %% verify 711: timer:sleep(?SLEEP_TIME), 712: %% ...that nothing else reached Bob 713: escalus_assert:has_no_stanzas(Bob), 714: %% ...that Alice got a privacy push 715: Responses = escalus_client:wait_for_stanza(Alice), 716: escalus:assert(fun privacy_helper:is_privacy_list_push/1, Responses), 717: %% and Alice didn't get anything else 718: escalus_assert:has_no_stanzas(Alice) 719: 720: end). 721: 722: block_jid_message_but_not_presence(Config) -> 723: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 724: 725: %% Alice should receive message 726: Msg = escalus_stanza:chat_to(Alice, <<"Hi! What's your name?">>), 727: escalus_client:send(Bob, Msg), 728: escalus_assert:is_chat_message(<<"Hi! What's your name?">>, 729: escalus_client:wait_for_stanza(Alice)), 730: 731: %% set the list on server and make it active 732: privacy_helper:set_and_activate(Alice, {<<"deny_client_message">>, Bob}), 733: 734: %% Alice should NOT receive message 735: escalus_client:send(Bob, escalus_stanza:chat_to(Alice, <<"Hi, Alice!">>)), 736: timer:sleep(?SLEEP_TIME), 737: escalus_assert:has_no_stanzas(Alice), 738: privacy_helper:gets_error(Bob, <<"service-unavailable">>), 739: 740: %% ...but should receive presence in 741: escalus_client:send(Bob, 742: escalus_stanza:presence_direct(Alice, <<"available">>)), 743: Received = escalus_client:wait_for_stanza(Alice), 744: escalus:assert(is_presence, Received), 745: escalus_assert:is_stanza_from(Bob, Received) 746: 747: end). 748: 749: newly_blocked_presense_jid_by_new_list(Config) -> 750: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 751: add_sample_contact(Alice, Bob, [<<"My Friends">>], <<"Bobbie">>), 752: subscribe(Bob, Alice), 753: 754: %% Alice gets notification that a roster contact is now subscribed 755: escalus:assert(is_roster_set, escalus_client:wait_for_stanza(Alice)), 756: 757: %% Bob should receive presence in 758: Presence = escalus_stanza:presence_direct(escalus_client:short_jid(Bob), 759: <<"available">>), 760: escalus_client:send(Alice, Presence), 761: Received = escalus_client:wait_for_stanza(Bob), 762: escalus:assert(is_presence, Received), 763: escalus_assert:is_stanza_from(Alice, Received), 764: 765: privacy_helper:set_list( 766: Alice, <<"deny_bob_presence_out">>, 767: [escalus_stanza:privacy_list_jid_item(<<"1">>, <<"deny">>, 768: escalus_client:short_jid(Bob), 769: [<<"presence-out">>])]), 770: privacy_helper:activate_list(Alice, <<"deny_bob_presence_out">>), 771: 772: %% Bob should receive unavailable, per XEP-0016 2.11 773: Received2 = escalus_client:wait_for_stanza(Bob), 774: escalus:assert(is_presence_with_type, [<<"unavailable">>], Received2), 775: escalus_assert:is_stanza_from(Alice, Received2) 776: 777: end). 778: 779: newly_blocked_presense_jid_by_list_change(Config) -> 780: escalus:fresh_story(Config, [{alice, 1}, {bob, 1}], fun(Alice, Bob) -> 781: add_sample_contact(Alice, Bob, [<<"My Friends">>], <<"Bobbie">>), 782: subscribe(Bob, Alice), 783: 784: %% Alice gets notification that a roster contact is now subscribed 785: escalus:assert(is_roster_set, escalus_client:wait_for_stanza(Alice)), 786: 787: %% Alice sets up an initially empty privacy list 788: privacy_helper:set_and_activate(Alice, <<"noop_list">>), 789: 790: %% Bob should receive presence in 791: escalus_client:send(Alice, 792: escalus_stanza:presence_direct(Bob, <<"available">>)), 793: Received = escalus_client:wait_for_stanza(Bob), 794: escalus:assert(is_presence, Received), 795: escalus_assert:is_stanza_from(Alice, Received), 796: 797: %% Alice now adds Bob to her currently active privacy list 798: privacy_helper:set_list( 799: Alice, <<"noop_list">>, 800: [escalus_stanza:privacy_list_jid_item(<<"1">>, <<"deny">>, 801: escalus_client:short_jid(Bob), 802: [<<"presence-out">>])]), 803: 804: %% Bob should receive unavailable, per XEP-0016 2.11 805: Received2 = escalus_client:wait_for_stanza(Bob), 806: escalus:assert(is_presence_with_type, [<<"unavailable">>], Received2), 807: escalus_assert:is_stanza_from(Alice, Received2) 808: 809: end). 810: 811: newly_blocked_presence_not_notify_self(Config) -> 812: escalus:fresh_story(Config, [{alice, 1}], fun(Alice) -> 813: %% Alice sets up an initially empty privacy list 814: privacy_helper:set_and_activate(Alice, 815: <<"deny_not_both_presence_out">>), 816: 817: %% Alice should not receive an 'unavailable' because she's not a 818: %% contact of herself. 819: timer:sleep(?SLEEP_TIME), 820: escalus_assert:has_no_stanzas(Alice) 821: 822: end). 823: 824: %%----------------------------------------------------------------- 825: %% Helpers 826: %%----------------------------------------------------------------- 827: 828: add_sample_contact(Who, Whom, Groups, Nick) -> 829: escalus_client:send(Who, 830: escalus_stanza:roster_add_contact(Whom, 831: Groups, 832: Nick)), 833: Received = escalus_client:wait_for_stanza(Who), 834: escalus_assert:is_roster_set(Received), 835: escalus_client:send(Who, escalus_stanza:iq_result(Received)), 836: escalus:assert(is_iq_result, escalus:wait_for_stanza(Who)). 837: 838: subscribe(Who, Whom) -> 839: % 'Who' sends a subscribe request to 'Whom' 840: escalus:send(Who, escalus_stanza:presence_direct( 841: escalus_client:short_jid(Whom), <<"subscribe">>)), 842: PushReq = escalus:wait_for_stanza(Who), 843: escalus:assert(is_roster_set, PushReq), 844: escalus:send(Who, escalus_stanza:iq_result(PushReq)), 845: 846: %% 'Whom' receives subscription request 847: Received = escalus:wait_for_stanza(Whom), 848: escalus:assert(is_presence_with_type, [<<"subscribe">>], Received), 849: 850: %% 'Whom' adds new contact to their roster 851: escalus:send(Whom, escalus_stanza:roster_add_contact(Who, 852: [<<"enemies">>], 853: <<"Enemy1">>)), 854: PushReq2 = escalus:wait_for_stanza(Whom), 855: escalus:assert(is_roster_set, PushReq2), 856: escalus:send(Whom, escalus_stanza:iq_result(PushReq2)), 857: escalus:assert(is_iq_result, escalus:wait_for_stanza(Whom)), 858: 859: %% 'Whom' sends subscribed presence 860: escalus:send(Whom, escalus_stanza:presence_direct( 861: escalus_client:short_jid(Who), <<"subscribed">>)), 862: 863: %% 'Who' receives subscribed 864: Stanzas = escalus:wait_for_stanzas(Who, 2), 865: 866: check_subscription_stanzas(Stanzas, <<"subscribed">>), 867: escalus:assert(is_presence, escalus:wait_for_stanza(Who)). 868: 869: check_subscription_stanzas(Stanzas, Type) -> 870: IsPresWithType = fun(S) -> 871: escalus_pred:is_presence_with_type(Type, S) 872: end, 873: escalus:assert_many([is_roster_set, IsPresWithType], Stanzas). 874: 875: subscribe_from_to(From, To, IsSecondSubscription) -> 876: %% From subscribes to To 877: ToBareJid = escalus_utils:get_short_jid(To), 878: SubStanza = escalus_stanza:presence_direct(ToBareJid, <<"subscribe">>), 879: escalus_client:send(From, SubStanza), 880: PushReq = escalus_client:wait_for_stanza(From), 881: escalus:assert(is_roster_set, PushReq), 882: Received = escalus_client:wait_for_stanza(To), 883: %% To accepts From 884: FromBareJid = escalus_utils:get_short_jid(From), 885: SubConfirmStanza = escalus_stanza:presence_direct(FromBareJid, <<"subscribed">>), 886: escalus_client:send(To, SubConfirmStanza), 887: case IsSecondSubscription of 888: true -> 889: escalus:assert(is_roster_set, Received), 890: escalus_client:wait_for_stanzas(To, 2); 891: false -> 892: escalus:assert(is_presence_with_type, [<<"subscribe">>], Received), 893: escalus_client:wait_for_stanza(To) 894: end, 895: escalus_client:wait_for_stanzas(From, 3).