1: -module(auth_methods_for_c2s_SUITE).
    2: -compile([export_all, nowarn_export_all]).
    3: 
    4: -include_lib("eunit/include/eunit.hrl").
    5: -include_lib("exml/include/exml.hrl").
    6: 
    7: -import(distributed_helper, [mim/0, rpc/4]).
    8: 
    9: all() ->
   10:     [
   11:      {group, two_methods_enabled},
   12:      {group, metrics}
   13:     ].
   14: 
   15: groups() ->
   16:     [
   17:      {two_methods_enabled, [parallel],
   18:       [
   19:        can_login_with_allowed_method,
   20:        cannot_login_with_not_allowed_method,
   21:        can_login_to_another_listener
   22:       ]},
   23:      {metrics, [],
   24:       [
   25:        metrics_incremented_on_user_connect
   26:       ]}
   27:     ].
   28: 
   29: init_per_suite(Config) ->
   30:     escalus:init_per_suite(Config).
   31: 
   32: end_per_suite(Config) ->
   33:     escalus:end_per_suite(Config).
   34: 
   35: init_per_group(metrics, Config) ->
   36:     set_auth_mod(Config);
   37: init_per_group(_, Config0) ->
   38:     Config1 = ejabberd_node_utils:init(Config0),
   39:     ejabberd_node_utils:backup_config_file(Config1),
   40:     Config2 = modify_config_and_restart(Config1),
   41:     escalus_cleaner:start(Config2).
   42: 
   43: end_per_group(metrics, _Config) ->
   44:     escalus_fresh:clean();
   45: end_per_group(_, Config) ->
   46:     ejabberd_node_utils:restore_config_file(Config),
   47:     ejabberd_node_utils:restart_application(mongooseim),
   48:     escalus_fresh:clean().
   49: 
   50: init_per_testcase(TC, Config) ->
   51:     Spec = escalus_fresh:freshen_spec(Config, alice),
   52:     Clean = register_user(Config, Spec),
   53:     [{clean_fn, Clean}, {spec, Spec}|escalus:init_per_testcase(TC, Config)].
   54: 
   55: end_per_testcase(TC, Config) ->
   56:     Clean = proplists:get_value(clean_fn, Config),
   57:     Clean(),
   58:     escalus:end_per_testcase(TC, Config).
   59: 
   60: set_auth_mod(Config) ->
   61:     Mod = case mongoose_helper:is_rdbms_enabled(domain_helper:host_type()) of
   62:             true ->
   63:                 ejabberd_auth_rdbms;
   64:             false ->
   65:                 ejabberd_auth_internal
   66:         end,
   67:     [{auth_mod, Mod} | Config].
   68: 
   69: modify_config_and_restart(Config) ->
   70:     {Method, Mod} = case mongoose_helper:is_rdbms_enabled(domain_helper:host_type()) of
   71:             true ->
   72:                 {"rdbms", ejabberd_auth_rdbms};
   73:             false ->
   74:                 {"internal", ejabberd_auth_internal}
   75:         end,
   76:     NewConfigValues = [{auth_method, Method ++ "]\n  [auth.dummy"},
   77:                        {auth_method_opts, false},
   78:                        {allowed_auth_methods, "\"" ++ Method ++ "\""}],
   79:     ejabberd_node_utils:modify_config_file(NewConfigValues, Config),
   80:     ejabberd_node_utils:restart_application(mongooseim),
   81:     [{auth_mod, Mod} | Config].
   82: 
   83: can_login_with_allowed_method(Config) ->
   84:     Spec = proplists:get_value(spec, Config),
   85:     {ok, _, _} = escalus_connection:start(Spec).
   86: 
   87: cannot_login_with_not_allowed_method(Config) ->
   88:     Spec = proplists:get_value(spec, Config),
   89:     {error, _} = escalus_connection:start([{password, <<"wrong">>}|Spec]).
   90: 
   91: can_login_to_another_listener(Config) ->
   92:     Spec = proplists:get_value(spec, Config),
   93:     TlsPort = ct:get_config({hosts, mim, c2s_tls_port}),
   94:     Spec2 = [{port, TlsPort}, {ssl, true}, {ssl_opts, [{verify, verify_none}]},
   95:              {password, <<"wrong">>} | Spec],
   96:     {ok, _, _} = escalus_connection:start(Spec2).
   97: 
   98: metrics_incremented_on_user_connect(ConfigIn) ->
   99:     F = fun(Alice, Bob) ->
  100:                 Body = <<"Hello Bob">>,
  101:                 escalus:send(Alice, escalus_stanza:chat_to(Bob, Body)),
  102:                 escalus:assert(is_chat_message, [Body], escalus:wait_for_stanza(Bob))
  103:         end,
  104:     HostType = domain_helper:host_type(),
  105:     HostTypePrefix = domain_helper:make_metrics_prefix(HostType),
  106:     MongooseMetrics = [{[HostTypePrefix, backends, auth, authorize], changed}],
  107:     Config = [{mongoose_metrics, MongooseMetrics} | ConfigIn],
  108:     escalus_fresh:story(Config, [{alice, 1}, {bob, 1}], F).
  109: 
  110: %% Helpers
  111: %% If dummy backend is enabled, it is not possible to create new users
  112: %% (we check if an user does exist before registering the user).
  113: register_user(Config, Spec) ->
  114:     Mod = proplists:get_value(auth_mod, Config),
  115:     #{username := User, server := Server,
  116:       password := Password} = maps:from_list(Spec),
  117:     LUser = jid:nodeprep(User),
  118:     LServer = escalus_utils:jid_to_lower(Server),
  119:     HostType = domain_helper:host_type(),
  120:     ok = rpc(mim(), Mod, try_register,
  121:         [HostType, LUser, LServer, Password]),
  122:     fun() -> rpc(mim(), Mod, remove_user,
  123:                  [HostType, LUser, LServer]) end.