fix(schema): add namespace to authn schemas

This commit is contained in:
Zaiming (Stone) Shi 2023-11-10 09:33:15 +01:00
parent 86110824eb
commit f1de0aa176
14 changed files with 71 additions and 42 deletions

View File

@ -38,7 +38,8 @@
authenticator_type_without/1, authenticator_type_without/1,
authenticator_type_without/2, authenticator_type_without/2,
mechanism/1, mechanism/1,
backend/1 backend/1,
namespace/0
]). ]).
-export([ -export([
@ -60,6 +61,7 @@
api_write api_write
%% config: schema for config validation %% config: schema for config validation
| config. | config.
-callback namespace() -> string().
-callback refs() -> [schema_ref()]. -callback refs() -> [schema_ref()].
-callback refs(shema_kind()) -> [schema_ref()]. -callback refs(shema_kind()) -> [schema_ref()].
-callback select_union_member(emqx_config:raw_config()) -> [schema_ref()] | undefined | no_return(). -callback select_union_member(emqx_config:raw_config()) -> [schema_ref()] | undefined | no_return().
@ -74,6 +76,8 @@
refs/1 refs/1
]). ]).
namespace() -> "authn".
roots() -> []. roots() -> [].
injected_fields(AuthnSchemaMods) -> injected_fields(AuthnSchemaMods) ->

View File

@ -22,6 +22,7 @@
-define(ERR(Reason), {error, Reason}). -define(ERR(Reason), {error, Reason}).
union_member_selector_mongo_test_() -> union_member_selector_mongo_test_() ->
ok = ensure_schema_load(),
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
@ -31,25 +32,26 @@ union_member_selector_mongo_test_() ->
end}, end},
{"single", fun() -> {"single", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "mongo_single"}), ?ERR(#{matched_type := "authn:mongo_single"}),
check("{mechanism = password_based, backend = mongodb, 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 := "mongo_rs"}), ?ERR(#{matched_type := "authn:mongo_rs"}),
check("{mechanism = password_based, backend = mongodb, mongo_type = rs}") check("{mechanism = password_based, backend = mongodb, mongo_type = rs}")
) )
end}, end},
{"sharded", fun() -> {"sharded", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "mongo_sharded"}), ?ERR(#{matched_type := "authn:mongo_sharded"}),
check("{mechanism = password_based, backend = mongodb, mongo_type = sharded}") check("{mechanism = password_based, backend = mongodb, mongo_type = sharded}")
) )
end} end}
]. ].
union_member_selector_jwt_test_() -> union_member_selector_jwt_test_() ->
ok = ensure_schema_load(),
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
@ -59,25 +61,26 @@ union_member_selector_jwt_test_() ->
end}, end},
{"jwks", fun() -> {"jwks", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "jwt_jwks"}), ?ERR(#{matched_type := "authn:jwt_jwks"}),
check("{mechanism = jwt, use_jwks = true}") check("{mechanism = jwt, use_jwks = true}")
) )
end}, end},
{"publick-key", fun() -> {"publick-key", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "jwt_public_key"}), ?ERR(#{matched_type := "authn:jwt_public_key"}),
check("{mechanism = jwt, 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 := "jwt_hmac"}), ?ERR(#{matched_type := "authn:jwt_hmac"}),
check("{mechanism = jwt, use_jwks = false}") check("{mechanism = jwt, use_jwks = false}")
) )
end} end}
]. ].
union_member_selector_redis_test_() -> union_member_selector_redis_test_() ->
ok = ensure_schema_load(),
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
@ -87,25 +90,26 @@ union_member_selector_redis_test_() ->
end}, end},
{"single", fun() -> {"single", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "redis_single"}), ?ERR(#{matched_type := "authn:redis_single"}),
check("{mechanism = password_based, backend = redis, redis_type = single}") check("{mechanism = password_based, backend = redis, redis_type = single}")
) )
end}, end},
{"cluster", fun() -> {"cluster", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "redis_cluster"}), ?ERR(#{matched_type := "authn:redis_cluster"}),
check("{mechanism = password_based, backend = redis, redis_type = cluster}") check("{mechanism = password_based, backend = redis, redis_type = cluster}")
) )
end}, end},
{"sentinel", fun() -> {"sentinel", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "redis_sentinel"}), ?ERR(#{matched_type := "authn:redis_sentinel"}),
check("{mechanism = password_based, backend = redis, redis_type = sentinel}") check("{mechanism = password_based, backend = redis, redis_type = sentinel}")
) )
end} end}
]. ].
union_member_selector_http_test_() -> union_member_selector_http_test_() ->
ok = ensure_schema_load(),
[ [
{"unknown", fun() -> {"unknown", fun() ->
?assertMatch( ?assertMatch(
@ -115,13 +119,13 @@ union_member_selector_http_test_() ->
end}, end},
{"get", fun() -> {"get", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "http_get"}), ?ERR(#{matched_type := "authn:http_get"}),
check("{mechanism = password_based, backend = http, method = get}") check("{mechanism = password_based, backend = http, method = get}")
) )
end}, end},
{"post", fun() -> {"post", fun() ->
?assertMatch( ?assertMatch(
?ERR(#{matched_type := "http_post"}), ?ERR(#{matched_type := "authn:http_post"}),
check("{mechanism = password_based, backend = http, method = post}") check("{mechanism = password_based, backend = http, method = post}")
) )
end} end}
@ -132,3 +136,7 @@ check(HoconConf) ->
#{roots => emqx_authn_schema:global_auth_fields()}, #{roots => emqx_authn_schema:global_auth_fields()},
["authentication= ", HoconConf] ["authentication= ", HoconConf]
). ).
ensure_schema_load() ->
_ = emqx_conf_schema:roots(),
ok.

View File

@ -16,10 +16,6 @@
-module(emqx_authn_http_schema). -module(emqx_authn_http_schema).
-include("emqx_auth_http.hrl").
-include_lib("emqx_auth/include/emqx_authn.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
@ -31,6 +27,10 @@
namespace/0 namespace/0
]). ]).
-include("emqx_auth_http.hrl").
-include_lib("emqx_auth/include/emqx_authn.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-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), -define(THROW_VALIDATION_ERROR(ERROR, MESSAGE),
throw(#{ throw(#{

View File

@ -16,18 +16,21 @@
-module(emqx_authn_jwt_schema). -module(emqx_authn_jwt_schema).
-include("emqx_auth_jwt.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
namespace/0,
fields/1, fields/1,
desc/1, desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
-include("emqx_auth_jwt.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() -> refs() ->
[ [
?R_REF(jwt_hmac), ?R_REF(jwt_hmac),

View File

@ -16,9 +16,6 @@
-module(emqx_authn_ldap_bind_schema). -module(emqx_authn_ldap_bind_schema).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
@ -29,6 +26,9 @@
namespace/0 namespace/0
]). ]).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn". namespace() -> "authn".
refs() -> refs() ->

View File

@ -16,18 +16,21 @@
-module(emqx_authn_ldap_schema). -module(emqx_authn_ldap_schema).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
namespace/0,
fields/1, fields/1,
desc/1, desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
-include("emqx_auth_ldap.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() -> refs() ->
[?R_REF(ldap)]. [?R_REF(ldap)].

View File

@ -22,12 +22,15 @@
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
namespace/0,
fields/1, fields/1,
desc/1, desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
namespace() -> "authn".
refs() -> refs() ->
[?R_REF(scram)]. [?R_REF(scram)].

View File

@ -16,19 +16,19 @@
-module(emqx_authn_mongodb_schema). -module(emqx_authn_mongodb_schema).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
namespace/0,
fields/1, fields/1,
desc/1, desc/1,
refs/0, refs/0,
select_union_member/1, select_union_member/1
namespace/0
]). ]).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn". namespace() -> "authn".
refs() -> refs() ->

View File

@ -16,9 +16,6 @@
-module(emqx_authz_mongodb_schema). -module(emqx_authz_mongodb_schema).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-export([ -export([
type/0, type/0,
fields/1, fields/1,
@ -28,6 +25,9 @@
namespace/0 namespace/0
]). ]).
-include("emqx_auth_mongodb.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authz". namespace() -> "authz".
type() -> ?AUTHZ_TYPE. type() -> ?AUTHZ_TYPE.

View File

@ -16,9 +16,6 @@
-module(emqx_authn_mysql_schema). -module(emqx_authn_mysql_schema).
-include("emqx_auth_mysql.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
@ -29,6 +26,9 @@
select_union_member/1 select_union_member/1
]). ]).
-include("emqx_auth_mysql.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn". namespace() -> "authn".
refs() -> refs() ->

View File

@ -104,7 +104,7 @@ t_update_with_invalid_config(_Config) ->
?assertMatch( ?assertMatch(
{error, #{ {error, #{
kind := validation_error, kind := validation_error,
matched_type := "postgresql", matched_type := "authn:postgresql",
path := "authentication.1.server", path := "authentication.1.server",
reason := required_field reason := required_field
}}, }},

View File

@ -170,7 +170,7 @@ test_create_invalid_config(InvalidAuthConfig, Path) ->
?assertMatch( ?assertMatch(
{error, #{ {error, #{
kind := validation_error, kind := validation_error,
matched_type := "redis_single", matched_type := "authn:redis_single",
path := Path path := Path
}}, }},
emqx:update_config(?PATH, {create_authenticator, ?GLOBAL, InvalidAuthConfig}) emqx:update_config(?PATH, {create_authenticator, ?GLOBAL, InvalidAuthConfig})

View File

@ -16,18 +16,21 @@
-module(emqx_gcp_device_authn_schema). -module(emqx_gcp_device_authn_schema).
-include("emqx_gcp_device.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-behaviour(emqx_authn_schema). -behaviour(emqx_authn_schema).
-export([ -export([
namespace/0,
fields/1, fields/1,
desc/1, desc/1,
refs/0, refs/0,
select_union_member/1 select_union_member/1
]). ]).
-include("emqx_gcp_device.hrl").
-include_lib("hocon/include/hoconsc.hrl").
namespace() -> "authn".
refs() -> [?R_REF(gcp_device)]. refs() -> [?R_REF(gcp_device)].
select_union_member(#{<<"mechanism">> := ?AUTHN_MECHANISM_BIN}) -> select_union_member(#{<<"mechanism">> := ?AUTHN_MECHANISM_BIN}) ->

View File

@ -22,6 +22,7 @@
-include_lib("snabbkaffe/include/snabbkaffe.hrl"). -include_lib("snabbkaffe/include/snabbkaffe.hrl").
-behaviour(emqx_resource). -behaviour(emqx_resource).
-behaviour(hocon_schema).
%% callbacks of behaviour emqx_resource %% callbacks of behaviour emqx_resource
-export([ -export([
@ -29,7 +30,8 @@
on_start/2, on_start/2,
on_stop/2, on_stop/2,
on_query/3, on_query/3,
on_get_status/2 on_get_status/2,
namespace/0
]). ]).
%% ecpool callback %% ecpool callback
@ -50,6 +52,9 @@
}). }).
%%===================================================================== %%=====================================================================
namespace() -> "mongo".
roots() -> roots() ->
[ [
{config, #{ {config, #{