emqx/apps/emqx_authn/test/emqx_authn_schema_SUITE.erl

191 lines
4.8 KiB
Erlang

-module(emqx_authn_schema_SUITE).
-compile(export_all).
-compile(nowarn_export_all).
-include_lib("eunit/include/eunit.hrl").
-include("emqx_authn.hrl").
all() ->
emqx_common_test_helpers:all(?MODULE).
init_per_suite(Config) ->
_ = application:load(emqx_conf),
emqx_common_test_helpers:start_apps([emqx_authn]),
Config.
end_per_suite(_) ->
emqx_common_test_helpers:stop_apps([emqx_authn]),
ok.
init_per_testcase(_Case, Config) ->
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
mria:clear_table(emqx_authn_mnesia),
Config.
end_per_testcase(_Case, Config) ->
Config.
-define(CONF(Conf), #{?CONF_NS_BINARY => Conf}).
t_check_schema(_Config) ->
Check = fun(C) -> emqx_config:check_config(emqx_schema, ?CONF(C)) end,
ConfigOk = #{
<<"mechanism">> => <<"password_based">>,
<<"backend">> => <<"built_in_database">>,
<<"user_id_type">> => <<"username">>,
<<"password_hash_algorithm">> => #{
<<"name">> => <<"bcrypt">>,
<<"salt_rounds">> => <<"6">>
}
},
_ = Check(ConfigOk),
ConfigNotOk = #{
<<"mechanism">> => <<"password_based">>,
<<"backend">> => <<"built_in_database">>,
<<"user_id_type">> => <<"username">>,
<<"password_hash_algorithm">> => #{
<<"name">> => <<"md6">>
}
},
?assertThrow(
#{
path := "authentication.1.password_hash_algorithm.name",
matched_type := "authn-builtin_db:authentication/authn-hash:simple",
reason := unable_to_convert_to_enum_symbol
},
Check(ConfigNotOk)
),
ConfigMissingAlgoName = #{
<<"mechanism">> => <<"password_based">>,
<<"backend">> => <<"built_in_database">>,
<<"user_id_type">> => <<"username">>,
<<"password_hash_algorithm">> => #{
<<"foo">> => <<"bar">>
}
},
?assertThrow(
#{
path := "authentication.1.password_hash_algorithm",
reason := "algorithm_name_missing",
matched_type := "authn-builtin_db:authentication"
},
Check(ConfigMissingAlgoName)
).
t_union_member_selector(_) ->
?assertMatch(#{authentication := undefined}, check(undefined)),
C1 = #{<<"backend">> => <<"built_in_database">>},
?assertThrow(
#{
path := "authentication.1",
reason := "missing_mechanism_field"
},
check(C1)
),
C2 = <<"foobar">>,
?assertThrow(
#{
path := "authentication.1",
reason := "not_a_struct",
value := <<"foobar">>
},
check(C2)
),
Base = #{
<<"user_id_type">> => <<"username">>,
<<"password_hash_algorithm">> => #{
<<"name">> => <<"plain">>
}
},
BadBackend = Base#{<<"mechanism">> => <<"password_based">>, <<"backend">> => <<"bar">>},
?assertThrow(
#{
reason := "unknown_backend",
backend := <<"bar">>
},
check(BadBackend)
),
BadMechanism = Base#{<<"mechanism">> => <<"foo">>, <<"backend">> => <<"built_in_database">>},
?assertThrow(
#{
reason := "unsupported_mechanism",
mechanism := <<"foo">>,
backend := <<"built_in_database">>
},
check(BadMechanism)
),
BadCombination = Base#{<<"mechanism">> => <<"scram">>, <<"backend">> => <<"http">>},
?assertThrow(
#{
reason := "unsupported_mechanism",
mechanism := <<"scram">>,
backend := <<"http">>
},
check(BadCombination)
),
ok.
t_http_auth_selector(_) ->
C1 = #{
<<"mechanism">> => <<"password_based">>,
<<"backend">> => <<"http">>
},
?assertThrow(
#{
field_name := method,
expected := "get | post"
},
check(C1)
),
ok.
t_mongo_auth_selector(_) ->
C1 = #{
<<"mechanism">> => <<"password_based">>,
<<"backend">> => <<"mongodb">>
},
?assertThrow(
#{
field_name := mongo_type,
expected := "single | rs | sharded"
},
check(C1)
),
ok.
t_redis_auth_selector(_) ->
C1 = #{
<<"mechanism">> => <<"password_based">>,
<<"backend">> => <<"redis">>
},
?assertThrow(
#{
field_name := redis_type,
expected := "single | cluster | sentinel"
},
check(C1)
),
ok.
t_redis_jwt_selector(_) ->
C1 = #{
<<"mechanism">> => <<"jwt">>
},
?assertThrow(
#{
field_name := use_jwks,
expected := "true | false"
},
check(C1)
),
ok.
check(C) ->
{_Mappings, Checked} = emqx_config:check_config(emqx_schema, ?CONF(C)),
Checked.