Browse Source

Merge pull request #7650 from JimMoen/add-authz-cache-api

add authz clean cache api
JianBo He 3 years ago
parent
commit
96c9fbca07

+ 1 - 1
Makefile

@@ -8,7 +8,7 @@ export EMQX_DEFAULT_BUILDER = ghcr.io/emqx/emqx-builder/5.0-10:1.13.3-24.2.1-1-a
 export EMQX_DEFAULT_RUNNER = alpine:3.15.1
 export EMQX_DEFAULT_RUNNER = alpine:3.15.1
 export OTP_VSN ?= $(shell $(CURDIR)/scripts/get-otp-vsn.sh)
 export OTP_VSN ?= $(shell $(CURDIR)/scripts/get-otp-vsn.sh)
 export ELIXIR_VSN ?= $(shell $(CURDIR)/scripts/get-elixir-vsn.sh)
 export ELIXIR_VSN ?= $(shell $(CURDIR)/scripts/get-elixir-vsn.sh)
-export EMQX_DASHBOARD_VERSION ?= v0.28.0
+export EMQX_DASHBOARD_VERSION ?= v0.29.0
 export DOCKERFILE := deploy/docker/Dockerfile
 export DOCKERFILE := deploy/docker/Dockerfile
 export EMQX_REL_FORM ?= tgz
 export EMQX_REL_FORM ?= tgz
 ifeq ($(OS),Windows_NT)
 ifeq ($(OS),Windows_NT)

+ 74 - 0
apps/emqx_authz/src/emqx_authz_api_cache.erl

@@ -0,0 +1,74 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2020-2022 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_authz_api_cache).
+
+-behaviour(minirest_api).
+
+-export([
+    api_spec/0,
+    paths/0,
+    schema/1
+]).
+
+-export([
+    clean_cache/2
+]).
+
+-define(BAD_REQUEST, 'BAD_REQUEST').
+
+api_spec() ->
+    emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}).
+
+paths() ->
+    [
+        "/authorization/cache"
+    ].
+
+%%--------------------------------------------------------------------
+%% Schema for each URI
+%%--------------------------------------------------------------------
+
+schema("/authorization/cache") ->
+    #{
+        'operationId' => clean_cache,
+        delete =>
+            #{
+                description => <<"Clean all authorization cache in the cluster.">>,
+                responses =>
+                    #{
+                        204 => <<"No Content">>,
+                        400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad Request">>)
+                    }
+            }
+    }.
+
+clean_cache(delete, _) ->
+    case emqx_mgmt:clean_authz_cache_all() of
+        ok ->
+            {204};
+        {error, Reason} ->
+            {400, #{
+                code => <<"BAD_REQUEST">>,
+                message => bin(Reason)
+            }}
+    end.
+
+%%--------------------------------------------------------------------
+%% Internal functions
+%%--------------------------------------------------------------------
+
+bin(Term) -> erlang:iolist_to_binary(io_lib:format("~p", [Term])).

+ 79 - 0
apps/emqx_authz/test/emqx_authz_api_cache_SUITE.erl

@@ -0,0 +1,79 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2020-2022 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_authz_api_cache_SUITE).
+
+-compile(nowarn_export_all).
+-compile(export_all).
+
+-import(emqx_dashboard_api_test_helpers, [request/2, uri/1]).
+
+-include_lib("eunit/include/eunit.hrl").
+-include_lib("common_test/include/ct.hrl").
+
+all() ->
+    emqx_common_test_helpers:all(?MODULE).
+
+groups() ->
+    [].
+
+init_per_suite(Config) ->
+    ok = emqx_common_test_helpers:start_apps(
+        [emqx_conf, emqx_authz, emqx_dashboard, emqx_management],
+        fun set_special_configs/1
+    ),
+    Config.
+
+end_per_suite(_Config) ->
+    {ok, _} = emqx:update_config(
+        [authorization],
+        #{
+            <<"no_match">> => <<"allow">>,
+            <<"cache">> => #{<<"enable">> => <<"true">>},
+            <<"sources">> => []
+        }
+    ),
+    ok = stop_apps([emqx_resource, emqx_connector]),
+    emqx_common_test_helpers:stop_apps([emqx_dashboard, emqx_authz, emqx_conf, emqx_management]),
+    ok.
+
+set_special_configs(emqx_dashboard) ->
+    emqx_dashboard_api_test_helpers:set_default_config();
+set_special_configs(emqx_authz) ->
+    {ok, _} = emqx:update_config([authorization, cache, enable], true),
+    {ok, _} = emqx:update_config([authorization, no_match], deny),
+    {ok, _} = emqx:update_config([authorization, sources], []),
+    ok;
+set_special_configs(_App) ->
+    ok.
+
+t_clean_cahce(_) ->
+    {ok, C} = emqtt:start_link([{clientid, <<"emqx0">>}, {username, <<"emqx0">>}]),
+    {ok, _} = emqtt:connect(C),
+    {ok, _, _} = emqtt:subscribe(C, <<"a/b/c">>, 0),
+    ok = emqtt:publish(C, <<"a/b/c">>, <<"{\"x\":1,\"y\":1}">>, 0),
+
+    {ok, 200, Result3} = request(get, uri(["clients", "emqx0", "authorization", "cache"])),
+    ?assertEqual(2, length(jsx:decode(Result3))),
+
+    request(delete, uri(["authorization", "cache"])),
+
+    {ok, 200, Result4} = request(get, uri(["clients", "emqx0", "authorization", "cache"])),
+    ?assertEqual(0, length(jsx:decode(Result4))),
+
+    ok.
+
+stop_apps(Apps) ->
+    lists:foreach(fun application:stop/1, Apps).

+ 4 - 4
apps/emqx_management/src/emqx_mgmt_api_clients.erl

@@ -78,7 +78,7 @@ api_spec() ->
 paths() ->
 paths() ->
     [ "/clients"
     [ "/clients"
     , "/clients/:clientid"
     , "/clients/:clientid"
-    , "/clients/:clientid/authz_cache"
+    , "/clients/:clientid/authorization/cache"
     , "/clients/:clientid/subscriptions"
     , "/clients/:clientid/subscriptions"
     , "/clients/:clientid/subscribe"
     , "/clients/:clientid/subscribe"
     , "/clients/:clientid/unsubscribe"
     , "/clients/:clientid/unsubscribe"
@@ -190,11 +190,11 @@ schema("/clients/:clientid") ->
         }
         }
     };
     };
 
 
-schema("/clients/:clientid/authz_cache") ->
+schema("/clients/:clientid/authorization/cache") ->
     #{
     #{
         'operationId' => authz_cache,
         'operationId' => authz_cache,
         get => #{
         get => #{
-            description => <<"Get client authz cache">>,
+            description => <<"Get client authz cache in the cluster.">>,
             parameters => [{clientid, hoconsc:mk(binary(), #{in => path})}],
             parameters => [{clientid, hoconsc:mk(binary(), #{in => path})}],
             responses => #{
             responses => #{
                 200 => hoconsc:mk(hoconsc:ref(?MODULE, authz_cache), #{}),
                 200 => hoconsc:mk(hoconsc:ref(?MODULE, authz_cache), #{}),
@@ -203,7 +203,7 @@ schema("/clients/:clientid/authz_cache") ->
             }
             }
         },
         },
         delete => #{
         delete => #{
-            description => <<"Clean client authz cache">>,
+            description => <<"Clean client authz cache in the cluster.">>,
             parameters => [{clientid, hoconsc:mk(binary(), #{in => path})}],
             parameters => [{clientid, hoconsc:mk(binary(), #{in => path})}],
             responses => #{
             responses => #{
                 204 => <<"Kick out client successfully">>,
                 204 => <<"Kick out client successfully">>,

+ 2 - 2
apps/emqx_management/test/emqx_mgmt_api_clients_SUITE.erl

@@ -76,9 +76,9 @@ t_clients(_) ->
     AfterKickoutResponse2 = emqx_mgmt_api_test_util:request_api(get, Client2Path),
     AfterKickoutResponse2 = emqx_mgmt_api_test_util:request_api(get, Client2Path),
     ?assertEqual({error, {"HTTP/1.1", 404, "Not Found"}}, AfterKickoutResponse2),
     ?assertEqual({error, {"HTTP/1.1", 404, "Not Found"}}, AfterKickoutResponse2),
 
 
-    %% get /clients/:clientid/authz_cache should has no authz cache
+    %% get /clients/:clientid/authorization/cache should has no authz cache
     Client1AuthzCachePath = emqx_mgmt_api_test_util:api_path(["clients",
     Client1AuthzCachePath = emqx_mgmt_api_test_util:api_path(["clients",
-        binary_to_list(ClientId1), "authz_cache"]),
+        binary_to_list(ClientId1), "authorization", "cache"]),
     {ok, Client1AuthzCache} = emqx_mgmt_api_test_util:request_api(get, Client1AuthzCachePath),
     {ok, Client1AuthzCache} = emqx_mgmt_api_test_util:request_api(get, Client1AuthzCachePath),
     ?assertEqual("[]", Client1AuthzCache),
     ?assertEqual("[]", Client1AuthzCache),