fix(test): fix test case
This commit is contained in:
parent
e998770f2e
commit
627de1d58c
|
@ -0,0 +1,238 @@
|
|||
%%--------------------------------------------------------------------
|
||||
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||
%%
|
||||
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||
%% you may not use this file except in compliance with the License.
|
||||
%% You may obtain a copy of the License at
|
||||
%%
|
||||
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||
%%
|
||||
%% Unless required by applicable law or agreed to in writing, software
|
||||
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
%% See the License for the specific language governing permissions and
|
||||
%% limitations under the License.
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-module(emqx_authentication_SUITE).
|
||||
|
||||
-behaviour(hocon_schema).
|
||||
-behaviour(emqx_authentication).
|
||||
|
||||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
|
||||
-include_lib("common_test/include/ct.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("typerefl/include/types.hrl").
|
||||
|
||||
-export([ fields/1 ]).
|
||||
|
||||
-export([ refs/0
|
||||
, create/1
|
||||
, update/2
|
||||
, authenticate/2
|
||||
, destroy/1
|
||||
]).
|
||||
|
||||
-define(AUTHN, emqx_authentication).
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% Hocon Schema
|
||||
%%------------------------------------------------------------------------------
|
||||
|
||||
fields(type1) ->
|
||||
[ {mechanism, {enum, ['password-based']}}
|
||||
, {backend, {enum, ['built-in-database']}}
|
||||
, {enable, fun enable/1}
|
||||
];
|
||||
|
||||
fields(type2) ->
|
||||
[ {mechanism, {enum, ['password-based']}}
|
||||
, {backend, {enum, ['mysql']}}
|
||||
, {enable, fun enable/1}
|
||||
].
|
||||
|
||||
enable(type) -> boolean();
|
||||
enable(default) -> true;
|
||||
enable(_) -> undefined.
|
||||
|
||||
%%------------------------------------------------------------------------------
|
||||
%% Callbacks
|
||||
%%------------------------------------------------------------------------------
|
||||
|
||||
refs() ->
|
||||
[ hoconsc:ref(?MODULE, type1)
|
||||
, hoconsc:ref(?MODULE, type2)
|
||||
].
|
||||
|
||||
create(_Config) ->
|
||||
{ok, #{mark => 1}}.
|
||||
|
||||
update(_Config, _State) ->
|
||||
{ok, #{mark => 2}}.
|
||||
|
||||
authenticate(#{username := <<"good">>}, _State) ->
|
||||
{ok, #{superuser => true}};
|
||||
authenticate(#{username := _}, _State) ->
|
||||
{error, bad_username_or_password}.
|
||||
|
||||
destroy(_State) ->
|
||||
ok.
|
||||
|
||||
all() ->
|
||||
emqx_ct:all(?MODULE).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
application:set_env(ekka, strict_mode, true),
|
||||
emqx_ct_helpers:start_apps([]),
|
||||
Config.
|
||||
|
||||
end_per_suite(_) ->
|
||||
emqx_ct_helpers:stop_apps([]),
|
||||
ok.
|
||||
|
||||
t_chain(_) ->
|
||||
% CRUD of authentication chain
|
||||
ChainName = <<"test">>,
|
||||
?assertMatch({ok, []}, ?AUTHN:list_chains()),
|
||||
?assertMatch({ok, #{name := ChainName, authenticators := []}}, ?AUTHN:create_chain(ChainName)),
|
||||
?assertEqual({error, {already_exists, {chain, ChainName}}}, ?AUTHN:create_chain(ChainName)),
|
||||
?assertMatch({ok, #{name := ChainName, authenticators := []}}, ?AUTHN:lookup_chain(ChainName)),
|
||||
?assertMatch({ok, [#{name := ChainName}]}, ?AUTHN:list_chains()),
|
||||
?assertEqual(ok, ?AUTHN:delete_chain(ChainName)),
|
||||
?assertMatch({error, {not_found, {chain, ChainName}}}, ?AUTHN:lookup_chain(ChainName)),
|
||||
ok.
|
||||
|
||||
t_authenticator(_) ->
|
||||
ChainName = <<"test">>,
|
||||
AuthenticatorConfig1 = #{mechanism => 'password-based',
|
||||
backend => 'built-in-database',
|
||||
enable => true},
|
||||
|
||||
% Create an authenticator when the authentication chain does not exist
|
||||
?assertEqual({error, {not_found, {chain, ChainName}}}, ?AUTHN:create_authenticator(ChainName, AuthenticatorConfig1)),
|
||||
?AUTHN:create_chain(ChainName),
|
||||
% Create an authenticator when the provider does not exist
|
||||
?assertEqual({error, no_available_provider}, ?AUTHN:create_authenticator(ChainName, AuthenticatorConfig1)),
|
||||
|
||||
AuthNType1 = {'password-based', 'built-in-database'},
|
||||
?AUTHN:add_provider(AuthNType1, ?MODULE),
|
||||
ID1 = <<"password-based:built-in-database">>,
|
||||
|
||||
% CRUD of authencaticator
|
||||
?assertMatch({ok, #{id := ID1, state := #{mark := 1}}}, ?AUTHN:create_authenticator(ChainName, AuthenticatorConfig1)),
|
||||
?assertMatch({ok, #{id := ID1}}, ?AUTHN:lookup_authenticator(ChainName, ID1)),
|
||||
?assertMatch({ok, [#{id := ID1}]}, ?AUTHN:list_authenticators(ChainName)),
|
||||
?assertEqual({error, {already_exists, {authenticator, ID1}}}, ?AUTHN:create_authenticator(ChainName, AuthenticatorConfig1)),
|
||||
?assertMatch({ok, #{id := ID1, state := #{mark := 2}}}, ?AUTHN:update_authenticator(ChainName, ID1, AuthenticatorConfig1)),
|
||||
?assertEqual(ok, ?AUTHN:delete_authenticator(ChainName, ID1)),
|
||||
?assertEqual({error, {not_found, {authenticator, ID1}}}, ?AUTHN:update_authenticator(ChainName, ID1, AuthenticatorConfig1)),
|
||||
?assertMatch({ok, []}, ?AUTHN:list_authenticators(ChainName)),
|
||||
|
||||
% Multiple authenticators exist at the same time
|
||||
AuthNType2 = {'password-based', mysql},
|
||||
?AUTHN:add_provider(AuthNType2, ?MODULE),
|
||||
ID2 = <<"password-based:mysql">>,
|
||||
AuthenticatorConfig2 = #{mechanism => 'password-based',
|
||||
backend => mysql,
|
||||
enable => true},
|
||||
?assertMatch({ok, #{id := ID1}}, ?AUTHN:create_authenticator(ChainName, AuthenticatorConfig1)),
|
||||
?assertMatch({ok, #{id := ID2}}, ?AUTHN:create_authenticator(ChainName, AuthenticatorConfig2)),
|
||||
|
||||
% Move authenticator
|
||||
?assertMatch({ok, [#{id := ID1}, #{id := ID2}]}, ?AUTHN:list_authenticators(ChainName)),
|
||||
?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, top)),
|
||||
?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(ChainName)),
|
||||
?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, bottom)),
|
||||
?assertMatch({ok, [#{id := ID1}, #{id := ID2}]}, ?AUTHN:list_authenticators(ChainName)),
|
||||
?assertEqual(ok, ?AUTHN:move_authenticator(ChainName, ID2, {before, ID1})),
|
||||
?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(ChainName)),
|
||||
|
||||
?AUTHN:delete_chain(ChainName),
|
||||
?AUTHN:remove_provider(AuthNType1),
|
||||
?AUTHN:remove_provider(AuthNType2),
|
||||
ok.
|
||||
|
||||
t_authenticate(_) ->
|
||||
ListenerID = <<"tcp:default">>,
|
||||
ClientInfo = #{zone => default,
|
||||
listener => ListenerID,
|
||||
protocol => mqtt,
|
||||
username => <<"good">>,
|
||||
password => <<"any">>},
|
||||
?assertEqual({ok, #{superuser => false}}, emqx_access_control:authenticate(ClientInfo)),
|
||||
|
||||
AuthNType = {'password-based', 'built-in-database'},
|
||||
?AUTHN:add_provider(AuthNType, ?MODULE),
|
||||
|
||||
AuthenticatorConfig = #{mechanism => 'password-based',
|
||||
backend => 'built-in-database',
|
||||
enable => true},
|
||||
?AUTHN:create_chain(ListenerID),
|
||||
?assertMatch({ok, _}, ?AUTHN:create_authenticator(ListenerID, AuthenticatorConfig)),
|
||||
?assertEqual({ok, #{superuser => true}}, emqx_access_control:authenticate(ClientInfo)),
|
||||
?assertEqual({error, bad_username_or_password}, emqx_access_control:authenticate(ClientInfo#{username => <<"bad">>})),
|
||||
|
||||
?AUTHN:delete_chain(ListenerID),
|
||||
?AUTHN:remove_provider(AuthNType),
|
||||
ok.
|
||||
|
||||
t_update_config(_) ->
|
||||
emqx_config_handler:add_handler([authentication], emqx_authentication),
|
||||
|
||||
AuthNType1 = {'password-based', 'built-in-database'},
|
||||
AuthNType2 = {'password-based', mysql},
|
||||
?AUTHN:add_provider(AuthNType1, ?MODULE),
|
||||
?AUTHN:add_provider(AuthNType2, ?MODULE),
|
||||
|
||||
Global = <<"mqtt:global">>,
|
||||
AuthenticatorConfig1 = #{mechanism => 'password-based',
|
||||
backend => 'built-in-database',
|
||||
enable => true},
|
||||
AuthenticatorConfig2 = #{mechanism => 'password-based',
|
||||
backend => mysql,
|
||||
enable => true},
|
||||
ID1 = <<"password-based:built-in-database">>,
|
||||
ID2 = <<"password-based:mysql">>,
|
||||
|
||||
?assertMatch({ok, []}, ?AUTHN:list_chains()),
|
||||
?assertMatch({ok, _}, update_config([authentication], {create_authenticator, Global, AuthenticatorConfig1})),
|
||||
?assertMatch({ok, #{id := ID1, state := #{mark := 1}}}, ?AUTHN:lookup_authenticator(Global, ID1)),
|
||||
|
||||
?assertMatch({ok, _}, update_config([authentication], {create_authenticator, Global, AuthenticatorConfig2})),
|
||||
?assertMatch({ok, #{id := ID2, state := #{mark := 1}}}, ?AUTHN:lookup_authenticator(Global, ID2)),
|
||||
|
||||
?assertMatch({ok, _}, update_config([authentication], {update_authenticator, Global, ID1, #{}})),
|
||||
?assertMatch({ok, #{id := ID1, state := #{mark := 2}}}, ?AUTHN:lookup_authenticator(Global, ID1)),
|
||||
|
||||
?assertMatch({ok, _}, update_config([authentication], {move_authenticator, Global, ID2, <<"top">>})),
|
||||
?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(Global)),
|
||||
|
||||
?assertMatch({ok, _}, update_config([authentication], {delete_authenticator, Global, ID1})),
|
||||
?assertEqual({error, {not_found, {authenticator, ID1}}}, ?AUTHN:lookup_authenticator(Global, ID1)),
|
||||
|
||||
ListenerID = <<"tcp:default">>,
|
||||
ConfKeyPath = [listeners, tcp, default, authentication],
|
||||
?assertMatch({ok, _}, update_config(ConfKeyPath, {create_authenticator, ListenerID, AuthenticatorConfig1})),
|
||||
?assertMatch({ok, #{id := ID1, state := #{mark := 1}}}, ?AUTHN:lookup_authenticator(ListenerID, ID1)),
|
||||
|
||||
?assertMatch({ok, _}, update_config(ConfKeyPath, {create_authenticator, ListenerID, AuthenticatorConfig2})),
|
||||
?assertMatch({ok, #{id := ID2, state := #{mark := 1}}}, ?AUTHN:lookup_authenticator(ListenerID, ID2)),
|
||||
|
||||
?assertMatch({ok, _}, update_config(ConfKeyPath, {update_authenticator, ListenerID, ID1, #{}})),
|
||||
?assertMatch({ok, #{id := ID1, state := #{mark := 2}}}, ?AUTHN:lookup_authenticator(ListenerID, ID1)),
|
||||
|
||||
?assertMatch({ok, _}, update_config(ConfKeyPath, {move_authenticator, ListenerID, ID2, <<"top">>})),
|
||||
?assertMatch({ok, [#{id := ID2}, #{id := ID1}]}, ?AUTHN:list_authenticators(ListenerID)),
|
||||
|
||||
?assertMatch({ok, _}, update_config(ConfKeyPath, {delete_authenticator, ListenerID, ID1})),
|
||||
?assertEqual({error, {not_found, {authenticator, ID1}}}, ?AUTHN:lookup_authenticator(ListenerID, ID1)),
|
||||
|
||||
?AUTHN:delete_chain(Global),
|
||||
?AUTHN:remove_provider(AuthNType1),
|
||||
?AUTHN:remove_provider(AuthNType2),
|
||||
ok.
|
||||
|
||||
update_config(Path, ConfigRequest) ->
|
||||
emqx:update_config(Path, ConfigRequest, #{rawconf_with_defaults => true}).
|
|
@ -251,8 +251,8 @@ generate_request(Credential, #{method := Method,
|
|||
post ->
|
||||
NPath = append_query(Path, BaseQuery),
|
||||
ContentType = proplists:get_value(<<"content-type">>, Headers),
|
||||
Body = serialize_body(ContentType, Body),
|
||||
{NPath, Headers, Body}
|
||||
NBody = serialize_body(ContentType, Body),
|
||||
{NPath, Headers, NBody}
|
||||
end.
|
||||
|
||||
replace_placeholders(KVs, Credential) ->
|
||||
|
|
|
@ -15,3 +15,8 @@
|
|||
%%--------------------------------------------------------------------
|
||||
|
||||
-module(emqx_authn_SUITE).
|
||||
|
||||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
|
||||
all() -> emqx_ct:all(?MODULE).
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
-module(emqx_authn_jwt_SUITE).
|
||||
|
||||
% -compile(export_all).
|
||||
% -compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
|
||||
% -include_lib("common_test/include/ct.hrl").
|
||||
% -include_lib("eunit/include/eunit.hrl").
|
||||
|
@ -26,8 +26,8 @@
|
|||
|
||||
% -define(AUTH, emqx_authn).
|
||||
|
||||
% all() ->
|
||||
% emqx_ct:all(?MODULE).
|
||||
all() ->
|
||||
emqx_ct:all(?MODULE).
|
||||
|
||||
% init_per_suite(Config) ->
|
||||
% emqx_ct_helpers:start_apps([emqx_authn]),
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
-module(emqx_authn_mnesia_SUITE).
|
||||
|
||||
% -compile(export_all).
|
||||
% -compile(nowarn_export_all).
|
||||
-compile(export_all).
|
||||
-compile(nowarn_export_all).
|
||||
|
||||
% -include_lib("common_test/include/ct.hrl").
|
||||
% -include_lib("eunit/include/eunit.hrl").
|
||||
|
@ -26,8 +26,8 @@
|
|||
|
||||
% -define(AUTH, emqx_authn).
|
||||
|
||||
% all() ->
|
||||
% emqx_ct:all(?MODULE).
|
||||
all() ->
|
||||
emqx_ct:all(?MODULE).
|
||||
|
||||
% init_per_suite(Config) ->
|
||||
% emqx_ct_helpers:start_apps([emqx_authn]),
|
||||
|
|
|
@ -142,7 +142,9 @@ to_ip_port(Str) ->
|
|||
_ -> {error, Str}
|
||||
end.
|
||||
|
||||
ip_port_to_string({Ip, Port}) ->
|
||||
ip_port_to_string({Ip, Port}) when is_list(Ip) ->
|
||||
iolist_to_binary([Ip, ":", integer_to_list(Port)]);
|
||||
ip_port_to_string({Ip, Port}) when is_tuple(Ip) ->
|
||||
iolist_to_binary([inet:ntoa(Ip), ":", integer_to_list(Port)]).
|
||||
|
||||
to_servers(Str) ->
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{vsn, "0.1.0"},
|
||||
{registered, []},
|
||||
{mod, {emqx_gateway_app, []}},
|
||||
{applications, [kernel, stdlib, grpc, lwm2m_coap, emqx, emqx_authn]},
|
||||
{applications, [kernel, stdlib, grpc, lwm2m_coap, emqx]},
|
||||
{env, []},
|
||||
{modules, []},
|
||||
{licenses, ["Apache 2.0"]},
|
||||
|
|
|
@ -55,20 +55,19 @@ metrics() ->
|
|||
init_per_group(GrpName, Cfg) ->
|
||||
put(grpname, GrpName),
|
||||
Svrs = emqx_exproto_echo_svr:start(),
|
||||
emqx_ct_helpers:start_apps([emqx_authn, emqx_gateway], fun set_special_cfg/1),
|
||||
emqx_ct_helpers:start_apps([emqx_gateway], fun set_special_cfg/1),
|
||||
emqx_logger:set_log_level(debug),
|
||||
[{servers, Svrs}, {listener_type, GrpName} | Cfg].
|
||||
|
||||
end_per_group(_, Cfg) ->
|
||||
emqx_ct_helpers:stop_apps([emqx_gateway, emqx_authn]),
|
||||
emqx_ct_helpers:stop_apps([emqx_gateway]),
|
||||
emqx_exproto_echo_svr:stop(proplists:get_value(servers, Cfg)).
|
||||
|
||||
set_special_cfg(emqx_gateway) ->
|
||||
LisType = get(grpname),
|
||||
emqx_config:put(
|
||||
[gateway, exproto],
|
||||
#{authentication => #{enable => false},
|
||||
server => #{bind => 9100},
|
||||
#{server => #{bind => 9100},
|
||||
handler => #{address => "http://127.0.0.1:9001"},
|
||||
listeners => listener_confs(LisType)
|
||||
});
|
||||
|
|
|
@ -35,11 +35,11 @@ all() -> emqx_ct:all(?MODULE).
|
|||
|
||||
init_per_suite(Cfg) ->
|
||||
ok = emqx_config:init_load(emqx_gateway_schema, ?CONF_DEFAULT),
|
||||
emqx_ct_helpers:start_apps([emqx_authn, emqx_gateway]),
|
||||
emqx_ct_helpers:start_apps([emqx_gateway]),
|
||||
Cfg.
|
||||
|
||||
end_per_suite(_Cfg) ->
|
||||
emqx_ct_helpers:stop_apps([emqx_authn, emqx_gateway]),
|
||||
emqx_ct_helpers:stop_apps([emqx_gateway]),
|
||||
ok.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -148,12 +148,12 @@ groups() ->
|
|||
].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
emqx_ct_helpers:start_apps([emqx_authn]),
|
||||
emqx_ct_helpers:start_apps([]),
|
||||
Config.
|
||||
|
||||
end_per_suite(Config) ->
|
||||
timer:sleep(300),
|
||||
emqx_ct_helpers:stop_apps([emqx_authn]),
|
||||
emqx_ct_helpers:stop_apps([]),
|
||||
Config.
|
||||
|
||||
init_per_testcase(_AllTestCase, Config) ->
|
||||
|
|
|
@ -83,11 +83,11 @@ all() ->
|
|||
|
||||
init_per_suite(Config) ->
|
||||
ok = emqx_config:init_load(emqx_gateway_schema, ?CONF_DEFAULT),
|
||||
emqx_ct_helpers:start_apps([emqx_authn, emqx_gateway]),
|
||||
emqx_ct_helpers:start_apps([emqx_gateway]),
|
||||
Config.
|
||||
|
||||
end_per_suite(_) ->
|
||||
emqx_ct_helpers:stop_apps([emqx_gateway, emqx_authn]).
|
||||
emqx_ct_helpers:stop_apps([emqx_gateway]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Test cases
|
||||
|
|
|
@ -43,11 +43,11 @@ all() -> emqx_ct:all(?MODULE).
|
|||
|
||||
init_per_suite(Cfg) ->
|
||||
ok = emqx_config:init_load(emqx_gateway_schema, ?CONF_DEFAULT),
|
||||
emqx_ct_helpers:start_apps([emqx_authn, emqx_gateway]),
|
||||
emqx_ct_helpers:start_apps([emqx_gateway]),
|
||||
Cfg.
|
||||
|
||||
end_per_suite(_Cfg) ->
|
||||
emqx_ct_helpers:stop_apps([emqx_gateway, emqx_authn]),
|
||||
emqx_ct_helpers:stop_apps([emqx_gateway]),
|
||||
ok.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue