Просмотр исходного кода

test: cleanup duplicated apikey with different name

JimMoen 2 лет назад
Родитель
Сommit
e6576951ef

+ 2 - 0
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).

+ 104 - 0
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})).