1: -module(graphql_token_SUITE).
    2: 
    3: -compile([export_all, nowarn_export_all]).
    4: 
    5: -import(common_helper, [unprep/1]).
    6: -import(distributed_helper, [require_rpc_nodes/1, mim/0]).
    7: -import(graphql_helper, [execute_command/4, execute_user_command/5, user_to_bin/1,
    8:                          get_ok_value/2, get_err_code/1, get_err_msg/1, get_unauthorized/1, get_not_loaded/1]).
    9: 
   10: -include_lib("eunit/include/eunit.hrl").
   11: 
   12: suite() ->
   13:     require_rpc_nodes([mim]) ++ escalus:suite().
   14: 
   15: all() ->
   16:     [{group, user},
   17:      {group, domain_admin},
   18:      {group, admin_http},
   19:      {group, admin_cli}].
   20: 
   21: groups() ->
   22:     [{user, [], user_groups()},
   23:      {domain_admin, domain_admin_tests()},
   24:      {admin_http, [], admin_groups()},
   25:      {admin_cli, [], admin_groups()},
   26:      {user_token_configured, [], user_tests()},
   27:      {user_token_not_configured, [], user_token_not_configured_tests()},
   28:      {admin_token_configured, [], admin_tests()},
   29:      {admin_token_not_configured, [], admin_token_not_configured_tests()}].
   30: 
   31: user_groups() ->
   32:     [{group, user_token_configured},
   33:      {group, user_token_not_configured}].
   34: 
   35: admin_groups() ->
   36:     [{group, admin_token_configured},
   37:      {group, admin_token_not_configured}].
   38: 
   39: user_tests() ->
   40:     [user_request_token_test,
   41:      user_revoke_token_no_token_before_test,
   42:      user_revoke_token_test].
   43: 
   44: user_token_not_configured_tests() ->
   45:     [user_request_token_test_not_configured,
   46:      user_revoke_token_test_not_configured].
   47: 
   48: domain_admin_tests() ->
   49:     [admin_request_token_test,
   50:      admin_request_token_test_unprep,
   51:      domain_admin_request_token_no_permission_test,
   52:      domain_admin_revoke_token_no_permission_test,
   53:      admin_revoke_token_no_token_test,
   54:      admin_revoke_token_test,
   55:      admin_revoke_token_test_unprep].
   56: 
   57: admin_tests() ->
   58:     [admin_request_token_test,
   59:      admin_request_token_test_unprep,
   60:      admin_request_token_no_host_test,
   61:      admin_revoke_token_no_host_test,
   62:      admin_revoke_token_no_token_test,
   63:      admin_revoke_token_test,
   64:      admin_revoke_token_test_unprep].
   65: 
   66: admin_token_not_configured_tests() ->
   67:     [admin_request_token_test_not_configured,
   68:      admin_revoke_token_test_not_configured].
   69: 
   70: init_per_suite(Config0) ->
   71:     case mongoose_helper:is_rdbms_enabled(domain_helper:host_type()) of
   72:         true ->
   73:             HostType = domain_helper:host_type(),
   74:             Config = dynamic_modules:save_modules(HostType, Config0),
   75:             Config1 = escalus:init_per_suite(Config),
   76:             ejabberd_node_utils:init(mim(), Config1);
   77:         false ->
   78:             {skip, "RDBMS not available"}
   79:     end.
   80: 
   81: end_per_suite(Config) ->
   82:     dynamic_modules:restore_modules(Config),
   83:     escalus:end_per_suite(Config).
   84: 
   85: required_modules() ->
   86:     KeyOpts = #{keys => #{token_secret => ram,
   87:                           provision_pre_shared => ram},
   88:                 backend => ct_helper:get_internal_database()},
   89:     KeyStoreOpts = config_parser_helper:mod_config(mod_keystore, KeyOpts),
   90:     [{mod_keystore, KeyStoreOpts},
   91:      {mod_auth_token, auth_token_opts()}].
   92: 
   93: auth_token_opts() ->
   94:     Defaults = config_parser_helper:default_mod_config(mod_auth_token),
   95:     Defaults#{validity_period => #{access => #{value => 60, unit => minutes},
   96:                                    refresh => #{value => 1, unit => days}}}.
   97: 
   98: init_per_group(admin_http, Config) ->
   99:     graphql_helper:init_admin_handler(Config);
  100: init_per_group(admin_cli, Config) ->
  101:     graphql_helper:init_admin_cli(Config);
  102: init_per_group(domain_admin, Config) ->
  103:     Config1 = ensure_token_started(Config),
  104:     graphql_helper:init_domain_admin_handler(Config1);
  105: init_per_group(Group, Config) when Group =:= admin_token_configured;
  106:                                    Group =:= user_token_configured ->
  107:     ensure_token_started(Config);
  108: init_per_group(Group, Config) when Group =:= admin_token_not_configured;
  109:                                    Group =:= user_token_not_configured ->
  110:     ensure_token_stopped(Config);
  111: init_per_group(user, Config) ->
  112:     graphql_helper:init_user(Config).
  113: 
  114: ensure_token_started(Config) ->
  115:     HostType = domain_helper:host_type(),
  116:     dynamic_modules:ensure_modules(HostType, required_modules()),
  117:     Config.
  118: 
  119: ensure_token_stopped(Config) ->
  120:     HostType = domain_helper:host_type(),
  121:     dynamic_modules:ensure_modules(HostType, [{mod_auth_token, stopped}]),
  122:     Config.
  123: 
  124: end_per_group(GroupName, _Config) when GroupName =:= admin_http;
  125:                                        GroupName =:= admin_cli;
  126:                                        GroupName =:= user;
  127:                                        GroupName =:= domain_admin ->
  128:     graphql_helper:clean();
  129: end_per_group(_GroupName, _Config) ->
  130:     escalus_fresh:clean().
  131: 
  132: init_per_testcase(CaseName, Config) ->
  133:     escalus:init_per_testcase(CaseName, Config).
  134: 
  135: end_per_testcase(CaseName, Config) ->
  136:     escalus:end_per_testcase(CaseName, Config).
  137: 
  138: % User tests
  139: 
  140: user_request_token_test(Config) ->
  141:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_request_token_test/2).
  142: 
  143: user_request_token_test(Config, Alice) ->
  144:     Res = user_request_token(Alice, Config),
  145:     #{<<"refresh">> := Refresh, <<"access">> := Access} =
  146:         get_ok_value([data, token, requestToken], Res),
  147:     ?assert(is_binary(Refresh)),
  148:     ?assert(is_binary(Access)).
  149: 
  150: user_revoke_token_no_token_before_test(Config) ->
  151:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_revoke_token_no_token_before_test/2).
  152: 
  153: user_revoke_token_no_token_before_test(Config, Alice) ->
  154:     Res = user_revoke_token(Alice, Config),
  155:     ?assertEqual(<<"not_found">>, get_err_code(Res)).
  156: 
  157: user_revoke_token_test(Config) ->
  158:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun user_revoke_token_test/2).
  159: 
  160: user_revoke_token_test(Config, Alice) ->
  161:     user_request_token(Alice, Config),
  162:     Res2 = user_revoke_token(Alice, Config),
  163:     ParsedRes = get_ok_value([data, token, revokeToken], Res2),
  164:     ?assertEqual(<<"Revoked">>, ParsedRes).
  165: 
  166: % User test cases mod_token not configured
  167: 
  168: user_request_token_test_not_configured(Config) ->
  169:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  170:         fun user_request_token_test_not_configured/2).
  171: 
  172: user_request_token_test_not_configured(Config, Alice) ->
  173:     Res = user_request_token(Alice, Config),
  174:     get_not_loaded(Res).
  175: 
  176: user_revoke_token_test_not_configured(Config) ->
  177:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  178:         fun user_revoke_token_test_not_configured/2).
  179: 
  180: user_revoke_token_test_not_configured(Config, Alice) ->
  181:     Res = user_revoke_token(Alice, Config),
  182:     get_not_loaded(Res).
  183: 
  184: % Domain admin tests
  185: 
  186: domain_admin_request_token_no_permission_test(Config) ->
  187:     escalus:fresh_story_with_config(Config, [{alice_bis, 1}],
  188:                                     fun domain_admin_request_token_no_permission_test/2).
  189: 
  190: domain_admin_request_token_no_permission_test(Config, AliceBis) ->
  191:     % External domain user
  192:     Res = admin_request_token(user_to_bin(AliceBis), Config),
  193:     get_unauthorized(Res),
  194:     % Non-existing domain
  195:     Res2 = admin_request_token(<<"eddie@otherhost">>, Config),
  196:     get_unauthorized(Res2).
  197: 
  198: domain_admin_revoke_token_no_permission_test(Config) ->
  199:     escalus:fresh_story_with_config(Config, [{alice_bis, 1}],
  200:                                     fun domain_admin_revoke_token_no_permission_test/2).
  201: 
  202: domain_admin_revoke_token_no_permission_test(Config, AliceBis) ->
  203:     % External domain user
  204:     Res = admin_revoke_token(user_to_bin(AliceBis), Config),
  205:     get_unauthorized(Res),
  206:     % Non-existing domain
  207:     Res2 = admin_revoke_token(<<"eddie@otherhost">>, Config),
  208:     get_unauthorized(Res2).
  209: 
  210: % Admin tests
  211: 
  212: admin_request_token_test(Config) ->
  213:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_request_token_test/2).
  214: 
  215: admin_request_token_test(Config, Alice) ->
  216:     Res = admin_request_token(user_to_bin(Alice), Config),
  217:     #{<<"refresh">> := Refresh, <<"access">> := Access} =
  218:         get_ok_value([data, token, requestToken], Res),
  219:     ?assert(is_binary(Refresh)),
  220:     ?assert(is_binary(Access)).
  221: 
  222: admin_request_token_test_unprep(Config) ->
  223:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_request_token_test_unprep/2).
  224: 
  225: admin_request_token_test_unprep(Config, Alice) ->
  226:     Res = admin_request_token(unprep(user_to_bin(Alice)), Config),
  227:     #{<<"refresh">> := Refresh, <<"access">> := Access} =
  228:         get_ok_value([data, token, requestToken], Res),
  229:     ?assert(is_binary(Refresh)),
  230:     ?assert(is_binary(Access)).
  231: 
  232: admin_request_token_no_host_test(Config) ->
  233:     Res = admin_request_token(<<"eddie@otherhost">>, Config),
  234:     ?assertEqual(<<"Unknown domain">>, get_err_msg(Res)).
  235: 
  236: admin_revoke_token_no_host_test(Config) ->
  237:     Res = admin_revoke_token(<<"eddie@otherhost">>, Config),
  238:     ?assertEqual(<<"Unknown domain">>, get_err_msg(Res)).
  239: 
  240: admin_revoke_token_no_token_test(Config) ->
  241:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_revoke_token_no_token_test/2).
  242: 
  243: admin_revoke_token_no_token_test(Config, Alice) ->
  244:     Res = admin_revoke_token(user_to_bin(Alice), Config),
  245:     ?assertEqual(<<"not_found">>, get_err_code(Res)).
  246: 
  247: admin_revoke_token_test(Config) ->
  248:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_revoke_token_test/2).
  249: 
  250: admin_revoke_token_test(Config, Alice) ->
  251:     admin_request_token(user_to_bin(Alice), Config),
  252:     Res2 = admin_revoke_token(user_to_bin(Alice), Config),
  253:     ParsedRes = get_ok_value([data, token, revokeToken], Res2),
  254:     ?assertEqual(<<"Revoked">>, ParsedRes).
  255: 
  256: admin_revoke_token_test_unprep(Config) ->
  257:     escalus:fresh_story_with_config(Config, [{alice, 1}], fun admin_revoke_token_test_unprep/2).
  258: 
  259: admin_revoke_token_test_unprep(Config, Alice) ->
  260:     admin_request_token(unprep(user_to_bin(Alice)), Config),
  261:     Res2 = admin_revoke_token(unprep(user_to_bin(Alice)), Config),
  262:     ParsedRes = get_ok_value([data, token, revokeToken], Res2),
  263:     ?assertEqual(<<"Revoked">>, ParsedRes).
  264: 
  265: % Admin test cases token not configured
  266: 
  267: admin_request_token_test_not_configured(Config) ->
  268:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  269:         fun admin_request_token_test_not_configured/2).
  270: 
  271: admin_request_token_test_not_configured(Config, Alice) ->
  272:     Res = admin_request_token(user_to_bin(Alice), Config),
  273:     get_not_loaded(Res).
  274: 
  275: admin_revoke_token_test_not_configured(Config) ->
  276:     escalus:fresh_story_with_config(Config, [{alice, 1}],
  277:         fun admin_revoke_token_test_not_configured/2).
  278: 
  279: admin_revoke_token_test_not_configured(Config, Alice) ->
  280:     Res = admin_request_token(user_to_bin(Alice), Config),
  281:     get_not_loaded(Res).
  282: 
  283: % Commands
  284: 
  285: user_request_token(User, Config) ->
  286:     execute_user_command(<<"token">>, <<"requestToken">>, User, #{}, Config).
  287: 
  288: user_revoke_token(User, Config) ->
  289:     execute_user_command(<<"token">>, <<"revokeToken">>, User, #{}, Config).
  290: 
  291: admin_request_token(User, Config) ->
  292:     execute_command(<<"token">>, <<"requestToken">>, #{user => User}, Config).
  293: 
  294: admin_revoke_token(User, Config) ->
  295:     execute_command(<<"token">>, <<"revokeToken">>, #{user => User}, Config).