From c3d24db642abb6286eb78ee7c6ed658c91342e17 Mon Sep 17 00:00:00 2001 From: Shawn <506895667@qq.com> Date: Fri, 16 Jul 2021 14:07:27 +0800 Subject: [PATCH] fix(authz): update emqx_authz for new config --- apps/emqx_authz/src/emqx_authz.erl | 20 +++--- apps/emqx_authz/src/emqx_authz_app.erl | 2 +- apps/emqx_authz/test/emqx_authz_SUITE.erl | 71 +++++++++++-------- .../test/emqx_authz_mongo_SUITE.erl | 41 +++++------ .../test/emqx_authz_mysql_SUITE.erl | 40 +++++------ .../test/emqx_authz_pgsql_SUITE.erl | 40 +++++------ .../test/emqx_authz_redis_SUITE.erl | 28 +++----- 7 files changed, 114 insertions(+), 128 deletions(-) diff --git a/apps/emqx_authz/src/emqx_authz.erl b/apps/emqx_authz/src/emqx_authz.erl index 78aa47d91..bb5991748 100644 --- a/apps/emqx_authz/src/emqx_authz.erl +++ b/apps/emqx_authz/src/emqx_authz.erl @@ -26,7 +26,7 @@ , compile/1 , lookup/0 , update/1 - , authorize/5 + , authorize/4 , match/4 ]). @@ -36,19 +36,16 @@ register_metrics() -> init() -> ok = register_metrics(), - Rules = emqx_config:get([emqx_authz, rules], []), - NRules = [compile(Rule) || Rule <- Rules], - ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1). + ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, []}, -1). lookup() -> emqx_config:get([emqx_authz, rules], []). update(Rules) -> emqx_config:put([emqx_authz], #{rules => Rules}), - NRules = [compile(Rule) || Rule <- Rules], Action = find_action_in_hooks(), ok = emqx_hooks:del('client.authorize', Action), - ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1), + ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, []}, -1), ok = emqx_acl_cache:empty_acl_cache(). %%-------------------------------------------------------------------- @@ -147,12 +144,11 @@ b2l(B) when is_binary(B) -> binary_to_list(B). %%-------------------------------------------------------------------- %% @doc Check AuthZ --spec(authorize(emqx_types:clientinfo(), emqx_types:all(), emqx_topic:topic(), emqx_permission_rule:acl_result(), rules()) - -> {stop, allow} | {ok, deny}). -authorize(#{username := Username, - peerhost := IpAddress - } = Client, PubSub, Topic, _DefaultResult, Rules) -> - case do_authorize(Client, PubSub, Topic, Rules) of +-spec(authorize(emqx_types:clientinfo(), emqx_types:all(), emqx_topic:topic(), + emqx_permission_rule:acl_result()) -> {stop, allow} | {ok, deny}). +authorize(#{username := Username, peerhost := IpAddress} = Client, + PubSub, Topic, _DefaultResult) -> + case do_authorize(Client, PubSub, Topic, [compile(Rule) || Rule <- lookup()]) of {matched, allow} -> ?LOG(info, "Client succeeded authorization: Username: ~p, IP: ~p, Topic: ~p, Permission: allow", [Username, IpAddress, Topic]), emqx_metrics:inc(?AUTHZ_METRICS(allow)), diff --git a/apps/emqx_authz/src/emqx_authz_app.erl b/apps/emqx_authz/src/emqx_authz_app.erl index dcce015c7..460d7cbf9 100644 --- a/apps/emqx_authz/src/emqx_authz_app.erl +++ b/apps/emqx_authz/src/emqx_authz_app.erl @@ -11,7 +11,7 @@ start(_StartType, _StartArgs) -> {ok, Sup} = emqx_authz_sup:start_link(), - %ok = emqx_authz:init(), + ok = emqx_authz:init(), {ok, Sup}. stop(_State) -> diff --git a/apps/emqx_authz/test/emqx_authz_SUITE.erl b/apps/emqx_authz/test/emqx_authz_SUITE.erl index 66b2e62de..81574330e 100644 --- a/apps/emqx_authz/test/emqx_authz_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_SUITE.erl @@ -29,23 +29,16 @@ groups() -> []. init_per_suite(Config) -> - ok = emqx_ct_helpers:start_apps([emqx_authz], fun set_special_configs/1), + ok = emqx_ct_helpers:start_apps([emqx_authz]), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, cache, enable], false), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, enable], true), + emqx_config:put([emqx_authz], #{rules => []}), Config. end_per_suite(_Config) -> file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), emqx_ct_helpers:stop_apps([emqx_authz]). -set_special_configs(emqx) -> - application:set_env(emqx, allow_anonymous, true), - application:set_env(emqx, enable_acl_cache, false), - ok; -set_special_configs(emqx_authz) -> - emqx_config:put([emqx_authz], #{rules => []}), - ok; -set_special_configs(_App) -> - ok. - -define(RULE1, #{principal => all, topics => [<<"#">>], action => all, @@ -86,7 +79,7 @@ t_compile(_) -> action => all, principal => all, topics => [['#']] - },emqx_authz:compile(?RULE1)), + }, emqx_authz:compile(?RULE1)), ?assertEqual(#{permission => allow, action => all, principal => @@ -121,44 +114,62 @@ t_compile(_) -> t_authz(_) -> ClientInfo1 = #{clientid => <<"test">>, username => <<"test">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, ClientInfo2 = #{clientid => <<"test">>, username => <<"test">>, - peerhost => {192,168,0,10} + peerhost => {192,168,0,10}, + zone => default, + listener => mqtt_tcp }, ClientInfo3 = #{clientid => <<"test">>, username => <<"fake">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, ClientInfo4 = #{clientid => <<"fake">>, username => <<"test">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, - Rules1 = [emqx_authz:compile(Rule) || Rule <- [?RULE1, ?RULE2]], - Rules2 = [emqx_authz:compile(Rule) || Rule <- [?RULE2, ?RULE1]], - Rules3 = [emqx_authz:compile(Rule) || Rule <- [?RULE3, ?RULE4]], - Rules4 = [emqx_authz:compile(Rule) || Rule <- [?RULE4, ?RULE1]], + Rules1 = [?RULE1, ?RULE2], + Rules2 = [?RULE2, ?RULE1], + Rules3 = [?RULE3, ?RULE4], + Rules4 = [?RULE4, ?RULE1], + emqx_config:put([emqx_authz], #{rules => []}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo1, subscribe, <<"#">>, deny, [])), + emqx_authz:authorize(ClientInfo1, subscribe, <<"#">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules1}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo1, subscribe, <<"+">>, deny, Rules1)), + emqx_authz:authorize(ClientInfo1, subscribe, <<"+">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules2}), ?assertEqual({stop, allow}, - emqx_authz:authorize(ClientInfo1, subscribe, <<"+">>, deny, Rules2)), + emqx_authz:authorize(ClientInfo1, subscribe, <<"+">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules3}), ?assertEqual({stop, allow}, - emqx_authz:authorize(ClientInfo1, publish, <<"test">>, deny, Rules3)), + emqx_authz:authorize(ClientInfo1, publish, <<"test">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules4}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo1, publish, <<"test">>, deny, Rules4)), + emqx_authz:authorize(ClientInfo1, publish, <<"test">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules2}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo2, subscribe, <<"#">>, deny, Rules2)), + emqx_authz:authorize(ClientInfo2, subscribe, <<"#">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules3}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo3, publish, <<"test">>, deny, Rules3)), + emqx_authz:authorize(ClientInfo3, publish, <<"test">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules4}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo3, publish, <<"fake">>, deny, Rules4)), + emqx_authz:authorize(ClientInfo3, publish, <<"fake">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules3}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo4, publish, <<"test">>, deny, Rules3)), + emqx_authz:authorize(ClientInfo4, publish, <<"test">>, deny)), + emqx_config:put([emqx_authz], #{rules => Rules4}), ?assertEqual({stop, deny}, - emqx_authz:authorize(ClientInfo4, publish, <<"fake">>, deny, Rules4)), + emqx_authz:authorize(ClientInfo4, publish, <<"fake">>, deny)), ok. diff --git a/apps/emqx_authz/test/emqx_authz_mongo_SUITE.erl b/apps/emqx_authz/test/emqx_authz_mongo_SUITE.erl index d2792e388..ab7ff548a 100644 --- a/apps/emqx_authz/test/emqx_authz_mongo_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_mongo_SUITE.erl @@ -31,22 +31,10 @@ groups() -> init_per_suite(Config) -> meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]), meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end ), - ok = emqx_ct_helpers:start_apps([emqx_authz], fun set_special_configs/1), - Config. - -end_per_suite(_Config) -> - file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), - emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), - meck:unload(emqx_resource). - -set_special_configs(emqx) -> - application:set_env(emqx, allow_anonymous, true), - application:set_env(emqx, enable_acl_cache, false), - application:set_env(emqx, acl_nomatch, deny), - application:set_env(emqx, plugins_loaded_file, - emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")), - ok; -set_special_configs(emqx_authz) -> + ok = emqx_ct_helpers:start_apps([emqx_authz]), + ct:pal("---- emqx_hooks: ~p", [ets:tab2list(emqx_hooks)]), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, cache, enable], false), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, enable], true), Rules = [#{config =>#{}, principal => all, collection => <<"fake">>, @@ -54,9 +42,12 @@ set_special_configs(emqx_authz) -> type => mongo} ], emqx_config:put([emqx_authz], #{rules => Rules}), - ok; -set_special_configs(_App) -> - ok. + Config. + +end_per_suite(_Config) -> + file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), + emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), + meck:unload(emqx_resource). -define(RULE1,[#{<<"topics">> => [<<"#">>], <<"permission">> => <<"deny">>, @@ -78,15 +69,21 @@ set_special_configs(_App) -> t_authz(_) -> ClientInfo1 = #{clientid => <<"test">>, username => <<"test">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, ClientInfo2 = #{clientid => <<"test_clientid">>, username => <<"test_username">>, - peerhost => {192,168,0,10} + peerhost => {192,168,0,10}, + zone => default, + listener => mqtt_tcp }, ClientInfo3 = #{clientid => <<"test_clientid">>, username => <<"fake_username">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, meck:expect(emqx_resource, query, fun(_, _) -> [] end), diff --git a/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl b/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl index a9acf5e36..0389ffd6e 100644 --- a/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_mysql_SUITE.erl @@ -31,31 +31,21 @@ groups() -> init_per_suite(Config) -> meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]), meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end ), - ok = emqx_ct_helpers:start_apps([emqx_authz], fun set_special_configs/1), - Config. - -end_per_suite(_Config) -> - file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), - emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), - meck:unload(emqx_resource). - -set_special_configs(emqx) -> - application:set_env(emqx, allow_anonymous, false), - application:set_env(emqx, enable_acl_cache, false), - application:set_env(emqx, acl_nomatch, deny), - application:set_env(emqx, plugins_loaded_file, - emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")), - ok; -set_special_configs(emqx_authz) -> + ok = emqx_ct_helpers:start_apps([emqx_authz]), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, cache, enable], false), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, enable], true), Rules = [#{config =>#{}, principal => all, sql => <<"fake">>, type => mysql} ], emqx_config:put([emqx_authz], #{rules => Rules}), - ok; -set_special_configs(_App) -> - ok. + Config. + +end_per_suite(_Config) -> + file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), + emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), + meck:unload(emqx_resource). -define(COLUMNS, [ <<"ipaddress">> , <<"username">> @@ -76,15 +66,21 @@ set_special_configs(_App) -> t_authz(_) -> ClientInfo1 = #{clientid => <<"test">>, username => <<"test">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, ClientInfo2 = #{clientid => <<"test_clientid">>, username => <<"test_username">>, - peerhost => {192,168,0,10} + peerhost => {192,168,0,10}, + zone => default, + listener => mqtt_tcp }, ClientInfo3 = #{clientid => <<"test_clientid">>, username => <<"fake_username">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, []} end), diff --git a/apps/emqx_authz/test/emqx_authz_pgsql_SUITE.erl b/apps/emqx_authz/test/emqx_authz_pgsql_SUITE.erl index 03bec2415..5c9c32551 100644 --- a/apps/emqx_authz/test/emqx_authz_pgsql_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_pgsql_SUITE.erl @@ -31,31 +31,21 @@ groups() -> init_per_suite(Config) -> meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]), meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end ), - ok = emqx_ct_helpers:start_apps([emqx_authz], fun set_special_configs/1), - Config. - -end_per_suite(_Config) -> - file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), - emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), - meck:unload(emqx_resource). - -set_special_configs(emqx) -> - application:set_env(emqx, allow_anonymous, false), - application:set_env(emqx, enable_acl_cache, false), - application:set_env(emqx, acl_nomatch, deny), - application:set_env(emqx, plugins_loaded_file, - emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")), - ok; -set_special_configs(emqx_authz) -> + ok = emqx_ct_helpers:start_apps([emqx_authz]), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, cache, enable], false), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, enable], true), Rules = [#{config =>#{}, principal => all, sql => <<"fake">>, type => pgsql} ], emqx_config:put([emqx_authz], #{rules => Rules}), - ok; -set_special_configs(_App) -> - ok. + Config. + +end_per_suite(_Config) -> + file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), + emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), + meck:unload(emqx_resource). -define(COLUMNS, [ {column, <<"ipaddress">>, meck, meck, meck, meck, meck, meck, meck} , {column, <<"username">>, meck, meck, meck, meck, meck, meck, meck} @@ -76,15 +66,21 @@ set_special_configs(_App) -> t_authz(_) -> ClientInfo1 = #{clientid => <<"test">>, username => <<"test">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, ClientInfo2 = #{clientid => <<"test_clientid">>, username => <<"test_username">>, - peerhost => {192,168,0,10} + peerhost => {192,168,0,10}, + zone => default, + listener => mqtt_tcp }, ClientInfo3 = #{clientid => <<"test_clientid">>, username => <<"fake_username">>, - peerhost => {127,0,0,1} + peerhost => {127,0,0,1}, + zone => default, + listener => mqtt_tcp }, meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, []} end), diff --git a/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl b/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl index 1e2264c29..233680884 100644 --- a/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_redis_SUITE.erl @@ -31,31 +31,21 @@ groups() -> init_per_suite(Config) -> meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]), meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end ), - ok = emqx_ct_helpers:start_apps([emqx_authz], fun set_special_configs/1), - Config. - -end_per_suite(_Config) -> - file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), - emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), - meck:unload(emqx_resource). - -set_special_configs(emqx) -> - application:set_env(emqx, allow_anonymous, true), - application:set_env(emqx, enable_acl_cache, false), - application:set_env(emqx, acl_nomatch, deny), - application:set_env(emqx, plugins_loaded_file, - emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")), - ok; -set_special_configs(emqx_authz) -> + ok = emqx_ct_helpers:start_apps([emqx_authz]), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, cache, enable], false), + emqx_config:put_listener_conf(default, mqtt_tcp, [acl, enable], true), Rules = [#{config =>#{}, principal => all, cmd => <<"fake">>, type => redis} ], emqx_config:put([emqx_authz], #{rules => Rules}), - ok; -set_special_configs(_App) -> - ok. + Config. + +end_per_suite(_Config) -> + file:delete(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf')), + emqx_ct_helpers:stop_apps([emqx_authz, emqx_resource]), + meck:unload(emqx_resource). -define(RULE1, [<<"test/%u">>, <<"publish">>]). -define(RULE2, [<<"test/%c">>, <<"publish">>]).