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