chore(auth): update tests

This commit is contained in:
Ilya Averyanov 2023-09-27 21:40:08 +03:00
parent 1eb75b43c4
commit c2c56ba481
48 changed files with 247 additions and 242 deletions

View File

@ -39,7 +39,8 @@
flush/1, flush/1,
load/1, load/1,
render_and_load_app_config/1, render_and_load_app_config/1,
render_and_load_app_config/2 render_and_load_app_config/2,
copy_acl_conf/0
]). ]).
-export([ -export([
@ -527,11 +528,11 @@ copy_certs(_, _) ->
copy_acl_conf() -> copy_acl_conf() ->
Dest = filename:join([code:lib_dir(emqx), "etc/acl.conf"]), Dest = filename:join([code:lib_dir(emqx), "etc/acl.conf"]),
case code:lib_dir(emqx_auth_file) of case code:lib_dir(emqx_auth) of
{error, bad_name} -> {error, bad_name} ->
(not filelib:is_regular(Dest)) andalso file:write_file(Dest, <<"">>); (not filelib:is_regular(Dest)) andalso file:write_file(Dest, <<"">>);
_ -> _ ->
{ok, _} = file:copy(deps_path(emqx_auth_file, "etc/acl.conf"), Dest) {ok, _} = file:copy(deps_path(emqx_auth, "etc/acl.conf"), Dest)
end, end,
ok. ok.

View File

@ -361,10 +361,16 @@ default_appspec(emqx_conf, SuiteOpts) ->
), ),
#{ #{
config => SharedConfig, config => SharedConfig,
% NOTE before_start => fun(App, Conf) ->
% We inform `emqx` of our config loader before starting `emqx_conf` so that it won't % NOTE
% overwrite everything with a default configuration. % We inform `emqx` of our config loader before starting `emqx_conf` so that it won't
before_start => fun inhibit_config_loader/2 % overwrite everything with a default configuration.
ok = inhibit_config_loader(App, Conf),
% NOTE
% This should be done to pass authz schema validations.
% In production, acl.conf file is created by the release process.
ok = emqx_common_test_helpers:copy_acl_conf()
end
}; };
default_appspec(emqx_dashboard, _SuiteOpts) -> default_appspec(emqx_dashboard, _SuiteOpts) ->
#{ #{

View File

@ -37,7 +37,7 @@
start(_StartType, _StartArgs) -> start(_StartType, _StartArgs) ->
%% required by test cases, ensure the injection of schema %% required by test cases, ensure the injection of schema
_ = emqx_conf_schema:roots(), _ = emqx_conf_schema:roots(),
{ok, Sup} = emqx_authn_sup:start_link(), {ok, Sup} = emqx_auth_sup:start_link(),
ok = emqx_authz:init(), ok = emqx_authz:init(),
{ok, Sup}. {ok, Sup}.

View File

@ -372,6 +372,17 @@ handle_call(
end; end;
handle_call({deregister_providers, AuthNTypes}, _From, #{providers := Providers} = State) -> handle_call({deregister_providers, AuthNTypes}, _From, #{providers := Providers} = State) ->
reply(ok, State#{providers := maps:without(AuthNTypes, Providers)}); reply(ok, State#{providers := maps:without(AuthNTypes, Providers)});
%% Do not handle anything else before initialization is done.
%% TODO convert gen_server to gen_statem
handle_call(_, _From, #{init_done := false, providers := Providers} = State) ->
ProviderTypes = maps:keys(Providers),
Chains = chain_configs(),
?SLOG(error, #{
msg => "authentication_not_initialized",
configured_provider_types => configured_provider_types(Chains),
registered_provider_types => ProviderTypes
}),
reply({error, not_initialized}, State);
handle_call({delete_chain, ChainName}, _From, State) -> handle_call({delete_chain, ChainName}, _From, State) ->
UpdateFun = fun(Chain) -> UpdateFun = fun(Chain) ->
{_MatchedIDs, NewChain} = do_delete_authenticators(fun(_) -> true end, Chain), {_MatchedIDs, NewChain} = do_delete_authenticators(fun(_) -> true end, Chain),
@ -469,14 +480,9 @@ code_change(_OldVsn, State, _Extra) ->
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
initialize_authentication(Providers) -> initialize_authentication(Providers) ->
Chains = chain_configs(),
ProviderTypes = maps:keys(Providers), ProviderTypes = maps:keys(Providers),
HasProviders = lists:all( Chains = chain_configs(),
fun({_, ChainConfigs}) -> HasProviders = has_providers_for_configs(Chains, ProviderTypes),
has_providers_for_configs(ChainConfigs, ProviderTypes)
end,
Chains
),
do_initialize_authentication(Providers, Chains, HasProviders). do_initialize_authentication(Providers, Chains, HasProviders).
do_initialize_authentication(_Providers, _Chains, _HasProviders = false) -> do_initialize_authentication(_Providers, _Chains, _HasProviders = false) ->
@ -513,25 +519,30 @@ initialize_chain_authentication(Providers, ChainName, AuthenticatorsConfig) ->
to_list(AuthenticatorsConfig) to_list(AuthenticatorsConfig)
). ).
has_providers_for_configs(AuthConfig, ProviderTypes) -> has_providers_for_configs(Chains, ProviderTypes) ->
(configured_provider_types(Chains) -- ProviderTypes) =:= [].
configured_provider_types(Chains) ->
{_, ChainConfs} = lists:unzip(Chains),
ProviderTypes = lists:flatmap(
fun provider_types_for_chain/1,
ChainConfs
),
lists:usort(ProviderTypes).
provider_types_for_chain(AuthConfig) ->
Configs = to_list(AuthConfig), Configs = to_list(AuthConfig),
lists:all( lists:map(
fun(Config) -> fun(Config) ->
has_providers_for_config(Config, ProviderTypes) provider_type_for_config(Config)
end, end,
Configs Configs
). ).
has_providers_for_config(_Config, []) -> provider_type_for_config(#{mechanism := Mechanism, backend := Backend}) ->
false; {Mechanism, Backend};
has_providers_for_config(#{mechanism := Mechanism, backend := Backend}, [ provider_type_for_config(#{mechanism := Mechanism}) ->
{Mechanism, Backend} | _ProviderTypes Mechanism.
]) ->
true;
has_providers_for_config(#{mechanism := Mechanism}, [Mechanism | _ProviderTypes]) ->
true;
has_providers_for_config(Config, [_ProviderType | ProviderTypes]) ->
has_providers_for_config(Config, ProviderTypes).
handle_update_authenticator(Chain, AuthenticatorID, Config) -> handle_update_authenticator(Chain, AuthenticatorID, Config) ->
#chain{authenticators = Authenticators} = Chain, #chain{authenticators = Authenticators} = Chain,

View File

@ -228,9 +228,9 @@ create_or_update_authenticators(OldIds, ChainName, NewConfig) ->
Id = authenticator_id(Conf), Id = authenticator_id(Conf),
case lists:member(Id, OldIds) of case lists:member(Id, OldIds) of
true -> true ->
emqx_authn_chains:update_authenticator(ChainName, Id, Conf); {ok, _} = emqx_authn_chains:update_authenticator(ChainName, Id, Conf);
false -> false ->
emqx_authn_chains:create_authenticator(ChainName, Conf) {ok, _} = emqx_authn_chains:create_authenticator(ChainName, Conf)
end end
end, end,
NewConfig NewConfig
@ -245,7 +245,7 @@ delete_authenticators(NewIds, ChainName, OldConfig) ->
true -> true ->
ok; ok;
false -> false ->
emqx_authn_chains:delete_authenticator(ChainName, Id) ok = emqx_authn_chains:delete_authenticator(ChainName, Id)
end end
end, end,
OldConfig OldConfig

View File

@ -10,16 +10,6 @@
-if(?EMQX_RELEASE_EDITION == ee). -if(?EMQX_RELEASE_EDITION == ee).
% providers() ->
% [
% {{password_based, ldap}, emqx_authn_ldap},
% {{password_based, ldap_bind}, emqx_ldap_authn_bind},
% {gcp_device, emqx_gcp_device_authn}
% ].
% resource_provider() ->
% [emqx_authn_ldap, emqx_ldap_authn_bind].
provider_schema_mods() -> provider_schema_mods() ->
?EE_PROVIDER_SCHEMA_MODS. ?EE_PROVIDER_SCHEMA_MODS.
@ -28,9 +18,4 @@ provider_schema_mods() ->
provider_schema_mods() -> provider_schema_mods() ->
[]. [].
% providers() ->
% [].
% resource_provider() ->
% [].
-endif. -endif.

View File

@ -22,6 +22,8 @@
-include("emqx_authn_schema.hrl"). -include("emqx_authn_schema.hrl").
-include("emqx_authn_chains.hrl"). -include("emqx_authn_chains.hrl").
-include_lib("eunit/include/eunit.hrl").
-behaviour(emqx_schema_hooks). -behaviour(emqx_schema_hooks).
-export([ -export([
injected_fields/0 injected_fields/0
@ -30,7 +32,6 @@
-export([ -export([
common_fields/0, common_fields/0,
roots/0, roots/0,
% validations/0,
tags/0, tags/0,
fields/1, fields/1,
authenticator_type/0, authenticator_type/0,
@ -39,6 +40,10 @@
backend/1 backend/1
]). ]).
-export([
global_auth_fields/0
]).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Authn Source Schema Behaviour %% Authn Source Schema Behaviour
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -110,6 +115,7 @@ global_auth_fields() ->
desc => ?DESC(global_authentication), desc => ?DESC(global_authentication),
converter => fun ensure_array/2, converter => fun ensure_array/2,
default => [], default => [],
validator => validator(),
importance => ?IMPORTANCE_LOW importance => ?IMPORTANCE_LOW
})} })}
]. ].
@ -121,6 +127,7 @@ mqtt_listener_auth_fields() ->
desc => ?DESC(listener_authentication), desc => ?DESC(listener_authentication),
converter => fun ensure_array/2, converter => fun ensure_array/2,
default => [], default => [],
validator => validator(),
importance => ?IMPORTANCE_HIDDEN importance => ?IMPORTANCE_HIDDEN
})} })}
]. ].
@ -206,6 +213,33 @@ common_field() ->
{"rate_last5m", ?HOCON(float(), #{desc => ?DESC("rate_last5m")})} {"rate_last5m", ?HOCON(float(), #{desc => ?DESC("rate_last5m")})}
]. ].
validator() ->
Validations = lists:flatmap(
fun validations/1,
provider_schema_mods()
),
fun(AuthConf) ->
lists:foreach(
fun(Conf) ->
lists:foreach(
fun({_Name, Validation}) ->
Validation(Conf)
end,
Validations
)
end,
wrap_list(AuthConf)
)
end.
validations(Mod) ->
case erlang:function_exported(Mod, validations, 0) of
true ->
Mod:validations();
false ->
[]
end.
provider_schema_mods() -> provider_schema_mods() ->
?PROVIDER_SCHEMA_MODS ++ emqx_authn_enterprise:provider_schema_mods(). ?PROVIDER_SCHEMA_MODS ++ emqx_authn_enterprise:provider_schema_mods().
@ -223,3 +257,8 @@ array(Name) ->
array(Name, DescId) -> array(Name, DescId) ->
{Name, ?HOCON(?R_REF(Name), #{desc => ?DESC(DescId)})}. {Name, ?HOCON(?R_REF(Name), #{desc => ?DESC(DescId)})}.
wrap_list(Map) when is_map(Map) ->
[Map];
wrap_list(L) when is_list(L) ->
L.

View File

@ -57,8 +57,6 @@
maybe_read_source_files_safe/1 maybe_read_source_files_safe/1
]). ]).
% -export([acl_conf_file/0]).
%% Data backup %% Data backup
-export([ -export([
import_config/1, import_config/1,
@ -89,9 +87,9 @@ init() ->
ok = register_metrics(), ok = register_metrics(),
emqx_conf:add_handler(?CONF_KEY_PATH, ?MODULE), emqx_conf:add_handler(?CONF_KEY_PATH, ?MODULE),
emqx_conf:add_handler(?ROOT_KEY, ?MODULE), emqx_conf:add_handler(?ROOT_KEY, ?MODULE),
emqx_authz_source_registry:create(),
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize_deny, []}, ?HP_AUTHZ), ok = emqx_hooks:put('client.authorize', {?MODULE, authorize_deny, []}, ?HP_AUTHZ),
ok = register_source(client_info, emqx_authz_client_info), ok = register_source(client_info, emqx_authz_client_info),
ok = register_source(file, emqx_authz_file),
ok. ok.
register_source(Type, Module) -> register_source(Type, Module) ->
@ -748,6 +746,13 @@ type_take(Type, Sources) ->
-compile(export_all). -compile(export_all).
merge_sources_test() -> merge_sources_test() ->
ok = emqx_authz_source_registry:create(),
ok = lists:foreach(
fun(Type) ->
ok = emqx_authz_source_registry:register(Type, ?MODULE)
end,
[file, http, mysql, mongodb, redis, postgresql]
),
Default = [emqx_authz_schema:default_authz()], Default = [emqx_authz_schema:default_authz()],
Http = #{<<"type">> => <<"http">>, <<"enable">> => true}, Http = #{<<"type">> => <<"http">>, <<"enable">> => true},
Mysql = #{<<"type">> => <<"mysql">>, <<"enable">> => true}, Mysql = #{<<"type">> => <<"mysql">>, <<"enable">> => true},

View File

@ -118,7 +118,7 @@ desc(_) ->
injected_fields() -> injected_fields() ->
#{ #{
'roots.high' => [ 'roots.high' => [
{?CONF_NS, ?HOCON(?R_REF("authorization"), #{desc => ?DESC(?CONF_NS)})} {?CONF_NS, ?HOCON(?R_REF(?CONF_NS), #{desc => ?DESC(?CONF_NS)})}
] ]
}. }.

View File

@ -33,6 +33,7 @@ start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []). supervisor:start_link({local, ?SERVER}, ?MODULE, []).
init([]) -> init([]) ->
emqx_authz_source_registry:create(),
SupFlags = #{ SupFlags = #{
strategy => one_for_all, strategy => one_for_all,
intensity => 0, intensity => 0,

View File

@ -66,7 +66,9 @@ authorize(Client, PubSub, Topic, #{annotations := #{rules := Rules}}) ->
read_files(#{<<"path">> := Path} = Source) -> read_files(#{<<"path">> := Path} = Source) ->
{ok, Rules} = read_file(Path), {ok, Rules} = read_file(Path),
maps:remove(<<"path">>, Source#{<<"rules">> => Rules}). maps:remove(<<"path">>, Source#{<<"rules">> => Rules});
read_files(#{<<"rules">> := _} = Source) ->
Source.
write_files(#{<<"rules">> := Rules} = Source0) -> write_files(#{<<"rules">> := Rules} = Source0) ->
AclPath = ?MODULE:acl_conf_file(), AclPath = ?MODULE:acl_conf_file(),
@ -75,7 +77,9 @@ write_files(#{<<"rules">> := Rules} = Source0) ->
ok = check_acl_file_rules(AclPath, Rules), ok = check_acl_file_rules(AclPath, Rules),
ok = write_file(AclPath, Rules), ok = write_file(AclPath, Rules),
Source1 = maps:remove(<<"rules">>, Source0), Source1 = maps:remove(<<"rules">>, Source0),
maps:put(<<"path">>, AclPath, Source1). maps:put(<<"path">>, AclPath, Source1);
write_files(#{<<"path">> := _} = Source) ->
Source.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Internal functions %% Internal functions

View File

@ -81,7 +81,7 @@ t_fill_defaults(Config) when is_list(Config) ->
). ).
t_will_message_connection_denied({init, Config}) -> t_will_message_connection_denied({init, Config}) ->
emqx_common_test_helpers:start_apps([emqx_conf, emqx_auth, emqx_auth_file]), emqx_common_test_helpers:start_apps([emqx_conf, emqx_auth]),
emqx_authn_test_lib:register_fake_providers([{password_based, built_in_database}]), emqx_authn_test_lib:register_fake_providers([{password_based, built_in_database}]),
AuthnConfig = #{ AuthnConfig = #{
<<"mechanism">> => <<"password_based">>, <<"mechanism">> => <<"password_based">>,
@ -106,7 +106,7 @@ t_will_message_connection_denied({'end', _Config}) ->
[authentication], [authentication],
{delete_authenticator, 'mqtt:global', <<"password_based:built_in_database">>} {delete_authenticator, 'mqtt:global', <<"password_based:built_in_database">>}
), ),
emqx_common_test_helpers:stop_apps([emqx_auth_file, emqx_auth, emqx_conf]), emqx_common_test_helpers:stop_apps([emqx_auth, emqx_conf]),
ok; ok;
t_will_message_connection_denied(Config) when is_list(Config) -> t_will_message_connection_denied(Config) when is_list(Config) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),

View File

@ -22,114 +22,113 @@
-define(ERR(Reason), {error, Reason}). -define(ERR(Reason), {error, Reason}).
union_member_selector_mongo_test_() -> union_member_selector_mongo_test_() ->
Check = fun(Txt) -> check(emqx_authn_mongodb, Txt) end,
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{field_name := mongo_type, expected := _}), ?ERR(#{field_name := mongo_type, expected := _}),
Check("{mongo_type: foobar}") check("{mechanism = password_based, backend = mongodb, mongo_type = foobar}")
) )
end}, end},
{"single", fun() -> {"single", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:mongo_single"}), ?ERR(#{matched_type := "mongo_single"}),
Check("{mongo_type: single}") check("{mechanism = password_based, backend = mongodb, mongo_type = single}")
) )
end}, end},
{"replica-set", fun() -> {"replica-set", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:mongo_rs"}), ?ERR(#{matched_type := "mongo_rs"}),
Check("{mongo_type: rs}") check("{mechanism = password_based, backend = mongodb, mongo_type = rs}")
) )
end}, end},
{"sharded", fun() -> {"sharded", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:mongo_sharded"}), ?ERR(#{matched_type := "mongo_sharded"}),
Check("{mongo_type: sharded}") check("{mechanism = password_based, backend = mongodb, mongo_type = sharded}")
) )
end} end}
]. ].
union_member_selector_jwt_test_() -> union_member_selector_jwt_test_() ->
Check = fun(Txt) -> check(emqx_authn_jwt, Txt) end,
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{field_name := use_jwks, expected := "true | false"}), ?ERR(#{field_name := use_jwks, expected := "true | false"}),
Check("{use_jwks = 1}") check("{mechanism = jwt, use_jwks = 1}")
) )
end}, end},
{"jwks", fun() -> {"jwks", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:jwt_jwks"}), ?ERR(#{matched_type := "jwt_jwks"}),
Check("{use_jwks = true}") check("{mechanism = jwt, use_jwks = true}")
) )
end}, end},
{"publick-key", fun() -> {"publick-key", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:jwt_public_key"}), ?ERR(#{matched_type := "jwt_public_key"}),
Check("{use_jwks = false, public_key = 1}") check("{mechanism = jwt, use_jwks = false, public_key = 1}")
) )
end}, end},
{"hmac-based", fun() -> {"hmac-based", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:jwt_hmac"}), ?ERR(#{matched_type := "jwt_hmac"}),
Check("{use_jwks = false}") check("{mechanism = jwt, use_jwks = false}")
) )
end} end}
]. ].
union_member_selector_redis_test_() -> union_member_selector_redis_test_() ->
Check = fun(Txt) -> check(emqx_authn_redis, Txt) end,
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{field_name := redis_type, expected := _}), ?ERR(#{field_name := redis_type, expected := _}),
Check("{redis_type = 1}") check("{mechanism = password_based, backend = redis, redis_type = 1}")
) )
end}, end},
{"single", fun() -> {"single", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:redis_single"}), ?ERR(#{matched_type := "redis_single"}),
Check("{redis_type = single}") check("{mechanism = password_based, backend = redis, redis_type = single}")
) )
end}, end},
{"cluster", fun() -> {"cluster", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:redis_cluster"}), ?ERR(#{matched_type := "redis_cluster"}),
Check("{redis_type = cluster}") check("{mechanism = password_based, backend = redis, redis_type = cluster}")
) )
end}, end},
{"sentinel", fun() -> {"sentinel", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:redis_sentinel"}), ?ERR(#{matched_type := "redis_sentinel"}),
Check("{redis_type = sentinel}") check("{mechanism = password_based, backend = redis, redis_type = sentinel}")
) )
end} end}
]. ].
union_member_selector_http_test_() -> union_member_selector_http_test_() ->
Check = fun(Txt) -> check(emqx_authn_http, Txt) end,
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{field_name := method, expected := _}), ?ERR(#{field_name := method, expected := _}),
Check("{method = 1}") check("{mechanism = password_based, backend = http, method = 1}")
) )
end}, end},
{"get", fun() -> {"get", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:http_get"}), ?ERR(#{matched_type := "http_get"}),
Check("{method = get}") check("{mechanism = password_based, backend = http, method = get}")
) )
end}, end},
{"post", fun() -> {"post", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "authn:http_post"}), ?ERR(#{matched_type := "http_post"}),
Check("{method = post}") check("{mechanism = password_based, backend = http, method = post}")
) )
end} end}
]. ].
check(Module, HoconConf) -> check(HoconConf) ->
emqx_hocon:check(Module, ["authentication= ", HoconConf]). emqx_hocon:check(
#{roots => emqx_authn_schema:global_auth_fields()},
["authentication= ", HoconConf]
).

View File

@ -42,7 +42,7 @@ init_per_suite(Config) ->
emqx_authz_file, emqx_authz_file,
acl_conf_file, acl_conf_file,
fun() -> fun() ->
emqx_common_test_helpers:deps_path(emqx_auth_file, "etc/acl.conf") emqx_common_test_helpers:deps_path(emqx_auth, "etc/acl.conf")
end end
), ),
Apps = emqx_cth_suite:start( Apps = emqx_cth_suite:start(
@ -51,7 +51,6 @@ init_per_suite(Config) ->
{emqx_conf, {emqx_conf,
"authorization { cache { enable = false }, no_match = deny, sources = [] }"}, "authorization { cache { enable = false }, no_match = deny, sources = [] }"},
emqx_auth, emqx_auth,
emqx_auth_file,
emqx_auth_http, emqx_auth_http,
emqx_auth_mnesia, emqx_auth_mnesia,
emqx_auth_redis, emqx_auth_redis,

View File

@ -110,7 +110,7 @@ init_per_suite(Config) ->
emqx_authz_file, emqx_authz_file,
acl_conf_file, acl_conf_file,
fun() -> fun() ->
emqx_common_test_helpers:deps_path(emqx_auth_file, "etc/acl.conf") emqx_common_test_helpers:deps_path(emqx_auth, "etc/acl.conf")
end end
), ),
@ -120,7 +120,6 @@ init_per_suite(Config) ->
{emqx_conf, {emqx_conf,
"authorization { cache { enable = false }, no_match = deny, sources = [] }"}, "authorization { cache { enable = false }, no_match = deny, sources = [] }"},
emqx_auth, emqx_auth,
emqx_auth_file,
emqx_auth_http, emqx_auth_http,
emqx_auth_mnesia, emqx_auth_mnesia,
emqx_auth_redis, emqx_auth_redis,

View File

@ -43,8 +43,7 @@ init_per_testcase(TestCase, Config) ->
[ [
{emqx_conf, "authorization.no_match = deny, authorization.cache.enable = false"}, {emqx_conf, "authorization.no_match = deny, authorization.cache.enable = false"},
emqx, emqx,
emqx_auth, emqx_auth
emqx_auth_file
], ],
#{work_dir => filename:join(?config(priv_dir, Config), TestCase)} #{work_dir => filename:join(?config(priv_dir, Config), TestCase)}
), ),

View File

@ -36,8 +36,7 @@ init_per_testcase(TestCase, Config) ->
[ [
emqx, emqx,
{emqx_conf, "authorization.no_match = deny, authorization.cache.enable = false"}, {emqx_conf, "authorization.no_match = deny, authorization.cache.enable = false"},
emqx_auth, emqx_auth
emqx_auth_file
], ],
#{work_dir => filename:join(?config(priv_dir, Config), TestCase)} #{work_dir => filename:join(?config(priv_dir, Config), TestCase)}
), ),

View File

@ -113,4 +113,4 @@ check(Txt0) ->
end. end.
schema() -> schema() ->
#{roots => emqx_authz_schema:fields("authorization")}. #{roots => emqx_authz_schema:authz_fields()}.

View File

@ -1,7 +0,0 @@
%% -*- mode: erlang -*-
{deps, [
{emqx, {path, "../emqx"}},
{emqx_utils, {path, "../emqx_utils"}},
{emqx_auth, {path, "../emqx_auth"}}
]}.

View File

@ -1,18 +0,0 @@
%% -*- mode: erlang -*-
{application, emqx_auth_file, [
{description, "EMQX File-based Authentication and Authorization"},
{vsn, "0.1.0"},
{registered, []},
{mod, {emqx_auth_file_app, []}},
{applications, [
kernel,
stdlib,
emqx,
emqx_auth
]},
{env, []},
{modules, []},
{licenses, ["Apache 2.0"]},
{links, []}
]}.

View File

@ -1,32 +0,0 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020-2023 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_auth_file_app).
-include("emqx_auth_file.hrl").
-behaviour(application).
-export([start/2, stop/1]).
start(_StartType, _StartArgs) ->
ok = emqx_authz:register_source(?AUTHZ_TYPE, emqx_authz_file),
{ok, Sup} = emqx_auth_file_sup:start_link(),
{ok, Sup}.
stop(_State) ->
ok = emqx_authz:unregister_source(?AUTHZ_TYPE),
ok.

View File

@ -1,37 +0,0 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020-2023 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_auth_file_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
-define(SERVER, ?MODULE).
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
init([]) ->
SupFlags = #{
strategy => one_for_all,
intensity => 0,
period => 1
},
ChildSpecs = [],
{ok, {SupFlags, ChildSpecs}}.

View File

@ -24,12 +24,19 @@
-export([ -export([
fields/1, fields/1,
validations/0,
desc/1, desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
-define(NOT_EMPTY(MSG), emqx_resource_validator:not_empty(MSG)). -define(NOT_EMPTY(MSG), emqx_resource_validator:not_empty(MSG)).
-define(THROW_VALIDATION_ERROR(ERROR, MESSAGE),
throw(#{
error => ERROR,
message => MESSAGE
})
).
refs() -> refs() ->
[?R_REF(http_get), ?R_REF(http_post)]. [?R_REF(http_get), ?R_REF(http_post)].
@ -78,6 +85,12 @@ desc(http_post) ->
desc(_) -> desc(_) ->
undefined. undefined.
validations() ->
[
{check_ssl_opts, fun check_ssl_opts/1},
{check_headers, fun check_headers/1}
].
common_fields() -> common_fields() ->
[ [
{mechanism, emqx_authn_schema:mechanism(?AUTHN_MECHANISM)}, {mechanism, emqx_authn_schema:mechanism(?AUTHN_MECHANISM)},
@ -130,3 +143,39 @@ request_timeout(type) -> emqx_schema:duration_ms();
request_timeout(desc) -> ?DESC(?FUNCTION_NAME); request_timeout(desc) -> ?DESC(?FUNCTION_NAME);
request_timeout(default) -> <<"5s">>; request_timeout(default) -> <<"5s">>;
request_timeout(_) -> undefined. request_timeout(_) -> undefined.
check_ssl_opts(#{
backend := ?AUTHN_BACKEND, url := <<"https://", _/binary>>, ssl := #{enable := false}
}) ->
?THROW_VALIDATION_ERROR(
invalid_ssl_opts,
<<"it's required to enable the TLS option to establish a https connection">>
);
check_ssl_opts(#{
<<"backend">> := ?AUTHN_BACKEND,
<<"url">> := <<"https://", _/binary>>,
<<"ssl">> := #{<<"enable">> := false}
}) ->
?THROW_VALIDATION_ERROR(
invalid_ssl_opts,
<<"it's required to enable the TLS option to establish a https connection">>
);
check_ssl_opts(_) ->
ok.
check_headers(#{backend := ?AUTHN_BACKEND, headers := Headers, method := get}) ->
do_check_get_headers(Headers);
check_headers(#{<<"backend">> := ?AUTHN_BACKEND, <<"headers">> := Headers, <<"method">> := get}) ->
do_check_get_headers(Headers);
check_headers(_) ->
ok.
do_check_get_headers(Headers) ->
case maps:is_key(<<"content-type">>, Headers) of
false ->
ok;
true ->
?THROW_VALIDATION_ERROR(
invalid_headers, <<"HTTP GET requests cannot include content-type header.">>
)
end.

View File

@ -7,7 +7,9 @@
{applications, [ {applications, [
kernel, kernel,
stdlib, stdlib,
emqx_auth emqx_auth,
emqx_resource,
emqx_connector
]}, ]},
{env, []}, {env, []},
{modules, []}, {modules, []},

View File

@ -23,6 +23,7 @@
-export([ -export([
fields/1, fields/1,
desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
@ -51,10 +52,10 @@ fields(ldap_bind) ->
emqx_authn_schema:common_fields() ++ emqx_authn_schema:common_fields() ++
emqx_ldap:fields(config) ++ emqx_ldap:fields(bind_opts). emqx_ldap:fields(config) ++ emqx_ldap:fields(bind_opts).
% desc(ldap_bind) -> desc(ldap_bind) ->
% ?DESC(ldap_bind); ?DESC(ldap_bind);
% desc(_) -> desc(_) ->
% undefined. undefined.
query_timeout(type) -> emqx_schema:timeout_duration_ms(); query_timeout(type) -> emqx_schema:timeout_duration_ms();
query_timeout(desc) -> ?DESC(?FUNCTION_NAME); query_timeout(desc) -> ?DESC(?FUNCTION_NAME);

View File

@ -23,6 +23,7 @@
-export([ -export([
fields/1, fields/1,
desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
@ -51,10 +52,10 @@ fields(ldap) ->
emqx_authn_schema:common_fields() ++ emqx_authn_schema:common_fields() ++
emqx_ldap:fields(config). emqx_ldap:fields(config).
% desc(ldap) -> desc(ldap) ->
% ?DESC(ldap); ?DESC(ldap);
% desc(_) -> desc(_) ->
% undefined. undefined.
password_attribute(type) -> string(); password_attribute(type) -> string();
password_attribute(desc) -> ?DESC(?FUNCTION_NAME); password_attribute(desc) -> ?DESC(?FUNCTION_NAME);

View File

@ -31,7 +31,7 @@ init_per_suite(Config) ->
_ = application:load(emqx_conf), _ = application:load(emqx_conf),
case emqx_common_test_helpers:is_tcp_server_available(?LDAP_HOST, ?LDAP_DEFAULT_PORT) of case emqx_common_test_helpers:is_tcp_server_available(?LDAP_HOST, ?LDAP_DEFAULT_PORT) of
true -> true ->
Apps = emqx_cth_suite:start([emqx, emqx_conf, emqx_auth], #{ Apps = emqx_cth_suite:start([emqx, emqx_conf, emqx_auth, emqx_auth_ldap], #{
work_dir => ?config(priv_dir, Config) work_dir => ?config(priv_dir, Config)
}), }),
{ok, _} = emqx_resource:create_local( {ok, _} = emqx_resource:create_local(

View File

@ -21,7 +21,6 @@ all() ->
emqx_common_test_helpers:all(?MODULE). emqx_common_test_helpers:all(?MODULE).
init_per_testcase(_, Config) -> init_per_testcase(_, Config) ->
emqx_authentication:initialize_authentication(?GLOBAL, []),
emqx_authn_test_lib:delete_authenticators( emqx_authn_test_lib:delete_authenticators(
[authentication], [authentication],
?GLOBAL ?GLOBAL
@ -32,7 +31,7 @@ init_per_suite(Config) ->
_ = application:load(emqx_conf), _ = application:load(emqx_conf),
case emqx_common_test_helpers:is_tcp_server_available(?LDAP_HOST, ?LDAP_DEFAULT_PORT) of case emqx_common_test_helpers:is_tcp_server_available(?LDAP_HOST, ?LDAP_DEFAULT_PORT) of
true -> true ->
Apps = emqx_cth_suite:start([emqx, emqx_conf, emqx_authn], #{ Apps = emqx_cth_suite:start([emqx, emqx_conf, emqx_auth, emqx_auth_ldap], #{
work_dir => ?config(priv_dir, Config) work_dir => ?config(priv_dir, Config)
}), }),
{ok, _} = emqx_resource:create_local( {ok, _} = emqx_resource:create_local(
@ -67,7 +66,7 @@ t_create(_Config) ->
{create_authenticator, ?GLOBAL, AuthConfig} {create_authenticator, ?GLOBAL, AuthConfig}
), ),
{ok, [#{provider := emqx_ldap_authn_bind}]} = emqx_authentication:list_authenticators(?GLOBAL), {ok, [#{provider := emqx_authn_ldap_bind}]} = emqx_authn_chains:list_authenticators(?GLOBAL),
emqx_authn_test_lib:delete_config(?ResourceID). emqx_authn_test_lib:delete_config(?ResourceID).
t_create_invalid(_Config) -> t_create_invalid(_Config) ->
@ -88,7 +87,7 @@ t_create_invalid(_Config) ->
emqx_authn_test_lib:delete_config(?ResourceID), emqx_authn_test_lib:delete_config(?ResourceID),
?assertEqual( ?assertEqual(
{error, {not_found, {chain, ?GLOBAL}}}, {error, {not_found, {chain, ?GLOBAL}}},
emqx_authentication:list_authenticators(?GLOBAL) emqx_authn_chains:list_authenticators(?GLOBAL)
) )
end, end,
InvalidConfigs InvalidConfigs
@ -135,10 +134,10 @@ t_destroy(_Config) ->
{create_authenticator, ?GLOBAL, AuthConfig} {create_authenticator, ?GLOBAL, AuthConfig}
), ),
{ok, [#{provider := emqx_ldap_authn_bind, state := State}]} = {ok, [#{provider := emqx_authn_ldap_bind, state := State}]} =
emqx_authentication:list_authenticators(?GLOBAL), emqx_authn_chains:list_authenticators(?GLOBAL),
{ok, _} = emqx_ldap_authn_bind:authenticate( {ok, _} = emqx_authn_ldap_bind:authenticate(
#{ #{
username => <<"mqttuser0001">>, username => <<"mqttuser0001">>,
password => <<"mqttuser0001">> password => <<"mqttuser0001">>
@ -154,7 +153,7 @@ t_destroy(_Config) ->
% Authenticator should not be usable anymore % Authenticator should not be usable anymore
?assertMatch( ?assertMatch(
ignore, ignore,
emqx_ldap_authn_bind:authenticate( emqx_authn_ldap_bind:authenticate(
#{ #{
username => <<"mqttuser0001">>, username => <<"mqttuser0001">>,
password => <<"mqttuser0001">> password => <<"mqttuser0001">>

View File

@ -25,7 +25,7 @@ init_per_suite(Config) ->
case emqx_common_test_helpers:is_tcp_server_available(?LDAP_HOST, ?LDAP_DEFAULT_PORT) of case emqx_common_test_helpers:is_tcp_server_available(?LDAP_HOST, ?LDAP_DEFAULT_PORT) of
true -> true ->
ok = emqx_common_test_helpers:start_apps( ok = emqx_common_test_helpers:start_apps(
[emqx_conf, emqx_authz], [emqx_conf, emqx_auth, emqx_auth_ldap],
fun set_special_configs/1 fun set_special_configs/1
), ),
ok = start_apps([emqx_resource]), ok = start_apps([emqx_resource]),
@ -39,7 +39,7 @@ end_per_suite(_Config) ->
ok = emqx_authz_test_lib:restore_authorizers(), ok = emqx_authz_test_lib:restore_authorizers(),
ok = emqx_resource:remove_local(?LDAP_RESOURCE), ok = emqx_resource:remove_local(?LDAP_RESOURCE),
ok = stop_apps([emqx_resource]), ok = stop_apps([emqx_resource]),
ok = emqx_common_test_helpers:stop_apps([emqx_conf, emqx_authz]). ok = emqx_common_test_helpers:stop_apps([emqx_conf, emqx_auth, emqx_auth_ldap]).
init_per_group(Group, Config) -> init_per_group(Group, Config) ->
[{test_case, emqx_authz_test_lib:get_case(Group, cases())} | Config]. [{test_case, emqx_authz_test_lib:get_case(Group, cases())} | Config].

View File

@ -76,6 +76,7 @@
emqx_conf, emqx_conf,
emqx, emqx,
emqx_auth, emqx_auth,
emqx_auth_mnesia,
emqx_management, emqx_management,
{emqx_rule_engine, "rule_engine { rules {} }"}, {emqx_rule_engine, "rule_engine { rules {} }"},
{emqx_bridge, "bridges {}"} {emqx_bridge, "bridges {}"}

View File

@ -27,11 +27,11 @@ all() ->
emqx_common_test_helpers:all(?MODULE). emqx_common_test_helpers:all(?MODULE).
init_per_suite(Config) -> init_per_suite(Config) ->
emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_auth]), emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_auth, emqx_auth_redis]),
Config. Config.
end_per_suite(_Config) -> end_per_suite(_Config) ->
emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_auth]). emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_auth, emqx_auth_redis]).
t_load_config(Config) -> t_load_config(Config) ->
Authz = authorization, Authz = authorization,

View File

@ -338,13 +338,11 @@ log_rotation_count_limit_test() ->
""" """
). ).
-define(ERROR(Reason), -define(ERROR(Error),
{emqx_conf_schema, [ {emqx_conf_schema, [
#{ #{
kind := validation_error, kind := validation_error,
reason := integrity_validation_failure, reason := #{error := Error}
result := _,
validation_name := Reason
} }
]} ]}
). ).
@ -374,7 +372,7 @@ authn_validations_test() ->
Conf2 = <<BaseConf/binary, DisableSSLWithHttps/binary>>, Conf2 = <<BaseConf/binary, DisableSSLWithHttps/binary>>,
{ok, ConfMap2} = hocon:binary(Conf2, #{format => richmap}), {ok, ConfMap2} = hocon:binary(Conf2, #{format => richmap}),
?assertThrow( ?assertThrow(
?ERROR(check_http_ssl_opts), ?ERROR(invalid_ssl_opts),
hocon_tconf:map_translate(emqx_conf_schema, ConfMap2, #{format => richmap}) hocon_tconf:map_translate(emqx_conf_schema, ConfMap2, #{format => richmap})
), ),

View File

@ -68,11 +68,11 @@ init_per_suite(Config) ->
emqx_config:erase(gateway), emqx_config:erase(gateway),
emqx_gateway_test_utils:load_all_gateway_apps(), emqx_gateway_test_utils:load_all_gateway_apps(),
init_gateway_conf(), init_gateway_conf(),
emqx_mgmt_api_test_util:init_suite([
emqx_conf, emqx_auth, emqx_auth_http, emqx_gateway
]),
meck:new(emqx_authz_file, [non_strict, passthrough, no_history, no_link]), meck:new(emqx_authz_file, [non_strict, passthrough, no_history, no_link]),
meck:expect(emqx_authz_file, create, fun(S) -> S end), meck:expect(emqx_authz_file, create, fun(S) -> S end),
emqx_mgmt_api_test_util:init_suite([
emqx_conf, emqx_auth, emqx_auth_file, emqx_auth_http, emqx_gateway
]),
application:ensure_all_started(cowboy), application:ensure_all_started(cowboy),
emqx_gateway_auth_ct:start(), emqx_gateway_auth_ct:start(),
Config. Config.
@ -83,7 +83,7 @@ end_per_suite(Config) ->
ok = emqx_authz_test_lib:restore_authorizers(), ok = emqx_authz_test_lib:restore_authorizers(),
emqx_config:erase(gateway), emqx_config:erase(gateway),
emqx_mgmt_api_test_util:end_suite([ emqx_mgmt_api_test_util:end_suite([
emqx_gateway, emqx_auth_http, emqx_auth_file, emqx_auth, emqx_conf emqx_gateway, emqx_auth_http, emqx_auth, emqx_conf
]), ]),
Config. Config.

View File

@ -135,13 +135,13 @@ init_per_suite(Config) ->
%% load application first for minirest api searching %% load application first for minirest api searching
application:load(emqx_gateway), application:load(emqx_gateway),
application:load(emqx_gateway_lwm2m), application:load(emqx_gateway_lwm2m),
emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_authn]), emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_auth]),
Config. Config.
end_per_suite(Config) -> end_per_suite(Config) ->
timer:sleep(300), timer:sleep(300),
{ok, _} = emqx_conf:remove([<<"gateway">>, <<"lwm2m">>], #{}), {ok, _} = emqx_conf:remove([<<"gateway">>, <<"lwm2m">>], #{}),
emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_authn]), emqx_mgmt_api_test_util:end_suite([emqx_conf, emqx_auth]),
Config. Config.
init_per_testcase(TestCase, Config) -> init_per_testcase(TestCase, Config) ->

View File

@ -23,6 +23,7 @@
-export([ -export([
fields/1, fields/1,
desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
@ -30,16 +31,16 @@
refs() -> [?R_REF(gcp_device)]. refs() -> [?R_REF(gcp_device)].
select_union_member(#{<<"mechanism">> := ?AUTHN_MECHANISM_BIN}) -> select_union_member(#{<<"mechanism">> := ?AUTHN_MECHANISM_BIN}) ->
[refs()]; refs();
select_union_member(_Value) -> select_union_member(_Value) ->
undefined. undefined.
fields(gcp_device) -> fields(gcp_device) ->
[ [
{mechanism, emqx_authn_schema:mechanism('gcp_device')} {mechanism, emqx_authn_schema:mechanism(gcp_device)}
] ++ emqx_authn_schema:common_fields(). ] ++ emqx_authn_schema:common_fields().
% desc(gcp_device) -> desc(gcp_device) ->
% ?DESC(emqx_gcp_device_api, gcp_device); ?DESC(emqx_gcp_device_api, gcp_device);
% desc(_) -> desc(_) ->
% undefined. undefined.

View File

@ -49,7 +49,6 @@
emqx_resource, emqx_resource,
emqx_connector, emqx_connector,
emqx_auth, emqx_auth,
emqx_auth_file,
emqx_auth_http, emqx_auth_http,
emqx_auth_jwt, emqx_auth_jwt,
emqx_auth_mnesia, emqx_auth_mnesia,

View File

@ -170,14 +170,15 @@ is_app(Name) ->
end. end.
sorted_reboot_apps() -> sorted_reboot_apps() ->
Apps0 = [{App, app_deps(App)} || App <- reboot_apps()], RebootApps = reboot_apps(),
Apps0 = [{App, app_deps(App, RebootApps)} || App <- RebootApps],
Apps = inject_bridge_deps(Apps0), Apps = inject_bridge_deps(Apps0),
sorted_reboot_apps(Apps). sorted_reboot_apps(Apps).
app_deps(App) -> app_deps(App, RebootApps) ->
case application:get_key(App, applications) of case application:get_key(App, applications) of
undefined -> undefined; undefined -> undefined;
{ok, List} -> lists:filter(fun(A) -> lists:member(A, reboot_apps()) end, List) {ok, List} -> lists:filter(fun(A) -> lists:member(A, RebootApps) end, List)
end. end.
%% `emqx_bridge' is special in that it needs all the bridges apps to %% `emqx_bridge' is special in that it needs all the bridges apps to

View File

@ -439,7 +439,6 @@ apps_to_start() ->
emqx_management, emqx_management,
emqx_dashboard, emqx_dashboard,
emqx_auth, emqx_auth,
emqx_auth_file,
emqx_auth_http, emqx_auth_http,
emqx_auth_jwt, emqx_auth_jwt,
emqx_auth_mnesia, emqx_auth_mnesia,

View File

@ -60,7 +60,7 @@ init_per_suite(Config) ->
ok = emqx_common_test_helpers:load_config(emqx_slow_subs_schema, ?CONF_DEFAULT), ok = emqx_common_test_helpers:load_config(emqx_slow_subs_schema, ?CONF_DEFAULT),
emqx_mgmt_api_test_util:init_suite([emqx_slow_subs]), emqx_mgmt_api_test_util:init_suite([emqx_slow_subs]),
{ok, _} = application:ensure_all_started(emqx_authn), {ok, _} = application:ensure_all_started(emqx_auth),
Config. Config.
end_per_suite(Config) -> end_per_suite(Config) ->
@ -69,7 +69,7 @@ end_per_suite(Config) ->
mria_mnesia:delete_schema(), mria_mnesia:delete_schema(),
meck:unload(emqx_alarm), meck:unload(emqx_alarm),
application:stop(emqx_authn), application:stop(emqx_auth),
emqx_mgmt_api_test_util:end_suite([emqx_slow_subs]), emqx_mgmt_api_test_util:end_suite([emqx_slow_subs]),
Config. Config.

View File

@ -58,7 +58,7 @@ init_per_suite(Config) ->
emqx_authz_file, emqx_authz_file,
acl_conf_file, acl_conf_file,
fun() -> fun() ->
emqx_common_test_helpers:deps_path(emqx_auth_file, "etc/acl.conf") emqx_common_test_helpers:deps_path(emqx_auth, "etc/acl.conf")
end end
), ),
ok = emqx_common_test_helpers:load_config(emqx_modules_schema, ?MODULES_CONF), ok = emqx_common_test_helpers:load_config(emqx_modules_schema, ?MODULES_CONF),

View File

@ -32,7 +32,7 @@ init_per_suite(Config) ->
ok = emqx_common_test_helpers:load_config(emqx_modules_schema, ?BASE_CONF), ok = emqx_common_test_helpers:load_config(emqx_modules_schema, ?BASE_CONF),
ok = emqx_common_test_helpers:load_config(emqx_telemetry_schema, ?BASE_CONF), ok = emqx_common_test_helpers:load_config(emqx_telemetry_schema, ?BASE_CONF),
ok = emqx_mgmt_api_test_util:init_suite( ok = emqx_mgmt_api_test_util:init_suite(
[emqx_conf, emqx_auth, emqx_auth_file, emqx_management, emqx_telemetry], [emqx_conf, emqx_auth, emqx_management, emqx_telemetry],
fun set_special_configs/1 fun set_special_configs/1
), ),
@ -48,7 +48,7 @@ end_per_suite(_Config) ->
} }
), ),
emqx_mgmt_api_test_util:end_suite([ emqx_mgmt_api_test_util:end_suite([
emqx_conf, emqx_auth, emqx_auth_file, emqx_management, emqx_telemetry emqx_conf, emqx_auth, emqx_management, emqx_telemetry
]), ]),
ok. ok.

2
dev
View File

@ -330,7 +330,7 @@ EOF
# copy cert files and acl.conf to etc # copy cert files and acl.conf to etc
copy_other_conf_files() { copy_other_conf_files() {
cp -r apps/emqx/etc/certs "$EMQX_ETC_DIR"/ cp -r apps/emqx/etc/certs "$EMQX_ETC_DIR"/
cp apps/emqx_auth_file/etc/acl.conf "$EMQX_ETC_DIR"/ cp apps/emqx_auth/etc/acl.conf "$EMQX_ETC_DIR"/
} }
is_current_profile_app() { is_current_profile_app() {

View File

@ -535,7 +535,7 @@ defmodule EMQXUmbrella.MixProject do
) )
Mix.Generator.copy_file( Mix.Generator.copy_file(
"apps/emqx_auth_file/etc/acl.conf", "apps/emqx_auth/etc/acl.conf",
Path.join(etc, "acl.conf"), Path.join(etc, "acl.conf"),
force: overwrite? force: overwrite?
) )

View File

@ -108,6 +108,7 @@ is_community_umbrella_app("apps/emqx_enterprise") -> false;
is_community_umbrella_app("apps/emqx_bridge_kinesis") -> false; is_community_umbrella_app("apps/emqx_bridge_kinesis") -> false;
is_community_umbrella_app("apps/emqx_bridge_azure_event_hub") -> false; is_community_umbrella_app("apps/emqx_bridge_azure_event_hub") -> false;
is_community_umbrella_app("apps/emqx_ldap") -> false; is_community_umbrella_app("apps/emqx_ldap") -> false;
is_community_umbrella_app("apps/emqx_auth_ldap") -> false;
is_community_umbrella_app("apps/emqx_gcp_device") -> false; is_community_umbrella_app("apps/emqx_gcp_device") -> false;
is_community_umbrella_app("apps/emqx_dashboard_rbac") -> false; is_community_umbrella_app("apps/emqx_dashboard_rbac") -> false;
is_community_umbrella_app("apps/emqx_dashboard_sso") -> false; is_community_umbrella_app("apps/emqx_dashboard_sso") -> false;
@ -455,7 +456,7 @@ relx_overlay(ReleaseType, Edition) ->
{copy, "bin/emqx_ctl", "bin/emqx_ctl-{{release_version}}"}, {copy, "bin/emqx_ctl", "bin/emqx_ctl-{{release_version}}"},
{copy, "bin/install_upgrade.escript", "bin/install_upgrade.escript-{{release_version}}"}, {copy, "bin/install_upgrade.escript", "bin/install_upgrade.escript-{{release_version}}"},
{copy, "apps/emqx_gateway_lwm2m/lwm2m_xml", "etc/lwm2m_xml"}, {copy, "apps/emqx_gateway_lwm2m/lwm2m_xml", "etc/lwm2m_xml"},
{copy, "apps/emqx_auth_file/etc/acl.conf", "etc/acl.conf"}, {copy, "apps/emqx_auth/etc/acl.conf", "etc/acl.conf"},
{template, "bin/emqx.cmd", "bin/emqx.cmd"}, {template, "bin/emqx.cmd", "bin/emqx.cmd"},
{template, "bin/emqx_ctl.cmd", "bin/emqx_ctl.cmd"}, {template, "bin/emqx_ctl.cmd", "bin/emqx_ctl.cmd"},
{copy, "bin/nodetool", "bin/nodetool"}, {copy, "bin/nodetool", "bin/nodetool"},