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

chore(authz): test Mongo backend with real Mongo

Ilya Averyanov 4 лет назад
Родитель
Сommit
a21f67a67e

+ 1 - 1
apps/emqx_authz/src/emqx_authz_mongodb.erl

@@ -97,7 +97,7 @@ replvar(Selector, #{clientid := Clientid,
                                  , bin(Clientid), [global, {return, binary}]),
                   V2 = re:replace( V1, emqx_authz:ph_to_re(?PH_S_USERNAME)
                                  , bin(Username), [global, {return, binary}]),
-                  V3 = re:replace( V2, emqx_authz:ph_to_re(?PH_S_HOST)
+                  V3 = re:replace( V2, emqx_authz:ph_to_re(?PH_S_PEERHOST)
                                  , inet_parse:ntoa(IpAddress), [global, {return, binary}]),
                   maps:put(K, V3, AccIn);
               InFun(K, V, AccIn) -> maps:put(K, V, AccIn)

+ 75 - 97
apps/emqx_authz/test/emqx_authz_mongodb_SUITE.erl

@@ -69,7 +69,6 @@ set_special_configs(_) ->
 %% Testcases
 %%------------------------------------------------------------------------------
 
-
 t_topic_rules(_Config) ->
     ClientInfo = #{clientid => <<"clientid">>,
                    username => <<"username">>,
@@ -78,106 +77,14 @@ t_topic_rules(_Config) ->
                    listener => {tcp, default}
                   },
 
-    %% No rules
-
-    ok = setup_samples([]),
-    ok = setup_config(#{}),
-
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{deny, subscribe, <<"#">>},
-            {deny, subscribe, <<"subs">>},
-            {deny, publish, <<"pub">>}]),
-
-    %% Publish rules
-
-    Samples0 = populate_records(
-                 [#{<<"topics">> => [<<"eq testpub1/${username}">>]},
-                  #{<<"topics">> => [<<"testpub2/${clientid}">>, <<"testpub3/#">>]}],
-                 #{<<"permission">> => <<"allow">>,
-                   <<"action">> => <<"publish">>,
-                   <<"username">> => <<"username">>}),
-
-    ok = setup_samples(Samples0),
-    ok = setup_config(#{}),
-
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{deny, publish, <<"testpub1/username">>},
-            {allow, publish, <<"testpub1/${username}">>},
-            {allow, publish, <<"testpub2/clientid">>},
-            {allow, publish, <<"testpub3/foobar">>},
-
-            {deny, publish, <<"testpub2/username">>},
-            {deny, publish, <<"testpub1/clientid">>},
-
-
-            {deny, subscribe, <<"testpub1/username">>},
-            {deny, subscribe, <<"testpub2/clientid">>},
-            {deny, subscribe, <<"testpub3/foobar">>}]),
+    ok = emqx_authz_test_lib:test_no_topic_rules(ClientInfo, fun setup_client_samples/2),
 
-    %% Subscribe rules
-
-    Samples1 = populate_records(
-                 [#{<<"topics">> => [<<"eq testsub1/${username}">>]},
-                  #{<<"topics">> => [<<"testsub2/${clientid}">>, <<"testsub3/#">>]}],
-                 #{<<"permission">> => <<"allow">>,
-                   <<"action">> => <<"subscribe">>,
-                   <<"username">> => <<"username">>}),
-
-    ok = setup_samples(Samples1),
-    ok = setup_config(#{}),
-
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{deny, subscribe, <<"testsub1/username">>},
-            {allow, subscribe, <<"testsub1/${username}">>},
-            {allow, subscribe, <<"testsub2/clientid">>},
-            {allow, subscribe, <<"testsub3/foobar">>},
-            {allow, subscribe, <<"testsub3/+/foobar">>},
-            {allow, subscribe, <<"testsub3/#">>},
-
-            {deny, subscribe, <<"testsub2/username">>},
-            {deny, subscribe, <<"testsub1/clientid">>},
-            {deny, subscribe, <<"testsub4/foobar">>},
-            {deny, publish, <<"testsub1/username">>},
-            {deny, publish, <<"testsub2/clientid">>},
-            {deny, publish, <<"testsub3/foobar">>}]),
-
-    %% All rules
-
-    Samples2 = populate_records(
-                 [#{<<"topics">> => [<<"eq testall1/${username}">>]},
-                  #{<<"topics">> => [<<"testall2/${clientid}">>, <<"testall3/#">>]}],
-                 #{<<"permission">> => <<"allow">>,
-                   <<"action">> => <<"all">>,
-                   <<"username">> => <<"username">>}),
-
-    ok = setup_samples(Samples2),
-    ok = setup_config(#{}),
-
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{deny, subscribe, <<"testall1/username">>},
-            {allow, subscribe, <<"testall1/${username}">>},
-            {allow, subscribe, <<"testall2/clientid">>},
-            {allow, subscribe, <<"testall3/foobar">>},
-            {allow, subscribe, <<"testall3/+/foobar">>},
-            {allow, subscribe, <<"testall3/#">>},
-            {deny, publish, <<"testall1/username">>},
-            {allow, publish, <<"testall1/${username}">>},
-            {allow, publish, <<"testall2/clientid">>},
-            {allow, publish, <<"testall3/foobar">>},
-
-            {deny, subscribe, <<"testall2/username">>},
-            {deny, subscribe, <<"testall1/clientid">>},
-            {deny, subscribe, <<"testall4/foobar">>},
-            {deny, publish, <<"testall2/username">>},
-            {deny, publish, <<"testall1/clientid">>},
-            {deny, publish, <<"testall4/foobar">>}]).
+    ok = emqx_authz_test_lib:test_allow_topic_rules(ClientInfo, fun setup_client_samples/2),
 
+    ok = emqx_authz_test_lib:test_deny_topic_rules(ClientInfo, fun setup_client_samples/2).
 
 t_complex_selector(_) ->
+    %% atom and string values also supported
     ClientInfo = #{clientid => clientid,
                    username => "username",
                    peerhost => {127,0,0,1},
@@ -205,6 +112,60 @@ t_complex_selector(_) ->
            ClientInfo,
            [{allow, publish, <<"t">>}]).
 
+t_mongo_error(_Config) ->
+    ClientInfo = #{clientid => <<"clientid">>,
+                   username => <<"username">>,
+                   peerhost => {127,0,0,1},
+                   zone => default,
+                   listener => {tcp, default}
+                  },
+
+    ok = setup_samples([]),
+    ok = setup_config(
+           #{<<"selector">> => #{<<"$badoperator">> => <<"$badoperator">>}}),
+
+    ok = emqx_authz_test_lib:test_samples(
+           ClientInfo,
+           [{deny, publish, <<"t">>}]).
+
+t_lookups(_Config) ->
+    ClientInfo = #{clientid => <<"clientid">>,
+                   cn => <<"cn">>,
+                   dn => <<"dn">>,
+                   username => <<"username">>,
+                   peerhost => {127,0,0,1},
+                   zone => default,
+                   listener => {tcp, default}
+                  },
+
+    ByClientid = #{<<"clientid">> => <<"clientid">>,
+                   <<"topics">> => [<<"a">>],
+                   <<"action">> => <<"all">>,
+                   <<"permission">> => <<"allow">>},
+
+    ok = setup_samples([ByClientid]),
+    ok = setup_config(
+           #{<<"selector">> => #{<<"clientid">> => <<"${clientid}">>}}),
+
+    ok = emqx_authz_test_lib:test_samples(
+           ClientInfo,
+           [{allow, subscribe, <<"a">>},
+            {deny, subscribe, <<"b">>}]),
+
+    ByPeerhost = #{<<"peerhost">> => <<"127.0.0.1">>,
+                   <<"topics">> => [<<"a">>],
+                   <<"action">> => <<"all">>,
+                   <<"permission">> => <<"allow">>},
+
+    ok = setup_samples([ByPeerhost]),
+    ok = setup_config(
+           #{<<"selector">> => #{<<"peerhost">> => <<"${peerhost}">>}}),
+
+    ok = emqx_authz_test_lib:test_samples(
+           ClientInfo,
+           [{allow, subscribe, <<"a">>},
+            {deny, subscribe, <<"b">>}]).
+
 %%------------------------------------------------------------------------------
 %% Helpers
 %%------------------------------------------------------------------------------
@@ -217,6 +178,23 @@ setup_samples(AclRecords) ->
     {{true, _}, _} = mc_worker_api:insert(?MONGO_CLIENT, <<"acl">>, AclRecords),
     ok.
 
+setup_client_samples(ClientInfo, Samples) ->
+    #{username := Username} = ClientInfo,
+    Records = lists:map(
+                fun(Sample) ->
+                        #{topics := Topics,
+                          permission := Permission,
+                          action := Action} = Sample,
+
+                        #{<<"topics">> => Topics,
+                          <<"permission">> => Permission,
+                          <<"action">> => Action,
+                          <<"username">> => Username}
+                end,
+                Samples),
+    setup_samples(Records),
+    setup_config(#{<<"selector">> => #{<<"username">> => <<"${username}">>}}).
+
 reset_samples() ->
     {true, _} = mc_worker_api:delete(?MONGO_CLIENT, <<"acl">>, #{}),
     ok.

+ 19 - 88
apps/emqx_authz/test/emqx_authz_redis_SUITE.erl

@@ -76,96 +76,10 @@ t_topic_rules(_Config) ->
                    listener => {tcp, default}
                   },
 
-    %% No rules
+    ok = emqx_authz_test_lib:test_no_topic_rules(ClientInfo, fun setup_client_samples/2),
 
-    ok = setup_sample(#{}),
-    ok = setup_config(#{}),
+    ok = emqx_authz_test_lib:test_allow_topic_rules(ClientInfo, fun setup_client_samples/2).
 
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{deny, subscribe, <<"#">>},
-            {deny, subscribe, <<"subs">>},
-            {deny, publish, <<"pub">>}]),
-
-    %% Publish rules
-
-    Sample0 = #{<<"mqtt_user:username">> =>
-                   #{<<"testpub1/${username}">> => <<"publish">>,
-                     <<"testpub2/${clientid}">> => <<"publish">>,
-                     <<"testpub3/#">> => <<"publish">>
-                    }
-              },
-    ok = setup_sample(Sample0),
-    ok = setup_config(#{}),
-
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{allow, publish, <<"testpub1/username">>},
-            {allow, publish, <<"testpub2/clientid">>},
-            {allow, publish, <<"testpub3/foobar">>},
-
-            {deny, publish, <<"testpub2/username">>},
-            {deny, publish, <<"testpub1/clientid">>},
-
-
-            {deny, subscribe, <<"testpub1/username">>},
-            {deny, subscribe, <<"testpub2/clientid">>},
-            {deny, subscribe, <<"testpub3/foobar">>}]),
-
-    %% Subscribe rules
-
-    Sample1 = #{<<"mqtt_user:username">> =>
-                   #{<<"testsub1/${username}">> => <<"subscribe">>,
-                     <<"testsub2/${clientid}">> => <<"subscribe">>,
-                     <<"testsub3/#">> => <<"subscribe">>
-                    }
-              },
-    ok = setup_sample(Sample1),
-    ok = setup_config(#{}),
-
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{allow, subscribe, <<"testsub1/username">>},
-            {allow, subscribe, <<"testsub2/clientid">>},
-            {allow, subscribe, <<"testsub3/foobar">>},
-            {allow, subscribe, <<"testsub3/+/foobar">>},
-            {allow, subscribe, <<"testsub3/#">>},
-
-            {deny, subscribe, <<"testsub2/username">>},
-            {deny, subscribe, <<"testsub1/clientid">>},
-            {deny, subscribe, <<"testsub4/foobar">>},
-            {deny, publish, <<"testsub1/username">>},
-            {deny, publish, <<"testsub2/clientid">>},
-            {deny, publish, <<"testsub3/foobar">>}]),
-
-    %% All rules
-
-    Sample2 = #{<<"mqtt_user:username">> =>
-                   #{<<"testall1/${username}">> => <<"all">>,
-                     <<"testall2/${clientid}">> => <<"all">>,
-                     <<"testall3/#">> => <<"all">>
-                    }
-              },
-    ok = setup_sample(Sample2),
-    ok = setup_config(#{}),
-
-    ok = emqx_authz_test_lib:test_samples(
-           ClientInfo,
-           [{allow, subscribe, <<"testall1/username">>},
-            {allow, subscribe, <<"testall2/clientid">>},
-            {allow, subscribe, <<"testall3/foobar">>},
-            {allow, subscribe, <<"testall3/+/foobar">>},
-            {allow, subscribe, <<"testall3/#">>},
-            {allow, publish, <<"testall1/username">>},
-            {allow, publish, <<"testall2/clientid">>},
-            {allow, publish, <<"testall3/foobar">>},
-
-            {deny, subscribe, <<"testall2/username">>},
-            {deny, subscribe, <<"testall1/clientid">>},
-            {deny, subscribe, <<"testall4/foobar">>},
-            {deny, publish, <<"testall2/username">>},
-            {deny, publish, <<"testall1/clientid">>},
-            {deny, publish, <<"testall4/foobar">>}]).
 
 t_lookups(_Config) ->
     ClientInfo = #{clientid => <<"clientid">>,
@@ -267,6 +181,23 @@ setup_sample(AuthzData) ->
            end,
            maps:to_list(AuthzData)).
 
+setup_client_samples(ClientInfo, Samples) ->
+    #{username := Username} = ClientInfo,
+    Key = <<"mqtt_user:", Username/binary>>,
+    lists:foreach(
+      fun(Sample) ->
+              #{topics := Topics,
+                permission := <<"allow">>,
+                action := Action} = Sample,
+              lists:foreach(
+                fun(Topic) ->
+                        q(["HSET", Key, Topic, Action])
+                end,
+                Topics)
+      end,
+      Samples),
+    setup_config(#{}).
+
 setup_config(SpecialParams) ->
     ok = emqx_authz_test_lib:reset_authorizers(deny, false),
     Config = maps:merge(raw_redis_authz_config(), SpecialParams),

+ 191 - 8
apps/emqx_authz/test/emqx_authz_test_lib.erl

@@ -41,6 +41,15 @@ setup_config(BaseConfig, SpecialParams) ->
     {ok, _} = emqx_authz:update(?CMD_REPLACE, [Config]),
     ok.
 
+is_tcp_server_available(Host, Port) ->
+    case gen_tcp:connect(Host, Port, [], ?DEFAULT_CHECK_AVAIL_TIMEOUT) of
+        {ok, Socket} ->
+            gen_tcp:close(Socket),
+            true;
+        {error, _} ->
+            false
+    end.
+
 test_samples(ClientInfo, Samples) ->
     lists:foreach(
       fun({Expected, Action, Topic}) ->
@@ -56,11 +65,185 @@ test_samples(ClientInfo, Samples) ->
       end,
       Samples).
 
-is_tcp_server_available(Host, Port) ->
-    case gen_tcp:connect(Host, Port, [], ?DEFAULT_CHECK_AVAIL_TIMEOUT) of
-        {ok, Socket} ->
-            gen_tcp:close(Socket),
-            true;
-        {error, _} ->
-            false
-    end.
+test_no_topic_rules(ClientInfo, SetupSamples) ->
+    %% No rules
+
+    ok = SetupSamples(ClientInfo, []),
+
+    ok = test_samples(
+           ClientInfo,
+           [{deny, subscribe, <<"#">>},
+            {deny, subscribe, <<"subs">>},
+            {deny, publish, <<"pub">>}]).
+
+test_allow_topic_rules(ClientInfo, SetupSamples) ->
+    Samples = [#{
+                 topics => [<<"eq testpub1/${username}">>,
+                            <<"testpub2/${clientid}">>,
+                            <<"testpub3/#">>],
+                 permission => <<"allow">>,
+                 action => <<"publish">>
+                },
+               #{
+                 topics => [<<"eq testsub1/${username}">>,
+                            <<"testsub2/${clientid}">>,
+                            <<"testsub3/#">>],
+                 permission => <<"allow">>,
+                 action => <<"subscribe">>
+                },
+
+               #{
+                 topics => [<<"eq testall1/${username}">>,
+                            <<"testall2/${clientid}">>,
+                            <<"testall3/#">>],
+                 permission => <<"allow">>,
+                 action => <<"all">>
+                }
+              ],
+
+    ok = SetupSamples(ClientInfo, Samples),
+
+    ok = test_samples(
+           ClientInfo,
+           [
+
+            %% Publish rules
+
+            {deny, publish, <<"testpub1/username">>},
+            {allow, publish, <<"testpub1/${username}">>},
+            {allow, publish, <<"testpub2/clientid">>},
+            {allow, publish, <<"testpub3/foobar">>},
+
+            {deny, publish, <<"testpub2/username">>},
+            {deny, publish, <<"testpub1/clientid">>},
+
+
+            {deny, subscribe, <<"testpub1/username">>},
+            {deny, subscribe, <<"testpub2/clientid">>},
+            {deny, subscribe, <<"testpub3/foobar">>},
+
+            %% Subscribe rules
+
+            {deny, subscribe, <<"testsub1/username">>},
+            {allow, subscribe, <<"testsub1/${username}">>},
+            {allow, subscribe, <<"testsub2/clientid">>},
+            {allow, subscribe, <<"testsub3/foobar">>},
+            {allow, subscribe, <<"testsub3/+/foobar">>},
+            {allow, subscribe, <<"testsub3/#">>},
+
+            {deny, subscribe, <<"testsub2/username">>},
+            {deny, subscribe, <<"testsub1/clientid">>},
+            {deny, subscribe, <<"testsub4/foobar">>},
+            {deny, publish, <<"testsub1/username">>},
+            {deny, publish, <<"testsub2/clientid">>},
+            {deny, publish, <<"testsub3/foobar">>},
+
+            %% All rules
+
+            {deny, subscribe, <<"testall1/username">>},
+            {allow, subscribe, <<"testall1/${username}">>},
+            {allow, subscribe, <<"testall2/clientid">>},
+            {allow, subscribe, <<"testall3/foobar">>},
+            {allow, subscribe, <<"testall3/+/foobar">>},
+            {allow, subscribe, <<"testall3/#">>},
+            {deny, publish, <<"testall1/username">>},
+            {allow, publish, <<"testall1/${username}">>},
+            {allow, publish, <<"testall2/clientid">>},
+            {allow, publish, <<"testall3/foobar">>},
+
+            {deny, subscribe, <<"testall2/username">>},
+            {deny, subscribe, <<"testall1/clientid">>},
+            {deny, subscribe, <<"testall4/foobar">>},
+            {deny, publish, <<"testall2/username">>},
+            {deny, publish, <<"testall1/clientid">>},
+            {deny, publish, <<"testall4/foobar">>}
+           ]).
+
+test_deny_topic_rules(ClientInfo, SetupSamples) ->
+    Samples = [
+               #{
+                 topics => [<<"#">>],
+                 permission => <<"allow">>,
+                 action => <<"all">>
+                },
+               #{
+                 topics => [<<"eq testpub1/${username}">>,
+                            <<"testpub2/${clientid}">>,
+                            <<"testpub3/#">>],
+                 permission => <<"deny">>,
+                 action => <<"publish">>
+                },
+               #{
+                 topics => [<<"eq testsub1/${username}">>,
+                            <<"testsub2/${clientid}">>,
+                            <<"testsub3/#">>],
+                 permission => <<"deny">>,
+                 action => <<"subscribe">>
+                },
+
+               #{
+                 topics => [<<"eq testall1/${username}">>,
+                            <<"testall2/${clientid}">>,
+                            <<"testall3/#">>],
+                 permission => <<"deny">>,
+                 action => <<"all">>
+                }
+              ],
+
+    ok = SetupSamples(ClientInfo, Samples),
+
+    ok = test_samples(
+           ClientInfo,
+           [
+
+            %% Publish rules
+
+            {allow, publish, <<"testpub1/username">>},
+            {deny, publish, <<"testpub1/${username}">>},
+            {deny, publish, <<"testpub2/clientid">>},
+            {deny, publish, <<"testpub3/foobar">>},
+
+            {allow, publish, <<"testpub2/username">>},
+            {allow, publish, <<"testpub1/clientid">>},
+
+
+            {allow, subscribe, <<"testpub1/username">>},
+            {allow, subscribe, <<"testpub2/clientid">>},
+            {allow, subscribe, <<"testpub3/foobar">>},
+
+            %% Subscribe rules
+
+            {allow, subscribe, <<"testsub1/username">>},
+            {deny, subscribe, <<"testsub1/${username}">>},
+            {deny, subscribe, <<"testsub2/clientid">>},
+            {deny, subscribe, <<"testsub3/foobar">>},
+            {deny, subscribe, <<"testsub3/+/foobar">>},
+            {deny, subscribe, <<"testsub3/#">>},
+
+            {allow, subscribe, <<"testsub2/username">>},
+            {allow, subscribe, <<"testsub1/clientid">>},
+            {allow, subscribe, <<"testsub4/foobar">>},
+            {allow, publish, <<"testsub1/username">>},
+            {allow, publish, <<"testsub2/clientid">>},
+            {allow, publish, <<"testsub3/foobar">>},
+
+            %% All rules
+
+            {allow, subscribe, <<"testall1/username">>},
+            {deny, subscribe, <<"testall1/${username}">>},
+            {deny, subscribe, <<"testall2/clientid">>},
+            {deny, subscribe, <<"testall3/foobar">>},
+            {deny, subscribe, <<"testall3/+/foobar">>},
+            {deny, subscribe, <<"testall3/#">>},
+            {allow, publish, <<"testall1/username">>},
+            {deny, publish, <<"testall1/${username}">>},
+            {deny, publish, <<"testall2/clientid">>},
+            {deny, publish, <<"testall3/foobar">>},
+
+            {allow, subscribe, <<"testall2/username">>},
+            {allow, subscribe, <<"testall1/clientid">>},
+            {allow, subscribe, <<"testall4/foobar">>},
+            {allow, publish, <<"testall2/username">>},
+            {allow, publish, <<"testall1/clientid">>},
+            {allow, publish, <<"testall4/foobar">>}
+           ]).