Преглед изворни кода

Merge pull request #13398 from zhongwencool/authz-db-clear-table

fix: don't destory when authz'source unchanged
zhongwencool пре 1 година
родитељ
комит
5f321702e7

+ 26 - 12
apps/emqx_auth/src/emqx_authz/emqx_authz.erl

@@ -327,18 +327,32 @@ do_post_config_update(?ROOT_KEY, _Conf, NewConf) ->
 
 overwrite_entire_sources(Sources) ->
     PrevSources = lookup(),
-    NewSourcesTypes = lists:map(fun type/1, Sources),
-    EnsureDelete = fun(S) ->
-        TypeName = type(S),
-        Opts =
-            case lists:member(TypeName, NewSourcesTypes) of
-                true -> #{clear_metric => false};
-                false -> #{clear_metric => true}
-            end,
-        ensure_deleted(S, Opts)
-    end,
-    lists:foreach(EnsureDelete, PrevSources),
-    create_sources(Sources).
+    #{
+        removed := Removed,
+        added := Added,
+        identical := Identical,
+        changed := Changed
+    } = emqx_utils:diff_lists(Sources, PrevSources, fun type/1),
+    lists:foreach(
+        fun(S) -> ensure_deleted(S, #{clear_metric => true}) end,
+        Removed
+    ),
+    AddedSources = create_sources(Added),
+    ChangedSources = lists:map(
+        fun({Old, New}) ->
+            update_source(type(New), Old, New)
+        end,
+        Changed
+    ),
+    New = Identical ++ AddedSources ++ ChangedSources,
+    lists:map(
+        fun(Type) ->
+            SearchFun = fun(S) -> type(S) =:= type(Type) end,
+            {value, Val} = lists:search(SearchFun, New),
+            Val
+        end,
+        Sources
+    ).
 
 %% @doc do source move
 do_move({?CMD_MOVE, Type, ?CMD_MOVE_FRONT}, Sources) ->

+ 24 - 0
apps/emqx_auth_mnesia/test/emqx_authz_mnesia_SUITE.erl

@@ -256,6 +256,30 @@ t_destroy(_Config) ->
         emqx_access_control:authorize(ClientInfo, ?AUTHZ_PUBLISH, <<"t">>)
     ).
 
+t_conf_cli_load(_Config) ->
+    ClientInfo = emqx_authz_test_lib:base_client_info(),
+
+    ok = emqx_authz_mnesia:store_rules(
+        {username, <<"username">>},
+        [#{<<"permission">> => <<"allow">>, <<"action">> => <<"publish">>, <<"topic">> => <<"t">>}]
+    ),
+
+    ?assertEqual(
+        allow,
+        emqx_access_control:authorize(ClientInfo, ?AUTHZ_PUBLISH, <<"t">>)
+    ),
+    PrevRules = ets:tab2list(emqx_acl),
+    Hocon = emqx_conf_cli:get_config("authorization"),
+    Bin = iolist_to_binary(hocon_pp:do(Hocon, #{})),
+    ok = emqx_conf_cli:load_config(Bin, #{mode => merge}),
+    %% ensure emqx_acl table not clear
+    ?assertEqual(PrevRules, ets:tab2list(emqx_acl)),
+    %% still working
+    ?assertEqual(
+        allow,
+        emqx_access_control:authorize(ClientInfo, ?AUTHZ_PUBLISH, <<"t">>)
+    ).
+
 %%------------------------------------------------------------------------------
 %% Helpers
 %%------------------------------------------------------------------------------