diff --git a/Makefile b/Makefile
index e381db3ed..52e4f3ffc 100644
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,7 @@ APPS=$(shell $(CURDIR)/scripts/find-apps.sh)
## app/name-ct targets are intended for local tests hence cover is not enabled
.PHONY: $(APPS:%=%-ct)
define gen-app-ct-target
-$1-ct:
+$1-ct: conf-segs
$(REBAR) ct --name $(CT_NODE_NAME) -v --suite $(shell $(CURDIR)/scripts/find-suites.sh $1)
endef
$(foreach app,$(APPS),$(eval $(call gen-app-ct-target,$(app))))
diff --git a/apps/emqx/include/emqx_authentication.hrl b/apps/emqx/include/emqx_authentication.hrl
new file mode 100644
index 000000000..948842433
--- /dev/null
+++ b/apps/emqx/include/emqx_authentication.hrl
@@ -0,0 +1,31 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 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.
+%%--------------------------------------------------------------------
+
+-ifndef(EMQX_AUTHENTICATION_HRL).
+-define(EMQX_AUTHENTICATION_HRL, true).
+
+%% config root name all auth providers have to agree on.
+-define(EMQX_AUTHENTICATION_CONFIG_ROOT_NAME, "authentication").
+-define(EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_ATOM, authentication).
+-define(EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_BINARY, <<"authentication">>).
+
+%% key to a persistent term which stores a module name in order to inject
+%% schema module at run-time to keep emqx app's compile time purity.
+%% see emqx_schema.erl for more details
+%% and emqx_conf_schema for an examples
+-define(EMQX_AUTHENTICATION_SCHEMA_MODULE_PT_KEY, emqx_authentication_schema_module).
+
+-endif.
diff --git a/apps/emqx/rebar.config b/apps/emqx/rebar.config
index 59c5cf045..5adcbd3bb 100644
--- a/apps/emqx/rebar.config
+++ b/apps/emqx/rebar.config
@@ -17,7 +17,7 @@
, {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.9.0"}}}
, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.11.1"}}}
, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "2.5.1"}}}
- , {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.20.6"}}}
+ , {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.22.0"}}}
, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}}
, {recon, {git, "https://github.com/ferd/recon", {tag, "2.5.1"}}}
, {snabbkaffe, {git, "https://github.com/kafka4beam/snabbkaffe.git", {tag, "0.15.0"}}}
diff --git a/apps/emqx/src/emqx_access_control.erl b/apps/emqx/src/emqx_access_control.erl
index 914651535..35b3767e0 100644
--- a/apps/emqx/src/emqx_access_control.erl
+++ b/apps/emqx/src/emqx_access_control.erl
@@ -63,4 +63,5 @@ do_authorize(ClientInfo, PubSub, Topic) ->
-compile({inline, [run_hooks/3]}).
run_hooks(Name, Args, Acc) ->
- ok = emqx_metrics:inc(Name), emqx_hooks:run_fold(Name, Args, Acc).
+ ok = emqx_metrics:inc(Name),
+ emqx_hooks:run_fold(Name, Args, Acc).
diff --git a/apps/emqx/src/emqx_authentication.erl b/apps/emqx/src/emqx_authentication.erl
index 77a5e2cee..1607497da 100644
--- a/apps/emqx/src/emqx_authentication.erl
+++ b/apps/emqx/src/emqx_authentication.erl
@@ -24,9 +24,12 @@
-include("emqx.hrl").
-include("logger.hrl").
+-include("emqx_authentication.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
+-define(CONF_ROOT, ?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME_ATOM).
+
%% The authentication entrypoint.
-export([ authenticate/2
]).
@@ -383,8 +386,8 @@ list_users(ChainName, AuthenticatorID, Params) ->
%%--------------------------------------------------------------------
init(_Opts) ->
- ok = emqx_config_handler:add_handler([authentication], ?MODULE),
- ok = emqx_config_handler:add_handler([listeners, '?', '?', authentication], ?MODULE),
+ ok = emqx_config_handler:add_handler([?CONF_ROOT], ?MODULE),
+ ok = emqx_config_handler:add_handler([listeners, '?', '?', ?CONF_ROOT], ?MODULE),
{ok, #{hooked => false, providers => #{}}}.
handle_call(get_providers, _From, #{providers := Providers} = State) ->
@@ -496,8 +499,8 @@ terminate(Reason, _State) ->
Other -> ?SLOG(error, #{msg => "emqx_authentication_terminating",
reason => Other})
end,
- emqx_config_handler:remove_handler([authentication]),
- emqx_config_handler:remove_handler([listeners, '?', '?', authentication]),
+ emqx_config_handler:remove_handler([?CONF_ROOT]),
+ emqx_config_handler:remove_handler([listeners, '?', '?', ?CONF_ROOT]),
ok.
code_change(_OldVsn, State, _Extra) ->
diff --git a/apps/emqx/src/emqx_authentication_config.erl b/apps/emqx/src/emqx_authentication_config.erl
index a7fa5673a..795dd060e 100644
--- a/apps/emqx/src/emqx_authentication_config.erl
+++ b/apps/emqx/src/emqx_authentication_config.erl
@@ -34,6 +34,7 @@
-export_type([config/0]).
-include("logger.hrl").
+-include("emqx_authentication.hrl").
-type parsed_config() :: #{mechanism := atom(),
backend => atom(),
@@ -132,9 +133,9 @@ do_post_config_update({move_authenticator, ChainName, AuthenticatorID, Position}
check_configs(Configs) ->
Providers = emqx_authentication:get_providers(),
- lists:map(fun(C) -> do_check_conifg(C, Providers) end, Configs).
+ lists:map(fun(C) -> do_check_config(C, Providers) end, Configs).
-do_check_conifg(Config, Providers) ->
+do_check_config(Config, Providers) ->
Type = authn_type(Config),
case maps:get(Type, Providers, false) of
false ->
@@ -143,19 +144,20 @@ do_check_conifg(Config, Providers) ->
providers => Providers}),
throw({unknown_authn_type, Type});
Module ->
- do_check_conifg(Type, Config, Module)
+ do_check_config(Type, Config, Module)
end.
-do_check_conifg(Type, Config, Module) ->
+do_check_config(Type, Config, Module) ->
F = case erlang:function_exported(Module, check_config, 1) of
true ->
fun Module:check_config/1;
false ->
fun(C) ->
- #{config := R} =
- hocon_schema:check_plain(Module, #{<<"config">> => C},
+ Key = list_to_binary(?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME),
+ AtomKey = list_to_atom(?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME),
+ R = hocon_schema:check_plain(Module, #{Key => C},
#{atom_key => true}),
- R
+ maps:get(AtomKey, R)
end
end,
try
@@ -261,8 +263,8 @@ authn_type(#{mechanism := M}) -> atom(M);
authn_type(#{<<"mechanism">> := M, <<"backend">> := B}) -> {atom(M), atom(B)};
authn_type(#{<<"mechanism">> := M}) -> atom(M).
-atom(Bin) ->
- binary_to_existing_atom(Bin, utf8).
+atom(A) when is_atom(A) -> A;
+atom(Bin) -> binary_to_existing_atom(Bin, utf8).
%% The relative dir for ssl files.
certs_dir(ChainName, ConfigOrID) ->
diff --git a/apps/emqx/src/emqx_config.erl b/apps/emqx/src/emqx_config.erl
index 8806d4bc3..9979629bf 100644
--- a/apps/emqx/src/emqx_config.erl
+++ b/apps/emqx/src/emqx_config.erl
@@ -268,23 +268,39 @@ init_load(SchemaMod, Conf) when is_list(Conf) orelse is_binary(Conf) ->
}),
error(failed_to_load_hocon_conf)
end;
-init_load(SchemaMod, RawConf0) when is_map(RawConf0) ->
+init_load(SchemaMod, RawConf) when is_map(RawConf) ->
ok = save_schema_mod_and_names(SchemaMod),
- %% check and save configs
- {_AppEnvs, CheckedConf} = check_config(SchemaMod, RawConf0),
+ %% check configs agains the schema, with environment variables applied on top
+ {_AppEnvs, CheckedConf} =
+ check_config(SchemaMod, RawConf, #{apply_override_envs => true}),
+ %% fill default values for raw config
+ RawConfWithEnvs = merge_envs(SchemaMod, RawConf),
+ RootNames = get_root_names(),
ok = save_to_config_map(maps:with(get_atom_root_names(), CheckedConf),
- maps:with(get_root_names(), RawConf0)).
+ maps:with(RootNames, RawConfWithEnvs)).
include_dirs() ->
[filename:join(emqx:data_dir(), "configs")].
+merge_envs(SchemaMod, RawConf) ->
+ Opts = #{logger => fun(_, _) -> ok end, %% everything should have been logged already when check_config
+ nullable => true, %% TODO: evil, remove, nullable should be declared in schema
+ format => map,
+ apply_override_envs => true
+ },
+ hocon_schema:merge_env_overrides(SchemaMod, RawConf, all, Opts).
+
-spec check_config(module(), raw_config()) -> {AppEnvs, CheckedConf}
when AppEnvs :: app_envs(), CheckedConf :: config().
check_config(SchemaMod, RawConf) ->
- Opts = #{return_plain => true,
- nullable => true,
- format => map
- },
+ check_config(SchemaMod, RawConf, #{}).
+
+check_config(SchemaMod, RawConf, Opts0) ->
+ Opts1 = #{return_plain => true,
+ nullable => true, %% TODO: evil, remove, nullable should be declared in schema
+ format => map
+ },
+ Opts = maps:merge(Opts0, Opts1),
{AppEnvs, CheckedConf} =
hocon_schema:map_translate(SchemaMod, RawConf, Opts),
{AppEnvs, emqx_map_lib:unsafe_atom_key_map(CheckedConf)}.
@@ -312,13 +328,15 @@ read_override_conf(#{} = Opts) ->
File = override_conf_file(Opts),
load_hocon_file(File, map).
-override_conf_file(Opts) ->
+override_conf_file(Opts) when is_map(Opts) ->
Key =
case maps:get(override_to, Opts, local) of
local -> local_override_conf_file;
cluster -> cluster_override_conf_file
end,
- application:get_env(emqx, Key, undefined).
+ application:get_env(emqx, Key, undefined);
+override_conf_file(Which) when is_atom(Which) ->
+ application:get_env(emqx, Which, undefined).
-spec save_schema_mod_and_names(module()) -> ok.
save_schema_mod_and_names(SchemaMod) ->
diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl
index e470ff478..1c471da90 100644
--- a/apps/emqx/src/emqx_schema.erl
+++ b/apps/emqx/src/emqx_schema.erl
@@ -22,6 +22,7 @@
-dialyzer(no_unused).
-dialyzer(no_fail_call).
+-include("emqx_authentication.hrl").
-include_lib("typerefl/include/types.hrl").
-type duration() :: integer().
@@ -105,11 +106,29 @@ and can not be deleted."""
The configs here work as default values which can be overriden
in zone
configs"""
})}
- , {"authentication",
+ , {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME,
authentication(
-"""Default authentication configs for all MQTT listeners.
+"""Default authentication configs for all MQTT listeners.
+
For per-listener overrides see authentication
-in listener configs""")}
+in listener configs
+
+
+EMQ X can be configured with:
+
+
[]
: The default value, it allows *ALL* logins{enable:true,backend:\"built-in-database\",mechanism=\"password-based\"}
\"TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256\"
or
-[\"TLS_AES_256_GCM_SHA384\",\"TLS_AES_128_GCM_SHA256\"]
[\"TLS_AES_256_GCM_SHA384\",\"TLS_AES_128_GCM_SHA256\"].
false
to disable this auth provider";
enable(_) -> undefined.
authenticator_type() ->
@@ -42,3 +45,18 @@ authenticator_type() ->
config_refs(Modules) ->
lists:append([Module:refs() || Module <- Modules]).
+
+%% authn is a core functionality however implemented outside fo emqx app
+%% in emqx_schema, 'authentication' is a map() type which is to allow
+%% EMQ X more plugable.
+root_type() ->
+ T = authenticator_type(),
+ hoconsc:union([T, hoconsc:array(T)]).
+
+mechanism(Name) ->
+ hoconsc:mk(hoconsc:enum([Name]),
+ #{nullable => false}).
+
+backend(Name) ->
+ hoconsc:mk(hoconsc:enum([Name]),
+ #{nullable => false}).
diff --git a/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl b/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl
index f02655462..3604455dc 100644
--- a/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl
+++ b/apps/emqx_authn/src/enhanced_authn/emqx_enhanced_authn_scram_mnesia.erl
@@ -83,11 +83,11 @@ mnesia(boot) ->
namespace() -> "authn-scram-builtin_db".
-roots() -> [config].
+roots() -> [?CONF_NS].
-fields(config) ->
- [ {mechanism, {enum, [scram]}}
- , {backend, {enum, ['built-in-database']}}
+fields(?CONF_NS) ->
+ [ {mechanism, emqx_authn_schema:mechanism('scram')}
+ , {backend, emqx_authn_schema:backend('built-in-database')}
, {algorithm, fun algorithm/1}
, {iteration_count, fun iteration_count/1}
] ++ emqx_authn_schema:common_fields().
@@ -105,7 +105,7 @@ iteration_count(_) -> undefined.
%%------------------------------------------------------------------------------
refs() ->
- [hoconsc:ref(?MODULE, config)].
+ [hoconsc:ref(?MODULE, ?CONF_NS)].
create(AuthenticatorID,
#{algorithm := Algorithm,
diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl
index 829ce2282..533301ea7 100644
--- a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl
+++ b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl
@@ -43,8 +43,9 @@
namespace() -> "authn-http".
roots() ->
- [ {config, hoconsc:mk(hoconsc:union(refs()),
- #{})}
+ [ {?CONF_NS,
+ hoconsc:mk(hoconsc:union(refs()),
+ #{})}
].
fields(get) ->
@@ -60,8 +61,8 @@ fields(post) ->
] ++ common_fields().
common_fields() ->
- [ {mechanism, hoconsc:enum(['password-based'])}
- , {backend, hoconsc:enum(['http'])}
+ [ {mechanism, emqx_authn_schema:mechanism('password-based')}
+ , {backend, emqx_authn_schema:backend(http)}
, {url, fun url/1}
, {body, fun body/1}
, {request_timeout, fun request_timeout/1}
@@ -233,9 +234,9 @@ transform_header_name(Headers) ->
end, #{}, Headers).
check_ssl_opts(Conf) ->
- case parse_url(hocon_schema:get_value("config.url", Conf)) of
+ case parse_url(get_conf_val("url", Conf)) of
#{scheme := https} ->
- case hocon_schema:get_value("config.ssl.enable", Conf) of
+ case get_conf_val("ssl.enable", Conf) of
true -> ok;
false -> false
end;
@@ -244,8 +245,8 @@ check_ssl_opts(Conf) ->
end.
check_headers(Conf) ->
- Method = to_bin(hocon_schema:get_value("config.method", Conf)),
- Headers = hocon_schema:get_value("config.headers", Conf),
+ Method = to_bin(get_conf_val("method", Conf)),
+ Headers = get_conf_val("headers", Conf),
Method =:= <<"post">> orelse (not maps:is_key(<<"content-type">>, Headers)).
parse_url(URL) ->
@@ -340,3 +341,6 @@ to_bin(B) when is_binary(B) ->
B;
to_bin(L) when is_list(L) ->
list_to_binary(L).
+
+get_conf_val(Name, Conf) ->
+ hocon_schema:get_value(?CONF_NS ++ "." ++ Name, Conf).
diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl
index 916911ffa..9295e5c7e 100644
--- a/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl
+++ b/apps/emqx_authn/src/simple_authn/emqx_authn_jwt.erl
@@ -16,6 +16,7 @@
-module(emqx_authn_jwt).
+-include("emqx_authn.hrl").
-include_lib("typerefl/include/types.hrl").
-behaviour(hocon_schema).
@@ -40,9 +41,9 @@
namespace() -> "authn-jwt".
roots() ->
- [ {config, hoconsc:mk(hoconsc:union(refs()),
- #{}
- )}
+ [ {?CONF_NS,
+ hoconsc:mk(hoconsc:union(refs()),
+ #{})}
].
fields('hmac-based') ->
@@ -82,7 +83,7 @@ fields(ssl_disable) ->
[ {enable, #{type => false}} ].
common_fields() ->
- [ {mechanism, {enum, [jwt]}}
+ [ {mechanism, emqx_authn_schema:mechanism('jwt')}
, {verify_claims, fun verify_claims/1}
] ++ emqx_authn_schema:common_fields().
diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl
index fd02671fb..f609d8cac 100644
--- a/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl
+++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mnesia.erl
@@ -85,11 +85,11 @@ mnesia(boot) ->
namespace() -> "authn-builtin_db".
-roots() -> [config].
+roots() -> [?CONF_NS].
-fields(config) ->
- [ {mechanism, {enum, ['password-based']}}
- , {backend, {enum, ['built-in-database']}}
+fields(?CONF_NS) ->
+ [ {mechanism, emqx_authn_schema:mechanism('password-based')}
+ , {backend, emqx_authn_schema:backend('built-in-database')}
, {user_id_type, fun user_id_type/1}
, {password_hash_algorithm, fun password_hash_algorithm/1}
] ++ emqx_authn_schema:common_fields();
@@ -104,7 +104,7 @@ fields(other_algorithms) ->
].
user_id_type(type) -> user_id_type();
-user_id_type(default) -> username;
+user_id_type(default) -> <<"username">>;
user_id_type(_) -> undefined.
password_hash_algorithm(type) -> hoconsc:union([hoconsc:ref(?MODULE, bcrypt),
@@ -121,7 +121,7 @@ salt_rounds(_) -> undefined.
%%------------------------------------------------------------------------------
refs() ->
- [hoconsc:ref(?MODULE, config)].
+ [hoconsc:ref(?MODULE, ?CONF_NS)].
create(AuthenticatorID,
#{user_id_type := Type,
diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl
index 2deef8506..3b47bcd7b 100644
--- a/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl
+++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mongodb.erl
@@ -42,8 +42,8 @@
namespace() -> "authn-mongodb".
roots() ->
- [ {config, hoconsc:mk(hoconsc:union(refs()),
- #{})}
+ [ {?CONF_NS, hoconsc:mk(hoconsc:union(refs()),
+ #{})}
].
fields(standalone) ->
@@ -56,8 +56,8 @@ fields('sharded-cluster') ->
common_fields() ++ emqx_connector_mongo:fields(sharded).
common_fields() ->
- [ {mechanism, {enum, ['password-based']}}
- , {backend, {enum, [mongodb]}}
+ [ {mechanism, emqx_authn_schema:mechanism('password-based')}
+ , {backend, emqx_authn_schema:backend(mongodb)}
, {collection, fun collection/1}
, {selector, fun selector/1}
, {password_hash_field, fun password_hash_field/1}
diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl
index 47ca0ae3c..fd0d09f57 100644
--- a/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl
+++ b/apps/emqx_authn/src/simple_authn/emqx_authn_mysql.erl
@@ -41,11 +41,11 @@
namespace() -> "authn-mysql".
-roots() -> [config].
+roots() -> [?CONF_NS].
-fields(config) ->
- [ {mechanism, {enum, ['password-based']}}
- , {backend, {enum, [mysql]}}
+fields(?CONF_NS) ->
+ [ {mechanism, emqx_authn_schema:mechanism('password-based')}
+ , {backend, emqx_authn_schema:backend(mysql)}
, {password_hash_algorithm, fun password_hash_algorithm/1}
, {salt_position, fun salt_position/1}
, {query, fun query/1}
@@ -74,7 +74,7 @@ query_timeout(_) -> undefined.
%%------------------------------------------------------------------------------
refs() ->
- [hoconsc:ref(?MODULE, config)].
+ [hoconsc:ref(?MODULE, ?CONF_NS)].
create(_AuthenticatorID, Config) ->
create(Config).
diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl
index 660acf566..fdd30b618 100644
--- a/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl
+++ b/apps/emqx_authn/src/simple_authn/emqx_authn_pgsql.erl
@@ -47,11 +47,11 @@
namespace() -> "authn-postgresql".
-roots() -> [config].
+roots() -> [?CONF_NS].
-fields(config) ->
- [ {mechanism, {enum, ['password-based']}}
- , {backend, {enum, [postgresql]}}
+fields(?CONF_NS) ->
+ [ {mechanism, emqx_authn_schema:mechanism('password-based')}
+ , {backend, emqx_authn_schema:backend(postgresql)}
, {password_hash_algorithm, fun password_hash_algorithm/1}
, {salt_position, fun salt_position/1}
, {query, fun query/1}
@@ -75,7 +75,7 @@ query(_) -> undefined.
%%------------------------------------------------------------------------------
refs() ->
- [hoconsc:ref(?MODULE, config)].
+ [hoconsc:ref(?MODULE, ?CONF_NS)].
create(_AuthenticatorID, Config) ->
create(Config).
diff --git a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl
index d238bc537..e17d0ad8f 100644
--- a/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl
+++ b/apps/emqx_authn/src/simple_authn/emqx_authn_redis.erl
@@ -42,8 +42,8 @@
namespace() -> "authn-redis".
roots() ->
- [ {config, hoconsc:mk(hoconsc:union(refs()),
- #{})}
+ [ {?CONF_NS, hoconsc:mk(hoconsc:union(refs()),
+ #{})}
].
fields(standalone) ->
@@ -56,11 +56,11 @@ fields(sentinel) ->
common_fields() ++ emqx_connector_redis:fields(sentinel).
common_fields() ->
- [{mechanism, {enum, ['password-based']}},
- {backend, {enum, [redis]}},
- {cmd, fun cmd/1},
- {password_hash_algorithm, fun password_hash_algorithm/1},
- {salt_position, fun salt_position/1}
+ [ {mechanism, emqx_authn_schema:mechanism('password-based')}
+ , {backend, emqx_authn_schema:backend(redis)}
+ , {cmd, fun cmd/1}
+ , {password_hash_algorithm, fun password_hash_algorithm/1}
+ , {salt_position, fun salt_position/1}
] ++ emqx_authn_schema:common_fields().
cmd(type) -> string();
diff --git a/apps/emqx_authn/test/emqx_authn_api_SUITE.erl b/apps/emqx_authn/test/emqx_authn_api_SUITE.erl
index ba9f4996a..885811fec 100644
--- a/apps/emqx_authn/test/emqx_authn_api_SUITE.erl
+++ b/apps/emqx_authn/test/emqx_authn_api_SUITE.erl
@@ -45,11 +45,11 @@ groups() ->
init_per_testcase(_, Config) ->
{ok, _} = emqx_cluster_rpc:start_link(node(), emqx_cluster_rpc, 1000),
emqx_authn_test_lib:delete_authenticators(
- [authentication],
+ [?CONF_NS_ATOM],
?GLOBAL),
emqx_authn_test_lib:delete_authenticators(
- [listeners, tcp, default, authentication],
+ [listeners, tcp, default, ?CONF_NS_ATOM],
?TCP_DEFAULT),
{atomic, ok} = mria:clear_table(emqx_authn_mnesia),
@@ -89,8 +89,8 @@ set_special_configs(_App) ->
%%------------------------------------------------------------------------------
t_invalid_listener(_) ->
- {ok, 404, _} = request(get, uri(["listeners", "invalid", "authentication"])),
- {ok, 404, _} = request(get, uri(["listeners", "in:valid", "authentication"])).
+ {ok, 404, _} = request(get, uri(["listeners", "invalid", ?CONF_NS])),
+ {ok, 404, _} = request(get, uri(["listeners", "in:valid", ?CONF_NS])).
t_authenticators(_) ->
test_authenticators([]).
@@ -133,86 +133,86 @@ test_authenticators(PathPrefix) ->
ValidConfig = emqx_authn_test_lib:http_example(),
{ok, 200, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
ValidConfig),
{ok, 409, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
ValidConfig),
InvalidConfig0 = ValidConfig#{method => <<"delete">>},
{ok, 400, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
InvalidConfig0),
InvalidConfig1 = ValidConfig#{method => <<"get">>,
headers => #{<<"content-type">> => <<"application/json">>}},
{ok, 400, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
InvalidConfig1),
?assertAuthenticatorsMatch(
[#{<<"mechanism">> := <<"password-based">>, <<"backend">> := <<"http">>}],
- PathPrefix ++ ["authentication"]).
+ PathPrefix ++ [?CONF_NS]).
test_authenticator(PathPrefix) ->
ValidConfig0 = emqx_authn_test_lib:http_example(),
{ok, 200, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
ValidConfig0),
{ok, 200, _} = request(
get,
- uri(PathPrefix ++ ["authentication", "password-based:http"])),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:http"])),
{ok, 404, _} = request(
get,
- uri(PathPrefix ++ ["authentication", "password-based:redis"])),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:redis"])),
{ok, 404, _} = request(
put,
- uri(PathPrefix ++ ["authentication", "password-based:built-in-database"]),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:built-in-database"]),
emqx_authn_test_lib:built_in_database_example()),
InvalidConfig0 = ValidConfig0#{method => <<"delete">>},
{ok, 400, _} = request(
put,
- uri(PathPrefix ++ ["authentication", "password-based:http"]),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:http"]),
InvalidConfig0),
InvalidConfig1 = ValidConfig0#{method => <<"get">>,
headers => #{<<"content-type">> => <<"application/json">>}},
{ok, 400, _} = request(
put,
- uri(PathPrefix ++ ["authentication", "password-based:http"]),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:http"]),
InvalidConfig1),
ValidConfig1 = ValidConfig0#{pool_size => 9},
{ok, 200, _} = request(
put,
- uri(PathPrefix ++ ["authentication", "password-based:http"]),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:http"]),
ValidConfig1),
{ok, 404, _} = request(
delete,
- uri(PathPrefix ++ ["authentication", "password-based:redis"])),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:redis"])),
{ok, 204, _} = request(
delete,
- uri(PathPrefix ++ ["authentication", "password-based:http"])),
+ uri(PathPrefix ++ [?CONF_NS, "password-based:http"])),
- ?assertAuthenticatorsMatch([], PathPrefix ++ ["authentication"]).
+ ?assertAuthenticatorsMatch([], PathPrefix ++ [?CONF_NS]).
test_authenticator_users(PathPrefix) ->
- UsersUri = uri(PathPrefix ++ ["authentication", "password-based:built-in-database", "users"]),
+ UsersUri = uri(PathPrefix ++ [?CONF_NS, "password-based:built-in-database", "users"]),
{ok, 200, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
emqx_authn_test_lib:built_in_database_example()),
InvalidUsers = [
@@ -263,11 +263,11 @@ test_authenticator_users(PathPrefix) ->
lists:usort([ UserId || #{<<"user_id">> := UserId} <- Page1Users ++ Page2Users])).
test_authenticator_user(PathPrefix) ->
- UsersUri = uri(PathPrefix ++ ["authentication", "password-based:built-in-database", "users"]),
+ UsersUri = uri(PathPrefix ++ [?CONF_NS, "password-based:built-in-database", "users"]),
{ok, 200, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
emqx_authn_test_lib:built_in_database_example()),
User = #{user_id => <<"u1">>, password => <<"p1">>},
@@ -311,7 +311,7 @@ test_authenticator_move(PathPrefix) ->
fun(Conf) ->
{ok, 200, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
Conf)
end,
AuthenticatorConfs),
@@ -322,40 +322,40 @@ test_authenticator_move(PathPrefix) ->
#{<<"mechanism">> := <<"jwt">>},
#{<<"mechanism">> := <<"password-based">>, <<"backend">> := <<"built-in-database">>}
],
- PathPrefix ++ ["authentication"]),
+ PathPrefix ++ [?CONF_NS]),
% Invalid moves
{ok, 400, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{position => <<"up">>}),
{ok, 400, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{}),
{ok, 404, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{position => <<"before:invalid">>}),
{ok, 404, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{position => <<"before:password-based:redis">>}),
{ok, 404, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{position => <<"before:password-based:redis">>}),
% Valid moves
{ok, 204, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{position => <<"top">>}),
?assertAuthenticatorsMatch(
@@ -364,11 +364,11 @@ test_authenticator_move(PathPrefix) ->
#{<<"mechanism">> := <<"password-based">>, <<"backend">> := <<"http">>},
#{<<"mechanism">> := <<"password-based">>, <<"backend">> := <<"built-in-database">>}
],
- PathPrefix ++ ["authentication"]),
+ PathPrefix ++ [?CONF_NS]),
{ok, 204, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{position => <<"bottom">>}),
?assertAuthenticatorsMatch(
@@ -377,11 +377,11 @@ test_authenticator_move(PathPrefix) ->
#{<<"mechanism">> := <<"password-based">>, <<"backend">> := <<"built-in-database">>},
#{<<"mechanism">> := <<"jwt">>}
],
- PathPrefix ++ ["authentication"]),
+ PathPrefix ++ [?CONF_NS]),
{ok, 204, _} = request(
post,
- uri(PathPrefix ++ ["authentication", "jwt", "move"]),
+ uri(PathPrefix ++ [?CONF_NS, "jwt", "move"]),
#{position => <<"before:password-based:built-in-database">>}),
?assertAuthenticatorsMatch(
@@ -390,17 +390,17 @@ test_authenticator_move(PathPrefix) ->
#{<<"mechanism">> := <<"jwt">>},
#{<<"mechanism">> := <<"password-based">>, <<"backend">> := <<"built-in-database">>}
],
- PathPrefix ++ ["authentication"]).
+ PathPrefix ++ [?CONF_NS]).
test_authenticator_import_users(PathPrefix) ->
ImportUri = uri(
PathPrefix ++
- ["authentication", "password-based:built-in-database", "import_users"]),
+ [?CONF_NS, "password-based:built-in-database", "import_users"]),
{ok, 200, _} = request(
post,
- uri(PathPrefix ++ ["authentication"]),
+ uri(PathPrefix ++ [?CONF_NS]),
emqx_authn_test_lib:built_in_database_example()),
{ok, 400, _} = request(post, ImportUri, #{}),
diff --git a/apps/emqx_authn/test/emqx_authn_http_SUITE.erl b/apps/emqx_authn/test/emqx_authn_http_SUITE.erl
index 67865d645..2c0716e8b 100644
--- a/apps/emqx_authn/test/emqx_authn_http_SUITE.erl
+++ b/apps/emqx_authn/test/emqx_authn_http_SUITE.erl
@@ -24,7 +24,7 @@
-include_lib("common_test/include/ct.hrl").
-include_lib("emqx/include/emqx_placeholder.hrl").
--define(PATH, [authentication]).
+-define(PATH, [?CONF_NS_ATOM]).
-define(HTTP_PORT, 33333).
-define(HTTP_PATH, "/auth").
diff --git a/apps/emqx_authn/test/emqx_authn_mnesia_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mnesia_SUITE.erl
index 5c6eb694c..53c8016cd 100644
--- a/apps/emqx_authn/test/emqx_authn_mnesia_SUITE.erl
+++ b/apps/emqx_authn/test/emqx_authn_mnesia_SUITE.erl
@@ -49,6 +49,8 @@ end_per_testcase(_Case, Config) ->
%% Tests
%%------------------------------------------------------------------------------
+-define(CONF(Conf), #{?CONF_NS_BINARY => Conf}).
+
t_check_schema(_Config) ->
ConfigOk = #{
<<"mechanism">> => <<"password-based">>,
@@ -60,7 +62,7 @@ t_check_schema(_Config) ->
}
},
- hocon_schema:check_plain(emqx_authn_mnesia, #{<<"config">> => ConfigOk}),
+ hocon_schema:check_plain(emqx_authn_mnesia, ?CONF(ConfigOk)),
ConfigNotOk = #{
<<"mechanism">> => <<"password-based">>,
@@ -74,7 +76,7 @@ t_check_schema(_Config) ->
?assertException(
throw,
{emqx_authn_mnesia, _},
- hocon_schema:check_plain(emqx_authn_mnesia, #{<<"config">> => ConfigNotOk})).
+ hocon_schema:check_plain(emqx_authn_mnesia, ?CONF(ConfigNotOk))).
t_create(_) ->
Config0 = config(),
diff --git a/apps/emqx_authz/test/emqx_authz_mnesia_SUITE.erl b/apps/emqx_authz/test/emqx_authz_mnesia_SUITE.erl
index 49056ed68..2bca1793d 100644
--- a/apps/emqx_authz/test/emqx_authz_mnesia_SUITE.erl
+++ b/apps/emqx_authz/test/emqx_authz_mnesia_SUITE.erl
@@ -31,7 +31,7 @@ groups() ->
init_per_suite(Config) ->
ok = emqx_common_test_helpers:start_apps(
- [emqx_conf, emqx_authz],
+ [emqx_connector, emqx_conf, emqx_authz],
fun set_special_configs/1
),
Config.
diff --git a/apps/emqx_bridge/src/emqx_bridge_api.erl b/apps/emqx_bridge/src/emqx_bridge_api.erl
index 417fa49f7..6e274903e 100644
--- a/apps/emqx_bridge/src/emqx_bridge_api.erl
+++ b/apps/emqx_bridge/src/emqx_bridge_api.erl
@@ -33,7 +33,7 @@
catch
error:{invalid_bridge_id, Id0} ->
{400, #{code => 'INVALID_ID', message => <<"invalid_bridge_id: ", Id0/binary,
- ". Bridge Ids must be of format authentication
in listener configs"""
- }).
+ }).
gateway_common_options() ->
[ {enable,
@@ -464,7 +449,7 @@ it has two purposes:
sc(ref(clientinfo_override),
#{ desc => ""
})}
- , {authentication, authentication()}
+ , {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME, authentication_schema()}
].
common_listener_opts() ->
@@ -483,7 +468,7 @@ common_listener_opts() ->
sc(integer(),
#{ default => 1000
})}
- , {authentication, authentication()}
+ , {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME, authentication_schema()}
, {mountpoint,
sc(binary(),
#{ default => undefined
diff --git a/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl b/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl
index e49a78e73..8e25a4e6e 100644
--- a/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl
+++ b/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl
@@ -28,6 +28,8 @@
-include_lib("eunit/include/eunit.hrl").
+%% this parses to #{}, will not cause config cleanup
+%% so we will need call emqx_config:erase
-define(CONF_DEFAULT, <<"
gateway {}
">>).
@@ -39,6 +41,7 @@ gateway {}
all() -> emqx_common_test_helpers:all(?MODULE).
init_per_suite(Conf) ->
+ emqx_config:erase(gateway),
emqx_config:init_load(emqx_gateway_schema, ?CONF_DEFAULT),
emqx_mgmt_api_test_util:init_suite([emqx_conf, emqx_authn, emqx_gateway]),
Conf.
diff --git a/apps/emqx_modules/test/emqx_rewrite_SUITE.erl b/apps/emqx_modules/test/emqx_rewrite_SUITE.erl
index 713468460..27093ef1d 100644
--- a/apps/emqx_modules/test/emqx_rewrite_SUITE.erl
+++ b/apps/emqx_modules/test/emqx_rewrite_SUITE.erl
@@ -170,9 +170,9 @@ t_update_re_failed(_Config) ->
{error,
{emqx_modules_schema,
[{validation_error,
- #{array_index => 1,path => "rewrite.re",
- reason => {<<"*^test/*">>,{"nothing to repeat",0}},
- value => <<"*^test/*">>}}]}}},
+ #{path => "rewrite.1.re",
+ reason => {<<"*^test/*">>,{"nothing to repeat",0}},
+ value => <<"*^test/*">>}}]}}},
?assertError(Error, emqx_rewrite:update(Rules)),
ok.
diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl
index 8daae99b5..995044fc7 100644
--- a/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl
+++ b/apps/emqx_rule_engine/src/emqx_rule_engine_schema.erl
@@ -56,7 +56,7 @@ A list of outputs of the rule.