From e6576951ef7acae7022bc8e68a585b10c1ac8976 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 20 Oct 2023 22:31:19 +0800 Subject: [PATCH] test: cleanup duplicated apikey with different name --- apps/emqx_management/src/emqx_mgmt_auth.erl | 2 + .../test/emqx_mgmt_api_api_keys_SUITE.erl | 104 ++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/apps/emqx_management/src/emqx_mgmt_auth.erl b/apps/emqx_management/src/emqx_mgmt_auth.erl index bce417dc4..afa8a8e2e 100644 --- a/apps/emqx_management/src/emqx_mgmt_auth.erl +++ b/apps/emqx_management/src/emqx_mgmt_auth.erl @@ -14,6 +14,7 @@ %% limitations under the License. %%-------------------------------------------------------------------- -module(emqx_mgmt_auth). +-include_lib("emqx_mgmt.hrl"). -include_lib("emqx/include/emqx.hrl"). -include_lib("emqx/include/logger.hrl"). @@ -49,6 +50,7 @@ -ifdef(TEST). -export([create/6]). +-export([trans/2, force_create_app/1]). -endif. -define(APP, emqx_app). diff --git a/apps/emqx_management/test/emqx_mgmt_api_api_keys_SUITE.erl b/apps/emqx_management/test/emqx_mgmt_api_api_keys_SUITE.erl index 2a78f76fc..72e0c5218 100644 --- a/apps/emqx_management/test/emqx_mgmt_api_api_keys_SUITE.erl +++ b/apps/emqx_management/test/emqx_mgmt_api_api_keys_SUITE.erl @@ -19,6 +19,19 @@ -compile(nowarn_export_all). -include_lib("eunit/include/eunit.hrl"). +-include_lib("common_test/include/ct.hrl"). + +-define(APP, emqx_app). + +-record(?APP, { + name = <<>> :: binary() | '_', + api_key = <<>> :: binary() | '_', + api_secret_hash = <<>> :: binary() | '_', + enable = true :: boolean() | '_', + desc = <<>> :: binary() | '_', + expired_at = 0 :: integer() | undefined | infinity | '_', + created_at = 0 :: integer() | '_' +}). all() -> [{group, parallel}, {group, sequence}]. suite() -> [{timetrap, {minutes, 1}}]. @@ -72,6 +85,97 @@ t_bootstrap_file(_) -> update_file(<<>>), ok. +t_bootstrap_file_override(_) -> + TestPath = <<"/api/v5/status">>, + Bin = + <<"test-1:secret-1\ntest-1:duplicated-secret-1\ntest-2:secret-2\ntest-2:duplicated-secret-2">>, + File = "./bootstrap_api_keys.txt", + ok = file:write_file(File, Bin), + update_file(File), + + ?assertEqual(ok, emqx_mgmt_auth:init_bootstrap_file()), + + MatchFun = fun(ApiKey) -> mnesia:match_object(#?APP{api_key = ApiKey, _ = '_'}) end, + ?assertMatch( + {ok, [ + #?APP{ + name = <<"from_bootstrap_file_18926f94712af04e">>, + api_key = <<"test-1">> + } + ]}, + emqx_mgmt_auth:trans(MatchFun, [<<"test-1">>]) + ), + ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"duplicated-secret-1">>)), + + ?assertMatch( + {ok, [ + #?APP{ + name = <<"from_bootstrap_file_de1c28a2e610e734">>, + api_key = <<"test-2">> + } + ]}, + emqx_mgmt_auth:trans(MatchFun, [<<"test-2">>]) + ), + ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"duplicated-secret-2">>)), + ok. + +t_bootstrap_file_dup_override(_) -> + TestPath = <<"/api/v5/status">>, + TestApiKey = <<"test-1">>, + Bin = <<"test-1:secret-1">>, + File = "./bootstrap_api_keys.txt", + ok = file:write_file(File, Bin), + update_file(File), + ?assertEqual(ok, emqx_mgmt_auth:init_bootstrap_file()), + + SameAppWithDiffName = #?APP{ + name = <<"name-1">>, + api_key = <<"test-1">>, + api_secret_hash = emqx_dashboard_admin:hash(<<"duplicated-secret-1">>), + enable = true, + desc = <<"dup api key">>, + created_at = erlang:system_time(second), + expired_at = infinity + }, + WriteFun = fun(App) -> mnesia:write(App) end, + MatchFun = fun(ApiKey) -> mnesia:match_object(#?APP{api_key = ApiKey, _ = '_'}) end, + + ?assertEqual({ok, ok}, emqx_mgmt_auth:trans(WriteFun, [SameAppWithDiffName])), + %% as erlang term order + ?assertMatch( + {ok, [ + #?APP{ + name = <<"name-1">>, + api_key = <<"test-1">> + }, + #?APP{ + name = <<"from_bootstrap_file_18926f94712af04e">>, + api_key = <<"test-1">> + } + ]}, + emqx_mgmt_auth:trans(MatchFun, [TestApiKey]) + ), + + update_file(File), + + %% Similar to loading bootstrap file at node startup + %% the duplicated apikey in mnesia will be cleaned up + ?assertEqual(ok, emqx_mgmt_auth:init_bootstrap_file()), + ?assertMatch( + {ok, [ + #?APP{ + name = <<"from_bootstrap_file_18926f94712af04e">>, + api_key = <<"test-1">> + } + ]}, + emqx_mgmt_auth:trans(MatchFun, [<<"test-1">>]) + ), + + %% the last apikey in bootstrap file will override the all in mnesia and the previous one(s) in bootstrap file + ?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-1">>)), + + ok. + update_file(File) -> ?assertMatch({ok, _}, emqx:update_config([<<"api_key">>], #{<<"bootstrap_file">> => File})).