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:     C.
   41: 
   42: end_per_suite(_C) ->
   43:     mnesia:stop(),
   44:     mnesia:delete_schema([node()]),
   45:     application:stop(exometer_core),
   46:     ok.
   47: 
   48: init_per_testcase(_, C) ->
   49:     mongooseim_helper:start_link_loaded_hooks(),
   50:     mongoose_config:set_opts(opts()),
   51:     mongoose_modules:start(),
   52:     C.
   53: 
   54: end_per_testcase(_, _) ->
   55:     mongoose_modules:stop(),
   56:     mongoose_config:erase_opts().
   57: 
   58: opts() ->
   59:     #{hosts => [<<"localhost">>],
   60:       host_types => [],
   61:       all_metrics_are_global => false,
   62:       {modules, <<"localhost">>} =>
   63:           #{mod_privacy => config_parser_helper:default_mod_config(mod_privacy)}}.
   64: 
   65: check_with_allowed(_C) ->
   66:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   67:     Acc1 = make_check(Acc, userlist(none), ?BOB, out, allow),
   68:     Acc2 = make_check(Acc1, userlist(none), ?BOB, in, allow),
   69:     Acc3 = make_check(Acc2, userlist(none), ?JEFF, out, allow),
   70:     _Acc4 = make_check(Acc3, userlist(none), ?JEFF, in, allow),
   71:     ok.
   72: 
   73: check_with_denied(_C) ->
   74:     % message
   75:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   76:     Acc1 = make_check(Acc, userlist(deny_all_message), ?BOB, out, allow),
   77:     Acc2 = make_check(Acc1, userlist(deny_all_message), ?BOB, in, deny),
   78:     Acc3 = make_check(Acc2, userlist(deny_all_message), ?JEFF, out, allow),
   79:     _Acc4 = make_check(Acc3, userlist(deny_all_message), ?JEFF, in, deny),
   80:     % presence
   81:     NAcc = mongoose_acc:new(?ACC_PARAMS#{element => presence()}),
   82:     NAcc1 = make_check(NAcc, userlist(deny_all_message), ?BOB, out, allow),
   83:     NAcc2 = make_check(NAcc1, userlist(deny_all_message), ?BOB, in, allow),
   84:     NAcc3 = make_check(NAcc2, userlist(deny_all_message), ?JEFF, out, allow),
   85:     _NAcc4 = make_check(NAcc3, userlist(deny_all_message), ?JEFF, in, allow),
   86:     ok.
   87: 
   88: check_with_denied_bob(_C) ->
   89:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   90:     Acc1 = make_check(Acc, userlist(deny_all_message), ?BOB, out, allow),
   91:     Acc2 = make_check(Acc1, userlist(deny_all_message), ?BOB, in, deny),
   92:     Acc3 = make_check(Acc2, userlist(none), ?JEFF, out, allow),
   93:     _Acc4 = make_check(Acc3, userlist(none), ?JEFF, in, allow),
   94:     ok.
   95: 
   96: check_with_bob_blocked(_C) ->
   97:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => message()}),
   98:     Acc1 = make_check(Acc, userlist(block_bob), ?BOB, out, block),
   99:     Acc2 = make_check(Acc1, userlist(block_bob), ?BOB, in, allow),
  100:     Acc3 = make_check(Acc2, userlist(none), ?JEFF, out, allow),
  101:     _Acc4 = make_check(Acc3, userlist(none), ?JEFF, in, allow),
  102:     % presence
  103:     NAcc = mongoose_acc:new(?ACC_PARAMS#{element => presence()}),
  104:     NAcc1 = make_check(NAcc, userlist(block_bob), ?BOB, out, block),
  105:     NAcc2 = make_check(NAcc1, userlist(block_bob), ?BOB, in, allow),
  106:     NAcc3 = make_check(NAcc2, userlist(block_bob), ?JEFF, out, allow),
  107:     _NAcc4 = make_check(NAcc3, userlist(block_bob), ?JEFF, in, allow),
  108:     ok.
  109: 
  110: check_with_changing_stanza(_C) ->
  111:     % message
  112:     M = message(),
  113:     P = presence(),
  114:     Ul = userlist(deny_all_message),
  115:     Acc = mongoose_acc:new(?ACC_PARAMS#{element => M}),
  116:     Acc1 = make_check({Acc, M}, Ul, ?BOB, out, allow),
  117:     Acc2 = make_check({Acc1, M}, Ul, ?BOB, in, deny),
  118:     Acc3 = make_check({Acc2, M}, Ul, ?JEFF, out, allow),
  119:     Acc4 = make_check({Acc3, M}, Ul, ?JEFF, in, deny),
  120:     % and now we have the same accumulator, but we are checking
  121:     % different stanza (I don't think it ever happens but kzemek
  122:     % justly pointed out that we should provide for it)
  123:     Acc5 = make_check({Acc4, P}, Ul, ?BOB, out, allow),
  124:     Acc6 = make_check({Acc5, P}, Ul, ?BOB, in, allow),
  125:     Acc7 = make_check({Acc6, P}, Ul, ?JEFF, out, allow),
  126:     _Acc8 = make_check({Acc7, P}, Ul, ?JEFF, in, allow).
  127: 
  128: 
  129: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
  130: 
  131: make_check(Acc, PList, To, Dir, Exp) ->
  132:     Server = <<"localhost">>,
  133:     User = <<"alice">>,
  134:     {Res, Acc1} = mongoose_privacy:privacy_check_packet(Acc, jid:make(User, Server, <<>>),
  135:                                                         PList, To, Dir),
  136:     ?assertEqual(Exp, Res),
  137:     Acc1.
  138: 
  139: userlist(deny_all_message) ->
  140:     It = #listitem{action = deny, order = 1, match_message = true},
  141:     #userlist{name= <<"deny_all_message">>, list = [It]};
  142: userlist(block_bob) ->
  143:     It = #listitem{type = jid, value = {<<"bob">>, <<"localhost">>, <<>>},
  144:         action = block, order = 1, match_all = true},
  145:     #userlist{name = <<"block_bob">>, list = [It]};
  146: userlist(_) ->
  147:     #userlist{name = <<"empty">>}.
  148: 
  149: 
  150: presence() ->
  151:     {xmlel, <<"presence">>, [{<<"xml:lang">>, <<"en">>}], []}.
  152: 
  153: message() ->
  154:     {xmlel, <<"message">>,
  155:         [{<<"type">>, <<"chat">>}, {<<"to">>, <<"bob@localhost">>}],
  156:         [{xmlel, <<"body">>, [], [{xmlcdata, <<"roar!">>}]}]}.