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