From b88796518eb35fbd145dd538b48d7383f0a2f00f Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 30 Jun 2022 14:04:27 +0800 Subject: [PATCH 1/4] fix(authn): authn http `is_superuser` field only support true|false|[num] and for [num]: zero => false | non-zero => true other type and string will fallback to default vaule => false i.e null|undefined|[empty string] --- apps/emqx_authn/src/emqx_authn_utils.erl | 29 +++++- .../src/simple_authn/emqx_authn_http.erl | 98 +++++++++++-------- 2 files changed, 85 insertions(+), 42 deletions(-) diff --git a/apps/emqx_authn/src/emqx_authn_utils.erl b/apps/emqx_authn/src/emqx_authn_utils.erl index 20d2b57c9..8d3d45b1b 100644 --- a/apps/emqx_authn/src/emqx_authn_utils.erl +++ b/apps/emqx_authn/src/emqx_authn_utils.erl @@ -135,6 +135,18 @@ render_sql_params(ParamList, Credential) -> #{return => rawlist, var_trans => fun handle_sql_var/2} ). +%% true +is_superuser(#{<<"is_superuser">> := <<"true">>}) -> + #{is_superuser => true}; +is_superuser(#{<<"is_superuser">> := true}) -> + #{is_superuser => true}; +is_superuser(#{<<"is_superuser">> := <<"1">>}) -> + #{is_superuser => true}; +is_superuser(#{<<"is_superuser">> := I}) when + is_integer(I) andalso I >= 1 +-> + #{is_superuser => true}; +%% false is_superuser(#{<<"is_superuser">> := <<"">>}) -> #{is_superuser => false}; is_superuser(#{<<"is_superuser">> := <<"0">>}) -> @@ -145,10 +157,25 @@ is_superuser(#{<<"is_superuser">> := null}) -> #{is_superuser => false}; is_superuser(#{<<"is_superuser">> := undefined}) -> #{is_superuser => false}; +is_superuser(#{<<"is_superuser">> := <<"false">>}) -> + #{is_superuser => false}; is_superuser(#{<<"is_superuser">> := false}) -> #{is_superuser => false}; +is_superuser(#{<<"is_superuser">> := MaybeBinInt}) when + is_binary(MaybeBinInt) +-> + try binary_to_integer(MaybeBinInt) of + Int when Int >= 1 -> + #{is_superuser => true}; + Int when Int =< 0 -> + #{is_superuser => false} + catch + error:badarg -> + #{is_superuser => false} + end; +%% fallback to default is_superuser(#{<<"is_superuser">> := _}) -> - #{is_superuser => true}; + #{is_superuser => false}; is_superuser(#{}) -> #{is_superuser => false}. 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 c4ce9f2b1..8dccb9ee3 100644 --- a/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl +++ b/apps/emqx_authn/src/simple_authn/emqx_authn_http.erl @@ -191,48 +191,21 @@ authenticate( case emqx_resource:query(ResourceId, {Method, Request, RequestTimeout}) of {ok, 204, _Headers} -> {ok, #{is_superuser => false}}; - {ok, 200, _Headers} -> - {ok, #{is_superuser => false}}; {ok, 200, Headers, Body} -> - ContentType = proplists:get_value(<<"content-type">>, Headers, <<"application/json">>), - case safely_parse_body(ContentType, Body) of - {ok, NBody} -> - %% TODO: Return by user property - UserProperty = maps:remove(<<"is_superuser">>, NBody), - IsSuperuser = emqx_authn_utils:is_superuser(NBody), - {ok, IsSuperuser#{user_property => UserProperty}}; - {error, _Reason} -> - {ok, #{is_superuser => false}} - end; + handle_response(Headers, Body); + {ok, _StatusCode, _Headers} = Response -> + log_response(ResourceId, Response), + ignore; + {ok, _StatusCode, _Headers, _Body} = Response -> + log_response(ResourceId, Response), + ignore; {error, Reason} -> ?SLOG(error, #{ msg => "http_server_query_failed", resource => ResourceId, reason => Reason }), - ignore; - Other -> - Output = may_append_body(#{resource => ResourceId}, Other), - case erlang:element(2, Other) of - Code5xx when Code5xx >= 500 andalso Code5xx < 600 -> - ?SLOG(error, Output#{ - msg => "http_server_error", - code => Code5xx - }), - ignore; - Code4xx when Code4xx >= 400 andalso Code4xx < 500 -> - ?SLOG(warning, Output#{ - msg => "refused_by_http_server", - code => Code4xx - }), - {error, not_authorized}; - OtherCode -> - ?SLOG(error, Output#{ - msg => "undesired_response_code", - code => OtherCode - }), - ignore - end + ignore end. destroy(#{resource_id := ResourceId}) -> @@ -366,20 +339,43 @@ qs([{K, V} | More], Acc) -> serialize_body(<<"application/json">>, Body) -> emqx_json:encode(Body); serialize_body(<<"application/x-www-form-urlencoded">>, Body) -> - qs(Body). + qs(maps:to_list(Body)). + +handle_response(Headers, Body) -> + ContentType = proplists:get_value(<<"content-type">>, Headers), + case safely_parse_body(ContentType, Body) of + {ok, NBody} -> + case maps:get(<<"result">>, NBody, <<"ignore">>) of + <<"allow">> -> + Res = emqx_authn_utils:is_superuser(NBody), + %% TODO: Return by user property + {ok, Res#{user_property => maps:get(<<"user_property">>, NBody, #{})}}; + <<"deny">> -> + {error, not_authorized}; + <<"ignore">> -> + ignore; + _ -> + ignore + end; + {error, _Reason} -> + ignore + end. safely_parse_body(ContentType, Body) -> - try parse_body(ContentType, Body) of - Result -> Result + try + parse_body(ContentType, Body) catch _Class:_Reason -> {error, invalid_body} end. -parse_body(<<"application/json">>, Body) -> +parse_body(<<"application/json", _/binary>>, Body) -> {ok, emqx_json:decode(Body, [return_maps])}; -parse_body(<<"application/x-www-form-urlencoded">>, Body) -> - {ok, maps:from_list(cow_qs:parse_qs(Body))}; +parse_body(<<"application/x-www-form-urlencoded", _/binary>>, Body) -> + Flags = [<<"result">>, <<"is_superuser">>], + RawMap = maps:from_list(cow_qs:parse_qs(Body)), + NBody = maps:with(Flags, RawMap), + {ok, NBody}; parse_body(ContentType, _) -> {error, {unsupported_content_type, ContentType}}. @@ -395,6 +391,26 @@ encode_path(Path) -> Parts = string:split(Path, "/", all), lists:flatten(["/" ++ Part || Part <- lists:map(fun uri_encode/1, Parts)]). +log_response(ResourceId, Other) -> + Output = may_append_body(#{resource => ResourceId}, Other), + case erlang:element(2, Other) of + Code5xx when Code5xx >= 500 andalso Code5xx < 600 -> + ?SLOG(error, Output#{ + msg => "http_server_error", + code => Code5xx + }); + Code4xx when Code4xx >= 400 andalso Code4xx < 500 -> + ?SLOG(warning, Output#{ + msg => "refused_by_http_server", + code => Code4xx + }); + OtherCode -> + ?SLOG(error, Output#{ + msg => "undesired_response_code", + code => OtherCode + }) + end. + to_list(A) when is_atom(A) -> atom_to_list(A); to_list(B) when is_binary(B) -> From f0c783b260aa391a7ff699f431b6fff11a45918e Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 30 Jun 2022 14:54:10 +0800 Subject: [PATCH 2/4] test(authn): emqx_authn and gateway_athn http `content-type` --- .../emqx_authn/test/emqx_authn_http_SUITE.erl | 236 ++++++++++++++---- .../test/emqx_authn_https_SUITE.erl | 2 + .../test/emqx_gateway_auth_ct.erl | 4 +- 3 files changed, 197 insertions(+), 45 deletions(-) diff --git a/apps/emqx_authn/test/emqx_authn_http_SUITE.erl b/apps/emqx_authn/test/emqx_authn_http_SUITE.erl index 4d17c7191..5384bcf6e 100644 --- a/apps/emqx_authn/test/emqx_authn_http_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_http_SUITE.erl @@ -37,6 +37,29 @@ protocol => mqtt }). +-define(SERVER_RESPONSE_JSON(Result), ?SERVER_RESPONSE_JSON(Result, false)). +-define(SERVER_RESPONSE_JSON(Result, IsSuperuser), + jiffy:encode(#{ + result => Result, + is_superuser => IsSuperuser + }) +). + +-define(SERVER_RESPONSE_URLENCODE(Result), ?SERVER_RESPONSE_URLENCODE(Result, false)). +-define(SERVER_RESPONSE_URLENCODE(Result, IsSuperuser), + list_to_binary( + "result=" ++ + uri_encode(Result) ++ "&" ++ + "is_superuser=" ++ + uri_encode(IsSuperuser) + ) +). + +-define(EXCEPTION_ALLOW, ?EXCEPTION_ALLOW(false)). +-define(EXCEPTION_ALLOW(IsSuperuser), {ok, #{is_superuser := IsSuperuser}}). +-define(EXCEPTION_DENY, {error, not_authorized}). +-define(EXCEPTION_IGNORE, ignore). + all() -> emqx_common_test_helpers:all(?MODULE). @@ -149,9 +172,12 @@ t_destroy(_Config) -> {create_authenticator, ?GLOBAL, AuthConfig} ), + Headers = #{<<"content-type">> => <<"application/json">>}, + Response = ?SERVER_RESPONSE_JSON(allow), + ok = emqx_authn_http_test_server:set_handler( fun(Req0, State) -> - Req = cowboy_req:reply(200, Req0), + Req = cowboy_req:reply(200, Headers, Response, Req0), {ok, Req, State} end ), @@ -161,9 +187,12 @@ t_destroy(_Config) -> Credentials = maps:with([username, password], ?CREDENTIALS), - {ok, _} = emqx_authn_http:authenticate( - Credentials, - State + ?assertMatch( + ?EXCEPTION_ALLOW, + emqx_authn_http:authenticate( + Credentials, + State + ) ), emqx_authn_test_lib:delete_authenticators( @@ -173,7 +202,7 @@ t_destroy(_Config) -> % Authenticator should not be usable anymore ?assertMatch( - ignore, + ?EXCEPTION_IGNORE, emqx_authn_http:authenticate( Credentials, State @@ -190,14 +219,20 @@ t_update(_Config) -> {create_authenticator, ?GLOBAL, IncorrectConfig} ), + Headers = #{<<"content-type">> => <<"application/json">>}, + Response = ?SERVER_RESPONSE_JSON(allow), + ok = emqx_authn_http_test_server:set_handler( fun(Req0, State) -> - Req = cowboy_req:reply(200, Req0), + Req = cowboy_req:reply(200, Headers, Response, Req0), {ok, Req, State} end ), - {error, not_authorized} = emqx_access_control:authenticate(?CREDENTIALS), + ?assertMatch( + ?EXCEPTION_DENY, + emqx_access_control:authenticate(?CREDENTIALS) + ), % We update with config with correct query, provider should update and work properly {ok, _} = emqx:update_config( @@ -205,7 +240,10 @@ t_update(_Config) -> {update_authenticator, ?GLOBAL, <<"password_based:http">>, CorrectConfig} ), - {ok, _} = emqx_access_control:authenticate(?CREDENTIALS). + ?assertMatch( + ?EXCEPTION_ALLOW, + emqx_access_control:authenticate(?CREDENTIALS) + ). t_is_superuser(_Config) -> Config = raw_http_auth_config(), @@ -215,33 +253,56 @@ t_is_superuser(_Config) -> ), Checks = [ - {json, <<"0">>, false}, - {json, <<"">>, false}, - {json, null, false}, - {json, 0, false}, + %% {ContentType, ExpectedIsSuperuser, ResponseIsSuperuser} + %% Is Superuser + {json, true, <<"1">>}, + {json, true, 1}, + {json, true, 123}, + {json, true, <<"true">>}, + {json, true, true}, - {json, <<"1">>, true}, - {json, <<"val">>, true}, - {json, 1, true}, - {json, 123, true}, + %% Not Superuser + {json, false, <<"">>}, + {json, false, <<"0">>}, + {json, false, 0}, + {json, false, null}, + {json, false, undefined}, + {json, false, <<"false">>}, + {json, false, false}, - {form, <<"0">>, false}, - {form, <<"">>, false}, + {json, false, <<"val">>}, - {form, <<"1">>, true}, - {form, <<"val">>, true} + %% Is Superuser + {form, true, <<"1">>}, + {form, true, 1}, + {form, true, 123}, + {form, true, <<"true">>}, + {form, true, true}, + + %% Not Superuser + {form, false, <<"">>}, + {form, false, <<"0">>}, + {form, false, 0}, + + {form, false, null}, + {form, false, undefined}, + {form, false, <<"false">>}, + {form, false, false}, + + {form, false, <<"val">>} ], lists:foreach(fun test_is_superuser/1, Checks). -test_is_superuser({Kind, Value, ExpectedValue}) -> +test_is_superuser({Kind, ExpectedValue, ServerResponse}) -> {ContentType, Res} = case Kind of json -> - {<<"application/json">>, jiffy:encode(#{is_superuser => Value})}; + {<<"application/json; charset=utf-8">>, + ?SERVER_RESPONSE_JSON(allow, ServerResponse)}; form -> - {<<"application/x-www-form-urlencoded">>, - iolist_to_binary([<<"is_superuser=">>, Value])} + {<<"application/x-www-form-urlencoded; charset=utf-8">>, + ?SERVER_RESPONSE_URLENCODE(allow, ServerResponse)} end, ok = emqx_authn_http_test_server:set_handler( @@ -257,10 +318,58 @@ test_is_superuser({Kind, Value, ExpectedValue}) -> ), ?assertMatch( - {ok, #{is_superuser := ExpectedValue}}, + ?EXCEPTION_ALLOW(ExpectedValue), emqx_access_control:authenticate(?CREDENTIALS) ). +t_ignore_allow_deny(_Config) -> + Config = raw_http_auth_config(), + {ok, _} = emqx:update_config( + ?PATH, + {create_authenticator, ?GLOBAL, Config} + ), + + Checks = [ + %% only one chain, ignore by authn http and deny by default + {deny, ?SERVER_RESPONSE_JSON(ignore)}, + + {{allow, true}, ?SERVER_RESPONSE_JSON(allow, true)}, + {{allow, false}, ?SERVER_RESPONSE_JSON(allow)}, + {{allow, false}, ?SERVER_RESPONSE_JSON(allow, false)}, + + {deny, ?SERVER_RESPONSE_JSON(deny)}, + {deny, ?SERVER_RESPONSE_JSON(deny, true)}, + {deny, ?SERVER_RESPONSE_JSON(deny, false)} + ], + + lists:foreach(fun test_ignore_allow_deny/1, Checks). + +test_ignore_allow_deny({ExpectedValue, ServerResponse}) -> + ok = emqx_authn_http_test_server:set_handler( + fun(Req0, State) -> + Req = cowboy_req:reply( + 200, + #{<<"content-type">> => <<"application/json">>}, + ServerResponse, + Req0 + ), + {ok, Req, State} + end + ), + + case ExpectedValue of + {allow, IsSuperuser} -> + ?assertMatch( + ?EXCEPTION_ALLOW(IsSuperuser), + emqx_access_control:authenticate(?CREDENTIALS) + ); + deny -> + ?assertMatch( + ?EXCEPTION_DENY, + emqx_access_control:authenticate(?CREDENTIALS) + ) + end. + %%------------------------------------------------------------------------------ %% Helpers %%------------------------------------------------------------------------------ @@ -287,11 +396,16 @@ samples() -> password := <<"plain">> } = cowboy_req:match_qs([username, password], Req0), - Req = cowboy_req:reply(200, Req0), + Req = cowboy_req:reply( + 200, + #{<<"content-type">> => <<"application/json">>}, + jiffy:encode(#{result => allow, is_superuser => false}), + Req0 + ), {ok, Req, State} end, config_params => #{}, - result => {ok, #{is_superuser => false}} + result => {ok, #{is_superuser => false, user_property => #{}}} }, %% get request with json body response @@ -300,7 +414,7 @@ samples() -> Req = cowboy_req:reply( 200, #{<<"content-type">> => <<"application/json">>}, - jiffy:encode(#{is_superuser => true}), + jiffy:encode(#{result => allow, is_superuser => true}), Req0 ), {ok, Req, State} @@ -318,7 +432,7 @@ samples() -> <<"content-type">> => <<"application/x-www-form-urlencoded">> }, - <<"is_superuser=true">>, + <<"is_superuser=true&result=allow">>, Req0 ), {ok, Req, State} @@ -342,7 +456,8 @@ samples() -> {ok, Req, State} end, config_params => #{}, - result => {ok, #{is_superuser => false}} + %% only one chain, ignore by authn http and deny by default + result => {error, not_authorized} }, %% simple post request, application/json @@ -353,14 +468,19 @@ samples() -> <<"username">> := <<"plain">>, <<"password">> := <<"plain">> } = jiffy:decode(RawBody, [return_maps]), - Req = cowboy_req:reply(200, Req1), + Req = cowboy_req:reply( + 200, + #{<<"content-type">> => <<"application/json">>}, + jiffy:encode(#{result => allow, is_superuser => false}), + Req1 + ), {ok, Req, State} end, config_params => #{ <<"method">> => <<"post">>, <<"headers">> => #{<<"content-type">> => <<"application/json">>} }, - result => {ok, #{is_superuser => false}} + result => {ok, #{is_superuser => false, user_property => #{}}} }, %% simple post request, application/x-www-form-urlencoded @@ -371,7 +491,12 @@ samples() -> <<"username">> := <<"plain">>, <<"password">> := <<"plain">> } = maps:from_list(PostVars), - Req = cowboy_req:reply(200, Req1), + Req = cowboy_req:reply( + 200, + #{<<"content-type">> => <<"application/json">>}, + jiffy:encode(#{result => allow, is_superuser => false}), + Req1 + ), {ok, Req, State} end, config_params => #{ @@ -381,15 +506,7 @@ samples() -> <<"application/x-www-form-urlencoded">> } }, - result => {ok, #{is_superuser => false}} - }#{ - %% 204 code - handler => fun(Req0, State) -> - Req = cowboy_req:reply(204, Req0), - {ok, Req, State} - end, - config_params => #{}, - result => {ok, #{is_superuser => false}} + result => {ok, #{is_superuser => false, user_property => #{}}} }, %% simple post request for placeholders, application/json @@ -402,7 +519,12 @@ samples() -> <<"clientid">> := <<"clienta">>, <<"peerhost">> := <<"127.0.0.1">> } = jiffy:decode(RawBody, [return_maps]), - Req = cowboy_req:reply(200, Req1), + Req = cowboy_req:reply( + 200, + #{<<"content-type">> => <<"application/json">>}, + jiffy:encode(#{result => allow, is_superuser => false}), + Req1 + ), {ok, Req, State} end, config_params => #{ @@ -415,7 +537,7 @@ samples() -> <<"peerhost">> => ?PH_PEERHOST } }, - result => {ok, #{is_superuser => false}} + result => {ok, #{is_superuser => false, user_property => #{}}} }, %% custom headers @@ -426,6 +548,17 @@ samples() -> {ok, Req, State} end, config_params => #{}, + %% only one chain, ignore by authn http and deny by default + result => {error, not_authorized} + }, + + %% 204 code + #{ + handler => fun(Req0, State) -> + Req = cowboy_req:reply(204, Req0), + {ok, Req, State} + end, + config_params => #{}, result => {ok, #{is_superuser => false}} }, @@ -436,6 +569,7 @@ samples() -> {ok, Req, State} end, config_params => #{}, + %% only one chain, ignore by authn http and deny by default result => {error, not_authorized} }, @@ -446,6 +580,7 @@ samples() -> {ok, Req, State} end, config_params => #{}, + %% only one chain, ignore by authn http and deny by default result => {error, not_authorized} }, @@ -456,6 +591,7 @@ samples() -> {ok, Req0, State} end, config_params => #{}, + %% only one chain, ignore by authn http and deny by default result => {error, not_authorized} } ]. @@ -465,3 +601,15 @@ start_apps(Apps) -> stop_apps(Apps) -> lists:foreach(fun application:stop/1, Apps). + +uri_encode(T) -> + emqx_http_lib:uri_encode(to_list(T)). + +to_list(A) when is_atom(A) -> + atom_to_list(A); +to_list(N) when is_integer(N) -> + integer_to_list(N); +to_list(B) when is_binary(B) -> + binary_to_list(B); +to_list(L) when is_list(L) -> + L. diff --git a/apps/emqx_authn/test/emqx_authn_https_SUITE.erl b/apps/emqx_authn/test/emqx_authn_https_SUITE.erl index ae4508967..7aa40f909 100644 --- a/apps/emqx_authn/test/emqx_authn_https_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_https_SUITE.erl @@ -167,6 +167,8 @@ cert_path(FileName) -> cowboy_handler(Req0, State) -> Req = cowboy_req:reply( 200, + #{<<"content-type">> => <<"application/json">>}, + jiffy:encode(#{result => allow, is_superuser => false}), Req0 ), {ok, Req, State}. diff --git a/apps/emqx_gateway/test/emqx_gateway_auth_ct.erl b/apps/emqx_gateway/test/emqx_gateway_auth_ct.erl index 7fec71ae3..14b3d463e 100644 --- a/apps/emqx_gateway/test/emqx_gateway_auth_ct.erl +++ b/apps/emqx_gateway/test/emqx_gateway_auth_ct.erl @@ -141,12 +141,14 @@ on_start_auth(authn_http) -> %% set handler for test server Handler = fun(Req0, State) -> ct:pal("Authn Req:~p~nState:~p~n", [Req0, State]), + Headers = #{<<"content-type">> => <<"application/json">>}, + Response = jiffy:encode(#{result => allow, is_superuser => false}), case cowboy_req:match_qs([username, password], Req0) of #{ username := <<"admin">>, password := <<"public">> } -> - Req = cowboy_req:reply(200, Req0); + Req = cowboy_req:reply(200, Headers, Response, Req0); _ -> Req = cowboy_req:reply(400, Req0) end, From 7b825fe4bdc07e35eff3abc042a3f9053831d707 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 1 Jul 2022 18:32:09 +0800 Subject: [PATCH 3/4] test(authn): authn `is_superuser` default value false. --- apps/emqx_authn/test/emqx_authn_mongo_SUITE.erl | 3 ++- apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/emqx_authn/test/emqx_authn_mongo_SUITE.erl b/apps/emqx_authn/test/emqx_authn_mongo_SUITE.erl index c39d4a2a2..f68f9a528 100644 --- a/apps/emqx_authn/test/emqx_authn_mongo_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_mongo_SUITE.erl @@ -225,9 +225,10 @@ t_is_superuser(_Config) -> {null, false}, {false, false}, {0, false}, + {<<"val">>, false}, {<<"1">>, true}, - {<<"val">>, true}, + {<<"123">>, true}, {1, true}, {123, true}, {true, true} diff --git a/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl b/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl index ec29ba422..2d9607c41 100644 --- a/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_pgsql_SUITE.erl @@ -243,7 +243,7 @@ t_is_superuser(_Config) -> {is_superuser_str, "", false}, {is_superuser_str, null, false}, {is_superuser_str, "1", true}, - {is_superuser_str, "val", true}, + {is_superuser_str, "val", false}, {is_superuser_int, 0, false}, {is_superuser_int, null, false}, From 2ad99fca7ae3bedccc07e5dc55890288be7c051c Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 30 Jun 2022 15:31:43 +0800 Subject: [PATCH 4/4] chore: update appup.src --- apps/emqx/src/emqx.appup.src | 12 ++++-- apps/emqx_authn/src/emqx_authn.appup.src | 14 ++++--- apps/emqx_conf/src/emqx_conf.appup.src | 30 +++++++------- .../src/emqx_dashboard.appup.src | 16 ++++---- .../src/emqx_management.appup.src | 40 +++++++++---------- 5 files changed, 58 insertions(+), 54 deletions(-) diff --git a/apps/emqx/src/emqx.appup.src b/apps/emqx/src/emqx.appup.src index 0cef3736e..d3121c97b 100644 --- a/apps/emqx/src/emqx.appup.src +++ b/apps/emqx/src/emqx.appup.src @@ -2,20 +2,24 @@ %% Unless you know what you are doing, DO NOT edit manually!! {VSN, [{"5.0.0", - [{load_module,emqx_channel,brutal_purge,soft_purge,[]}, + [{load_module,emqx_quic_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_config,brutal_purge,soft_purge,[]}, + {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_schema,brutal_purge,soft_purge,[]}, {load_module,emqx_release,brutal_purge,soft_purge,[]}, {load_module,emqx_authentication,brutal_purge,soft_purge,[]}, {load_module,emqx_metrics,brutal_purge,soft_purge,[]}, {add_module,emqx_exclusive_subscription}, - {apply, {emqx_exclusive_subscription, on_add_module, []}}, + {apply,{emqx_exclusive_subscription,on_add_module,[]}}, {load_module,emqx_broker,brutal_purge,soft_purge,[]}, {load_module,emqx_mqtt_caps,brutal_purge,soft_purge,[]}, {load_module,emqx_topic,brutal_purge,soft_purge,[]}, {load_module,emqx_relup}]}, {<<".*">>,[]}], [{"5.0.0", - [{load_module,emqx_channel,brutal_purge,soft_purge,[]}, + [{load_module,emqx_quic_connection,brutal_purge,soft_purge,[]}, + {load_module,emqx_config,brutal_purge,soft_purge,[]}, + {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_schema,brutal_purge,soft_purge,[]}, {load_module,emqx_release,brutal_purge,soft_purge,[]}, {load_module,emqx_authentication,brutal_purge,soft_purge,[]}, @@ -23,7 +27,7 @@ {load_module,emqx_broker,brutal_purge,soft_purge,[]}, {load_module,emqx_mqtt_caps,brutal_purge,soft_purge,[]}, {load_module,emqx_topic,brutal_purge,soft_purge,[]}, - {apply, {emqx_exclusive_subscription, on_delete_module, []}}, + {apply,{emqx_exclusive_subscription,on_delete_module,[]}}, {delete_module,emqx_exclusive_subscription}, {load_module,emqx_relup}]}, {<<".*">>,[]}]}. diff --git a/apps/emqx_authn/src/emqx_authn.appup.src b/apps/emqx_authn/src/emqx_authn.appup.src index f165b2f77..9dcf55950 100644 --- a/apps/emqx_authn/src/emqx_authn.appup.src +++ b/apps/emqx_authn/src/emqx_authn.appup.src @@ -1,11 +1,13 @@ %% -*- mode: erlang -*- %% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [{"0.1.0",[ + [{"0.1.0", + [{load_module,emqx_authn_http,brutal_purge,soft_purge,[]}, {load_module,emqx_authn_utils,brutal_purge,soft_purge,[]}, - {load_module,emqx_authn_redis,brutal_purge,soft_purge,[]}] - }], - [{"0.1.0",[ + {load_module,emqx_authn_redis,brutal_purge,soft_purge,[]}]}, + {<<".*">>,[]}], + [{"0.1.0", + [{load_module,emqx_authn_http,brutal_purge,soft_purge,[]}, {load_module,emqx_authn_utils,brutal_purge,soft_purge,[]}, - {load_module,emqx_authn_redis,brutal_purge,soft_purge,[]}] - }]}. + {load_module,emqx_authn_redis,brutal_purge,soft_purge,[]}]}, + {<<".*">>,[]}]}. diff --git a/apps/emqx_conf/src/emqx_conf.appup.src b/apps/emqx_conf/src/emqx_conf.appup.src index 1937d1fd9..b86a15889 100644 --- a/apps/emqx_conf/src/emqx_conf.appup.src +++ b/apps/emqx_conf/src/emqx_conf.appup.src @@ -1,21 +1,19 @@ %% -*- mode: erlang -*- {VSN, - [ {"0.1.0", - [ - {add_module, emqx_conf_proto_v2}, - {load_module,emqx_conf_schema,brutal_purge,soft_purge,[]}, - {load_module,emqx_conf,brutal_purge,soft_purge,[]}, - {load_module,emqx_conf_app,brutal_purge,soft_purge,[]} - ]}, - {<<".*">>, []} + [{"0.1.0", + [{add_module, emqx_conf_proto_v2}, + {load_module,emqx_conf_schema,brutal_purge,soft_purge,[]}, + {load_module,emqx_conf,brutal_purge,soft_purge,[]}, + {load_module,emqx_conf_app,brutal_purge,soft_purge,[]} + ]}, + {<<".*">>, []} ], - [ {"0.1.0", - [ - {delete_module, emqx_conf_proto_v2}, - {load_module,emqx_conf_schema,brutal_purge,soft_purge,[]}, - {load_module,emqx_conf,brutal_purge,soft_purge,[]}, - {load_module,emqx_conf_app,brutal_purge,soft_purge,[]} - ]}, - {<<".*">>, []} + [{"0.1.0", + [{delete_module, emqx_conf_proto_v2}, + {load_module,emqx_conf_schema,brutal_purge,soft_purge,[]}, + {load_module,emqx_conf,brutal_purge,soft_purge,[]}, + {load_module,emqx_conf_app,brutal_purge,soft_purge,[]} + ]}, + {<<".*">>, []} ] }. diff --git a/apps/emqx_dashboard/src/emqx_dashboard.appup.src b/apps/emqx_dashboard/src/emqx_dashboard.appup.src index c499e1d9f..2b1053380 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard.appup.src +++ b/apps/emqx_dashboard/src/emqx_dashboard.appup.src @@ -1,13 +1,13 @@ %% -*- mode: erlang -*- %% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [{"5.0.0", [ - {load_module,emqx_dashboard_api,brutal_purge,soft_purge,[]}, - {load_module,emqx_dashboard_token,brutal_purge,soft_purge,[]} - ]}, + [{"5.0.0", + [{load_module,emqx_dashboard,brutal_purge,soft_purge,[]}, + {load_module,emqx_dashboard_api,brutal_purge,soft_purge,[]}, + {load_module,emqx_dashboard_token,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], - [{"5.0.0", [ - {load_module,emqx_dashboard_api,brutal_purge,soft_purge,[]}, - {load_module,emqx_dashboard_token,brutal_purge,soft_purge,[]} - ]}, + [{"5.0.0", + [{load_module,emqx_dashboard,brutal_purge,soft_purge,[]}, + {load_module,emqx_dashboard_api,brutal_purge,soft_purge,[]}, + {load_module,emqx_dashboard_token,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}]}. diff --git a/apps/emqx_management/src/emqx_management.appup.src b/apps/emqx_management/src/emqx_management.appup.src index d56a03fb2..22a6833c8 100644 --- a/apps/emqx_management/src/emqx_management.appup.src +++ b/apps/emqx_management/src/emqx_management.appup.src @@ -1,25 +1,25 @@ %% -*- mode: erlang -*- %% Unless you know what you are doing, DO NOT edit manually!! {VSN, - [{"5.0.0",[ - {load_module,emqx_mgmt_cli,brutal_purge,soft_purge,[]}, - {add_module,emqx_management_proto_v2}, - {load_module,emqx_mgmt_api_clients,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_api_publish,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_api_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_api_configs,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_util,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt,brutal_purge,soft_purge,[]} - ]}, + [{"5.0.0", + [{load_module,emqx_mgmt_api_nodes,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_cli,brutal_purge,soft_purge,[]}, + {add_module,emqx_management_proto_v2}, + {load_module,emqx_mgmt_api_clients,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_api_publish,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_api_listeners,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_api_configs,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_util,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}], - [{"5.0.0",[ - {load_module,emqx_mgmt_cli,brutal_purge,soft_purge,[]}, - {delete_module,emqx_management_proto_v2}, - {load_module,emqx_mgmt_api_clients,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_api_publish,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_api_listeners,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_api_configs,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt_util,brutal_purge,soft_purge,[]}, - {load_module,emqx_mgmt,brutal_purge,soft_purge,[]} - ]}, + [{"5.0.0", + [{load_module,emqx_mgmt_api_nodes,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_cli,brutal_purge,soft_purge,[]}, + {delete_module,emqx_management_proto_v2}, + {load_module,emqx_mgmt_api_clients,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_api_publish,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_api_listeners,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_api_configs,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt_util,brutal_purge,soft_purge,[]}, + {load_module,emqx_mgmt,brutal_purge,soft_purge,[]}]}, {<<".*">>,[]}]}.