fix(authn api): update removing listener-specific chain logic

This commit is contained in:
Ilya Averyanov 2022-05-31 15:55:46 +03:00
parent 1bad5f8b7c
commit d32b2ecd81
5 changed files with 43 additions and 65 deletions

View File

@ -218,8 +218,11 @@ when
authenticate(#{listener := Listener, protocol := Protocol} = Credential, _AuthResult) ->
Authenticators = get_authenticators(Listener, global_chain(Protocol)),
case get_enabled(Authenticators) of
[] -> ignore;
NAuthenticators -> do_authenticate(NAuthenticators, Credential)
[] ->
ignore;
NAuthenticators ->
ct:print("NAuthenticators: ~p", [NAuthenticators]),
do_authenticate(NAuthenticators, Credential)
end.
get_authenticators(Listener, Global) ->
@ -584,6 +587,7 @@ handle_delete_authenticator(Chain, AuthenticatorID) ->
[] ->
{error, {not_found, {authenticator, AuthenticatorID}}};
[AuthenticatorID] ->
ct:print("handle_delete_authenticator: ~p", [AuthenticatorID]),
emqx_metrics_worker:clear_metrics(authn_metrics, AuthenticatorID),
ok
end.
@ -751,7 +755,7 @@ do_create_authenticator(AuthenticatorID, #{enable := Enable} = Config, Providers
end
end.
do_delete_authenticators(MatchFun, #chain{authenticators = Authenticators} = Chain) ->
do_delete_authenticators(MatchFun, #chain{name = Name, authenticators = Authenticators} = Chain) ->
{Matching, Others} = lists:partition(MatchFun, Authenticators),
MatchingIDs = lists:map(
@ -760,7 +764,14 @@ do_delete_authenticators(MatchFun, #chain{authenticators = Authenticators} = Cha
),
ok = lists:foreach(fun do_destroy_authenticator/1, Matching),
true = ets:insert(?CHAINS_TAB, Chain#chain{authenticators = Others}),
true =
case Others of
[] ->
ets:delete(?CHAINS_TAB, Name);
%% ets:insert(?CHAINS_TAB, Chain#chain{authenticators = Others});
_ ->
ets:insert(?CHAINS_TAB, Chain#chain{authenticators = Others})
end,
MatchingIDs.
do_destroy_authenticator(#authenticator{provider = Provider, state = State}) ->

View File

@ -52,7 +52,6 @@
-type update_request() ::
{create_authenticator, chain_name(), map()}
| {delete_authenticator, chain_name(), authenticator_id()}
| {delete_authenticators, chain_name()}
| {update_authenticator, chain_name(), authenticator_id(), map()}
| {move_authenticator, chain_name(), authenticator_id(), position()}.
@ -89,8 +88,6 @@ do_pre_config_update({delete_authenticator, _ChainName, AuthenticatorID}, OldCon
OldConfig
),
{ok, NewConfig};
do_pre_config_update({delete_authenticators, _ChainName}, _OldConfig) ->
{ok, []};
do_pre_config_update({update_authenticator, ChainName, AuthenticatorID, Config}, OldConfig) ->
CertsDir = certs_dir(ChainName, AuthenticatorID),
NewConfig = lists:map(
@ -159,25 +156,6 @@ do_post_config_update(
{error, Reason} ->
{error, Reason}
end;
do_post_config_update(
{delete_authenticators, ChainName},
_NewConfig,
OldConfig,
_AppEnvs
) ->
case emqx_authentication:delete_chain(ChainName) of
ok ->
lists:foreach(
fun(Config) ->
AuthenticatorID = authenticator_id(Config),
CertsDir = certs_dir(ChainName, AuthenticatorID),
ok = clear_certs(CertsDir, Config)
end,
to_list(OldConfig)
);
{error, Reason} ->
{error, Reason}
end;
do_post_config_update(
{update_authenticator, ChainName, AuthenticatorID, Config},
NewConfig,

View File

@ -49,13 +49,6 @@ emqx_authn_api {
}
}
listeners_listener_id_authentication_delete {
desc {
en: """Delete listener-specific authentication."""
zh: """删除特定于侦听器的身份验证。"""
}
}
listeners_listener_id_authentication_post {
desc {
en: """Create authenticator for listener authentication."""

View File

@ -248,15 +248,6 @@ schema("/listeners/:listener_id/authentication") ->
)
}
},
delete => #{
tags => ?API_TAGS_SINGLE,
description => ?DESC(listeners_listener_id_authentication_delete),
parameters => [param_listener_id()],
responses => #{
204 => <<"Authentication chain deleted">>,
404 => error_codes([?NOT_FOUND], <<"Not Found">>)
}
},
post => #{
tags => ?API_TAGS_SINGLE,
description => ?DESC(listeners_listener_id_authentication_post),
@ -610,13 +601,6 @@ listener_authenticators(get, #{bindings := #{listener_id := ListenerID}}) ->
fun(Type, Name, _) ->
list_authenticators([listeners, Type, Name, authentication])
end
);
listener_authenticators(delete, #{bindings := #{listener_id := ListenerID}}) ->
with_listener(
ListenerID,
fun(Type, Name, ChainName) ->
delete_authenticators([listeners, Type, Name, authentication], ChainName)
end
).
listener_authenticator(get, #{bindings := #{listener_id := ListenerID, id := AuthenticatorID}}) ->
@ -1036,16 +1020,6 @@ delete_authenticator(ConfKeyPath, ChainName, AuthenticatorID) ->
serialize_error(Reason)
end.
delete_authenticators(ConfKeyPath, ChainName) ->
case update_config(ConfKeyPath, {delete_authenticators, ChainName}) of
{ok, _} ->
{204};
{error, {_PrePostConfigUpdate, emqx_authentication, Reason}} ->
serialize_error(Reason);
{error, Reason} ->
serialize_error(Reason)
end.
move_authenticator(ConfKeyPath, ChainName, AuthenticatorID, Position) ->
case parse_position(Position) of
{ok, NPosition} ->

View File

@ -674,6 +674,11 @@ t_switch_to_global_chain(_) ->
uri([listeners, "tcp:default", ?CONF_NS]),
emqx_authn_test_lib:built_in_database_example()
),
{ok, 200, _} = request(
post,
uri([listeners, "tcp:default", ?CONF_NS]),
maps:put(enable, false, emqx_authn_test_lib:http_example())
),
GlobalUser = #{user_id => <<"global_user">>, password => <<"p1">>},
@ -716,29 +721,46 @@ t_switch_to_global_chain(_) ->
{ok, 204, _} = request(
delete,
uri([listeners, "tcp:default", ?CONF_NS])
uri([listeners, "tcp:default", ?CONF_NS, "password_based:built_in_database"])
),
%% Listener user should not be OK local chain removed
%% Now listener has only disabled authenticators, should allow anonymous access
{ok, Client2} = emqtt:start_link([
{username, <<"any_user">>},
{password, <<"any_password">>}
]),
?assertMatch(
{ok, _},
emqtt:connect(Client2)
),
ok = emqtt:disconnect(Client2),
{ok, 204, _} = request(
delete,
uri([listeners, "tcp:default", ?CONF_NS, "password_based:http"])
),
%% Local chain is empty now and should be removed
%% Listener user should not be OK
{ok, Client3} = emqtt:start_link([
{username, <<"listener_user">>},
{password, <<"p1">>}
]),
?assertMatch(
{error, {unauthorized_client, _}},
emqtt:connect(Client2)
emqtt:connect(Client3)
),
%% Global user should be now OK, switched back to the global chain
{ok, Client3} = emqtt:start_link([
{ok, Client4} = emqtt:start_link([
{username, <<"global_user">>},
{password, <<"p1">>}
]),
?assertMatch(
{ok, _},
emqtt:connect(Client3)
emqtt:connect(Client4)
),
ok = emqtt:disconnect(Client3).
ok = emqtt:disconnect(Client4).
%%------------------------------------------------------------------------------
%% Helpers