From 07c29e8c5555750f45ae63e7cf2bc5b388f0d0e1 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Tue, 27 Jul 2021 17:56:09 +0800 Subject: [PATCH] chore(acl): support ipaddr list --- etc/acl.conf | 1 + src/emqx_access_rule.erl | 11 ++++++++++- test/emqx_access_rule_SUITE.erl | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/etc/acl.conf b/etc/acl.conf index af2fb0dd1..444ad486a 100644 --- a/etc/acl.conf +++ b/etc/acl.conf @@ -3,6 +3,7 @@ %% %% -type(who() :: all | binary() | %% {ipaddr, esockd_access:cidr()} | +%% {ipaddrs, [esockd_access:cidr()]} | %% {client, binary()} | %% {user, binary()}). %% diff --git a/src/emqx_access_rule.erl b/src/emqx_access_rule.erl index 5a607dd16..49831d614 100644 --- a/src/emqx_access_rule.erl +++ b/src/emqx_access_rule.erl @@ -28,7 +28,8 @@ -type(who() :: all | binary() | {client, binary()} | {user, binary()} | - {ipaddr, esockd_cidr:cidr_string()}). + {ipaddr, esockd_cidr:cidr_string()} | + {ipaddrs, list(esockd_cidr:cidr_string())}). -type(access() :: subscribe | publish | pubsub). @@ -52,6 +53,8 @@ compile(who, all) -> all; compile(who, {ipaddr, CIDR}) -> {ipaddr, esockd_cidr:parse(CIDR, true)}; +compile(who, {ipaddrs, CIDRs}) -> + {ipaddrs, lists:map(fun(CIDR) -> esockd_cidr:parse(CIDR, true) end, CIDRs)}; compile(who, {client, all}) -> {client, all}; compile(who, {client, ClientId}) -> @@ -107,8 +110,14 @@ match_who(#{username := Username}, {user, Username}) -> true; match_who(#{peerhost := undefined}, {ipaddr, _Tup}) -> false; +match_who(#{peerhost := undefined}, {ipaddrs, _}) -> + false; match_who(#{peerhost := IP}, {ipaddr, CIDR}) -> esockd_cidr:match(IP, CIDR); +match_who(#{peerhost := IP}, {ipaddrs, CIDRs}) -> + lists:any(fun(CIDR) -> + esockd_cidr:match(IP, CIDR) + end, CIDRs); match_who(ClientInfo, {'and', Conds}) when is_list(Conds) -> lists:foldl(fun(Who, Allow) -> match_who(ClientInfo, Who) andalso Allow diff --git a/test/emqx_access_rule_SUITE.erl b/test/emqx_access_rule_SUITE.erl index 93c84a958..0eb06ce2f 100644 --- a/test/emqx_access_rule_SUITE.erl +++ b/test/emqx_access_rule_SUITE.erl @@ -44,10 +44,18 @@ t_compile(_) -> Rule4 = {allow, {'or', [{client, all}, {user, all}]}, pubsub, [ <<"testTopics1">>, <<"testTopics2">>]}, Compile4 = {allow, {'or', [{client, all}, {user, all}]}, pubsub, [[<<"testTopics1">>], [<<"testTopics2">>]]}, + Rule5 = {allow, {ipaddrs, ["127.0.0.1", "192.168.1.0/24"]}, pubsub, <<"%c">>}, + Compile5 = {allow, {ipaddrs,[{{127,0,0,1},{127,0,0,1},32}, + {{192,168,1,0},{192,168,1,255},24}]}, + pubsub, + [{pattern,[<<"%c">>]}] + }, + ?assertEqual(Compile1, emqx_access_rule:compile(Rule1)), ?assertEqual(Compile2, emqx_access_rule:compile(Rule2)), ?assertEqual(Compile3, emqx_access_rule:compile(Rule3)), - ?assertEqual(Compile4, emqx_access_rule:compile(Rule4)). + ?assertEqual(Compile4, emqx_access_rule:compile(Rule4)), + ?assertEqual(Compile5, emqx_access_rule:compile(Rule5)). t_match(_) -> ClientInfo1 = #{zone => external, @@ -94,4 +102,6 @@ t_match(_) -> ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"Topic">>, emqx_access_rule:compile({allow, {'and', [{ipaddr, "127.0.0.1"}, {user, <<"TestUser">>}]}, publish, <<"Topic">>}))), ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo1, <<"Topic">>, - emqx_access_rule:compile({allow, {'or', [{ipaddr, "127.0.0.1"}, {user, <<"WrongUser">>}]}, publish, ["Topic"]}))). + emqx_access_rule:compile({allow, {'or', [{ipaddr, "127.0.0.1"}, {user, <<"WrongUser">>}]}, publish, ["Topic"]}))), + ?assertEqual({matched, allow}, emqx_access_rule:match(ClientInfo2, <<"Topic">>, + emqx_access_rule:compile({allow, {ipaddrs, ["127.0.0.1", "192.168.0.0/24"]}, publish, ["Topic"]}))).