1: %%%-------------------------------------------------------------------
    2: %%% @author bartek
    3: %%% @copyright (C) 2017, <COMPANY>
    4: %%% @doc
    5: %%%
    6: %%% @end
    7: %%% Created : 24. Mar 2017 13:26
    8: %%%-------------------------------------------------------------------
    9: -module(privacy_SUITE).
   10: -author("bartek").
   11: -compile([export_all, nowarn_export_all]).
   12: 
   13: -include_lib("exml/include/exml.hrl").
   14: -include_lib("eunit/include/eunit.hrl").
   15: -include("mod_privacy.hrl").
   16: -include("mongoose.hrl").
   17: -include("jlib.hrl").
   18: 
   19: -define(ALICE, jid:from_binary(<<"alice@localhost">>)).
   20: -define(BOB, jid:from_binary(<<"bob@localhost">>)).
   21: -define(JEFF, jid:from_binary(<<"jeff@localhost">>)).
   22: -define(ACC_PARAMS, #{location => ?LOCATION,
   23:                       lserver => (?ALICE)#jid.lserver,
   24:                       host_type => (?ALICE)#jid.lserver,
   25:                       from_jid => ?ALICE,
   26:                       to_jid => ?BOB}).
   27: 
   28: all() ->
   29:       [ check_with_allowed,
   30:         check_with_denied,
   31:         check_with_denied_bob,
   32:         check_with_bob_blocked,
   33:         check_with_changing_stanza].
   34: 
   35: init_per_suite(C) ->
   36:     {ok, _} = application:ensure_all_started(jid),
   37:     ok = mnesia:create_schema([node()]),
   38:     ok = mnesia:start(),
   39:     {ok, _} = application:ensure_all_started(exometer_core),
   40:     mongoose_config:set_opt(all_metrics_are_global, false),
   41:     C.
   42: 
   43: init_per_testcase(_, C) ->
   44:     gen_hook:start_link(),
   45:     mod_privacy:start(<<"localhost">>, config_parser_helper:default_mod_config(mod_privacy)),
   46:     C.
   47: 
   48: end_per_suite(_C) ->
   49:     mongoose_config:unset_opt(all_metrics_are_global),
   50:     mnesia:stop(),
   51:     mnesia:delete_schema([node()]),
   52:     application:stop(exometer_core),
   53:     ok.
   54: 
   55: check_with_allowed(_C) ->
   56:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   57:     Acc1 = make_check(Acc, userlist(none), ?BOB, out, allow),
   58:     Acc2 = make_check(Acc1, userlist(none), ?BOB, in, allow),
   59:     Acc3 = make_check(Acc2, userlist(none), ?JEFF, out, allow),
   60:     _Acc4 = make_check(Acc3, userlist(none), ?JEFF, in, allow),
   61:     ok.
   62: 
   63: check_with_denied(_C) ->
   64:     % message
   65:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   66:     Acc1 = make_check(Acc, userlist(deny_all_message), ?BOB, out, allow),
   67:     Acc2 = make_check(Acc1, userlist(deny_all_message), ?BOB, in, deny),
   68:     Acc3 = make_check(Acc2, userlist(deny_all_message), ?JEFF, out, allow),
   69:     _Acc4 = make_check(Acc3, userlist(deny_all_message), ?JEFF, in, deny),
   70:     % presence
   71:     NAcc = mongoose_acc:new(?ACC_PARAMS#{element => presence()}),
   72:     NAcc1 = make_check(NAcc, userlist(deny_all_message), ?BOB, out, allow),
   73:     NAcc2 = make_check(NAcc1, userlist(deny_all_message), ?BOB, in, allow),
   74:     NAcc3 = make_check(NAcc2, userlist(deny_all_message), ?JEFF, out, allow),
   75:     _NAcc4 = make_check(NAcc3, userlist(deny_all_message), ?JEFF, in, allow),
   76:     ok.
   77: 
   78: check_with_denied_bob(_C) ->
   79:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   80:     Acc1 = make_check(Acc, userlist(deny_all_message), ?BOB, out, allow),
   81:     Acc2 = make_check(Acc1, userlist(deny_all_message), ?BOB, in, deny),
   82:     Acc3 = make_check(Acc2, userlist(none), ?JEFF, out, allow),
   83:     _Acc4 = make_check(Acc3, userlist(none), ?JEFF, in, allow),
   84:     ok.
   85: 
   86: check_with_bob_blocked(_C) ->
   87:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   88:     Acc1 = make_check(Acc, userlist(block_bob), ?BOB, out, block),
   89:     Acc2 = make_check(Acc1, userlist(block_bob), ?BOB, in, allow),
   90:     Acc3 = make_check(Acc2, userlist(none), ?JEFF, out, allow),
   91:     _Acc4 = make_check(Acc3, userlist(none), ?JEFF, in, allow),
   92:     % presence
   93:     NAcc = mongoose_acc:new(?ACC_PARAMS#{element => presence()}),
   94:     NAcc1 = make_check(NAcc, userlist(block_bob), ?BOB, out, block),
   95:     NAcc2 = make_check(NAcc1, userlist(block_bob), ?BOB, in, allow),
   96:     NAcc3 = make_check(NAcc2, userlist(block_bob), ?JEFF, out, allow),
   97:     _NAcc4 = make_check(NAcc3, userlist(block_bob), ?JEFF, in, allow),
   98:     ok.
   99: 
  100: check_with_changing_stanza(_C) ->
  101:     % message
  102:     M = message(),
  103:     P = presence(),
  104:     Ul = userlist(deny_all_message),
  105:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => M}),
  106:     Acc1 = make_check({Acc, M}, Ul, ?BOB, out, allow),
  107:     Acc2 = make_check({Acc1, M}, Ul, ?BOB, in, deny),
  108:     Acc3 = make_check({Acc2, M}, Ul, ?JEFF, out, allow),
  109:     Acc4 = make_check({Acc3, M}, Ul, ?JEFF, in, deny),
  110:     % and now we have the same accumulator, but we are checking
  111:     % different stanza (I don't think it ever happens but kzemek
  112:     % justly pointed out that we should provide for it)
  113:     Acc5 = make_check({Acc4, P}, Ul, ?BOB, out, allow),
  114:     Acc6 = make_check({Acc5, P}, Ul, ?BOB, in, allow),
  115:     Acc7 = make_check({Acc6, P}, Ul, ?JEFF, out, allow),
  116:     _Acc8 = make_check({Acc7, P}, Ul, ?JEFF, in, allow).
  117: 
  118: 
  119: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
  120: 
  121: make_check(Acc, PList, To, Dir, Exp) ->
  122:     Server = <<"localhost">>,
  123:     User = <<"alice">>,
  124:     {Acc1, Res} = mongoose_privacy:privacy_check_packet(Acc, jid:make(User, Server, <<>>),
  125:                                                         PList, To, Dir),
  126:     ?assertEqual(Exp, Res),
  127:     Acc1.
  128: 
  129: userlist(deny_all_message) ->
  130:     It = #listitem{action = deny, order = 1, match_message = true},
  131:     #userlist{name= <<"deny_all_message">>, list = [It]};
  132: userlist(block_bob) ->
  133:     It = #listitem{type = jid, value = {<<"bob">>, <<"localhost">>, <<>>},
  134:         action = block, order = 1, match_all = true},
  135:     #userlist{name = <<"block_bob">>, list = [It]};
  136: userlist(_) ->
  137:     #userlist{name = <<"empty">>}.
  138: 
  139: 
  140: presence() ->
  141:     {xmlel, <<"presence">>, [{<<"xml:lang">>, <<"en">>}], []}.
  142: 
  143: message() ->
  144:     {xmlel, <<"message">>,
  145:         [{<<"type">>, <<"chat">>}, {<<"to">>, <<"bob@localhost">>}],
  146:         [{xmlel, <<"body">>, [], [{xmlcdata, <<"roar!">>}]}]}.