chore(auth): removed direct usages of authn from emqx core app

This commit is contained in:
Ilya Averyanov 2023-08-01 19:38:58 +03:00
parent ce2b159022
commit ca8c1e3ef8
5 changed files with 109 additions and 48 deletions

View File

@ -14,6 +14,9 @@
%% limitations under the License.
%%--------------------------------------------------------------------
-ifndef(EMQX_ACCESS_CONTROL_HRL).
-define(EMQX_ACCESS_CONTROL_HRL, true).
%% config root name all auth providers have to agree on.
-define(EMQX_AUTHORIZATION_CONFIG_ROOT_NAME, "authorization").
-define(EMQX_AUTHORIZATION_CONFIG_ROOT_NAME_ATOM, authorization).
@ -35,3 +38,4 @@
-define(AUTHN_TRACE_TAG, "AUTHN").
-endif.

View File

@ -29,6 +29,7 @@
-define(HP_RETAINER, 930).
-define(HP_AUTO_SUB, 920).
-define(HP_RULE_ENGINE, 900).
%% apps that can work with the republish action
-define(HP_SLOW_SUB, 880).
-define(HP_BRIDGE, 870).

View File

@ -0,0 +1,86 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2017-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_authentication_listener_hooks).
-include_lib("emqx/include/emqx_hooks.hrl").
-export([
on_listener_started/4,
on_listener_stopped/4,
on_listener_updated/4
]).
-export([
load/0,
unload/0
]).
%%--------------------------------------------------------------------
%% API
%%--------------------------------------------------------------------
load() ->
ok = emqx_hook:put('listener.started', {?MODULE, on_listener_started, []}, ?HP_AUTHN),
ok = emqx_hook:put('listener.stopped', {?MODULE, on_listener_stopped, []}, ?HP_AUTHN),
ok = emqx_hook:put('listener.updated', {?MODULE, on_listener_updated, []}, ?HP_AUTHN),
ok.
unload() ->
ok = emqx_hooks:del('listener.started', {?MODULE, authenticate, []}),
ok = emqx_hooks:del('listener.stopped', {?MODULE, authenticate, []}),
ok = emqx_hooks:del('listener.updated', {?MODULE, authenticate, []}),
ok.
%%--------------------------------------------------------------------
%% Hooks
%%--------------------------------------------------------------------
on_listener_started(Type, Name, Conf, ok) ->
recreate_authenticators(Type, Name, Conf);
on_listener_started(_Type, _Name, _Conf, _Error) ->
ok.
on_listener_updated(Type, Name, {_OldConf, NewConf}, ok) ->
recreate_authenticators(Type, Name, NewConf);
on_listener_updated(_Type, _Name, _Conf, _Error) ->
ok.
on_listener_stopped(Type, Name, _OldConf, ok) ->
_ = emqx_authentication:delete_chain(emqx_listeners:listener_id(Type, Name)),
ok;
on_listener_stopped(_Type, _Name, _Conf, _Error) ->
ok.
%%--------------------------------------------------------------------
%% Internal functions
%%--------------------------------------------------------------------
recreate_authenticators(Type, Name, Conf) ->
Chain = emqx_listeners:listener_id(Type, Name),
_ = emqx_authentication:delete_chain(Chain),
do_create_authneticators(Chain, maps:get(authentication, Conf, [])).
do_create_authneticators(Chain, [AuthN | T]) ->
case emqx_authentication:create_authenticator(Chain, AuthN) of
{ok, _} ->
do_create_authneticators(Chain, T);
Error ->
_ = emqx_authentication:delete_chain(Chain),
{ok, Error}
end;
do_create_authneticators(_Chain, []) ->
ok.

View File

@ -531,41 +531,18 @@ post_config_update(_Path, _Request, _NewConf, _OldConf, _AppEnvs) ->
ok.
create_listener(Type, Name, NewConf) ->
Res = start_listener(Type, Name, NewConf),
recreate_authenticators(Res, Type, Name, NewConf).
recreate_authenticators(ok, Type, Name, Conf) ->
Chain = listener_id(Type, Name),
_ = emqx_authentication:delete_chain(Chain),
do_create_authneticators(Chain, maps:get(authentication, Conf, []));
recreate_authenticators(Error, _Type, _Name, _NewConf) ->
Error.
do_create_authneticators(Chain, [AuthN | T]) ->
case emqx_authentication:create_authenticator(Chain, AuthN) of
{ok, _} ->
do_create_authneticators(Chain, T);
Error ->
_ = emqx_authentication:delete_chain(Chain),
Error
end;
do_create_authneticators(_Chain, []) ->
ok.
StartRes = start_listener(Type, Name, NewConf),
emqx_hooks:run_fold('listener.started', [Type, Name, NewConf], StartRes).
remove_listener(Type, Name, OldConf) ->
ok = unregister_ocsp_stapling_refresh(Type, Name),
case stop_listener(Type, Name, OldConf) of
ok ->
_ = emqx_authentication:delete_chain(listener_id(Type, Name)),
ok;
Err ->
Err
end.
StopRes = stop_listener(Type, Name, OldConf),
emqx_hooks:run_fold('listener.stopped', [Type, Name, OldConf], StopRes).
update_listener(Type, Name, {OldConf, NewConf}) ->
ok = maybe_unregister_ocsp_stapling_refresh(Type, Name, NewConf),
Res = restart_listener(Type, Name, {OldConf, NewConf}),
recreate_authenticators(Res, Type, Name, NewConf).
RestartRes = restart_listener(Type, Name, {OldConf, NewConf}),
emqx_hooks:run_fold('listener.restarted', [Type, Name, {OldConf, NewConf}], RestartRes).
perform_listener_changes([]) ->
ok;

View File

@ -26,6 +26,7 @@
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
-include_lib("emqx/include/emqx.hrl").
-include_lib("emqx/include/emqx_hooks.hrl").
-include_lib("emqx/include/emqx_mqtt.hrl").
all() ->
@ -680,28 +681,17 @@ t_connect_client_never_negative({'end', _Config}) ->
t_connack_auth_error({init, Config}) ->
process_flag(trap_exit, true),
ChainName = 'mqtt:global',
AuthenticatorConfig = #{
enable => true,
mechanism => password_based,
backend => built_in_database,
user_id_type => username,
password_hash_algorithm => #{
name => plain,
salt_position => disable
},
user_group => <<"global:mqtt">>
},
ok = emqx_authentication:register_providers(
[{{password_based, built_in_database}, emqx_authentication_SUITE}]
emqx_hooks:put(
'client.authenticate',
{?MODULE, authenticate_deny, []},
?HP_AUTHN
),
emqx_authentication:initialize_authentication(ChainName, AuthenticatorConfig),
Config;
t_connack_auth_error({'end', _Config}) ->
ChainName = 'mqtt:global',
AuthenticatorID = <<"password_based:built_in_database">>,
ok = emqx_authentication:deregister_provider({password_based, built_in_database}),
ok = emqx_authentication:delete_authenticator(ChainName, AuthenticatorID),
emqx_hooks:del(
'client.authenticate',
{?MODULE, authenticate_deny, []}
),
ok;
t_connack_auth_error(Config) when is_list(Config) ->
%% MQTT 3.1
@ -733,6 +723,9 @@ t_handle_in_empty_client_subscribe_hook(Config) when is_list(Config) ->
emqtt:disconnect(C)
end.
authenticate_deny(_Credentials, _Default) ->
{stop, {error, bad_username_or_password}}.
wait_for_events(Action, Kinds) ->
wait_for_events(Action, Kinds, 500).