Jelajahi Sumber

Merge branch 'dev-hd' into dev

Feng Lee 10 tahun lalu
induk
melakukan
5b16368408

+ 1 - 1
apps/emqttd/src/emqttd_access_control.erl

@@ -152,7 +152,7 @@ stop() ->
 %%%=============================================================================
 
 init([]) ->
-    {ok, AcOpts} = application:get_env(access),
+    {ok, AcOpts} = application:get_env(emqttd, access),
 	ets:new(?ACCESS_CONTROL_TAB, [set, named_table, protected, {read_concurrency, true}]),
     ets:insert(?ACCESS_CONTROL_TAB, {auth_modules, init_mods(auth, proplists:get_value(auth, AcOpts))}),
     ets:insert(?ACCESS_CONTROL_TAB, {acl_modules, init_mods(acl, proplists:get_value(acl, AcOpts))}),

+ 107 - 0
apps/emqttd/test/emqttd_access_control_tests.erl

@@ -0,0 +1,107 @@
+%%%-----------------------------------------------------------------------------
+%%% @Copyright (C) 2012-2015, Feng Lee <feng@emqtt.io>
+%%%
+%%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%%% of this software and associated documentation files (the "Software"), to deal
+%%% in the Software without restriction, including without limitation the rights
+%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%%% copies of the Software, and to permit persons to whom the Software is
+%%% furnished to do so, subject to the following conditions:
+%%%
+%%% The above copyright notice and this permission notice shall be included in all
+%%% copies or substantial portions of the Software.
+%%%
+%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+%%% SOFTWARE.
+%%%-----------------------------------------------------------------------------
+%%% @doc
+%%% emqttd_access_control tests.
+%%%
+%%% @end
+%%%-----------------------------------------------------------------------------
+-module(emqttd_access_control_tests).
+
+-include("emqttd.hrl").
+
+-ifdef(TEST).
+
+-include_lib("eunit/include/eunit.hrl").
+
+reload_acl_test() ->
+    with_acl(
+        fun() ->
+            ?assertEqual([ok], emqttd_access_control:reload_acl())
+        end).
+
+register_mod_test() ->
+    with_acl(
+        fun() ->
+            emqttd_access_control:register_mod(acl, emqttd_acl_test_mod, []),
+            ?assertMatch([{emqttd_acl_test_mod, _}, {emqttd_acl_internal, _}],
+                          emqttd_access_control:lookup_mods(acl)),
+	    emqttd_access_control:register_mod(auth, emqttd_auth_anonymous_test_mod,[]),
+	    ?assertMatch([{emqttd_auth_anonymous_test_mod, _}, {emqttd_auth_anonymous, _}],
+                          emqttd_access_control:lookup_mods(auth))
+        end).
+
+unregister_mod_test() ->
+    with_acl(
+        fun() ->
+            emqttd_access_control:register_mod(acl,emqttd_acl_test_mod, []),
+            ?assertMatch([{emqttd_acl_test_mod, _}, {emqttd_acl_internal, _}],
+                          emqttd_access_control:lookup_mods(acl)),
+            emqttd_access_control:unregister_mod(acl, emqttd_acl_test_mod),
+            timer:sleep(5),
+            ?assertMatch([{emqttd_acl_internal, _}], emqttd_access_control:lookup_mods(acl)),
+	
+	    emqttd_access_control:register_mod(auth, emqttd_auth_anonymous_test_mod,[]),
+	    ?assertMatch([{emqttd_auth_anonymous_test_mod, _}, {emqttd_auth_anonymous, _}],
+                          emqttd_access_control:lookup_mods(auth)),
+		
+	    emqttd_access_control:unregister_mod(auth, emqttd_auth_anonymous_test_mod),
+            timer:sleep(5),
+            ?assertMatch([{emqttd_auth_anonymous, _}], emqttd_access_control:lookup_mods(auth))
+        end).
+
+check_acl_test() ->
+    with_acl(
+        fun() ->
+            User1 = #mqtt_client{clientid = <<"client1">>, username = <<"testuser">>},
+            User2 = #mqtt_client{clientid = <<"client2">>, username = <<"xyz">>},
+            ?assertEqual(allow, emqttd_access_control:check_acl(User1, subscribe, <<"users/testuser/1">>)),
+	    ?assertEqual(allow, emqttd_access_control:check_acl(User1, subscribe, <<"clients/client1">>)),
+	    ?assertEqual(deny, emqttd_access_control:check_acl(User1, subscribe, <<"clients/client1/x/y">>)),
+            ?assertEqual(allow, emqttd_access_control:check_acl(User1, publish, <<"users/testuser/1">>)),
+            ?assertEqual(allow, emqttd_access_control:check_acl(User1, subscribe, <<"a/b/c">>)),
+            ?assertEqual(deny, emqttd_access_control:check_acl(User2, subscribe, <<"a/b/c">>))
+        end).
+
+with_acl(Fun) ->
+    process_flag(trap_exit, true),
+     AclOpts = [
+        {auth, [
+            %% Authentication with username, password
+            %{username, []},
+            %% Authentication with clientid
+            %{clientid, [{password, no}, {file, "etc/clients.config"}]},
+            %% Allow all
+            {anonymous, []}
+        ]},
+        %% ACL config
+        {acl, [
+            %% Internal ACL module
+            {internal,  [{file, "../test/test_acl.config"}, {nomatch, allow}]}
+        ]}
+    ],
+    application:set_env(emqttd, access, AclOpts),
+    emqttd_access_control:start_link(),
+    Fun(),
+    emqttd_access_control:stop().
+
+-endif.
+

+ 3 - 3
apps/emqttd/test/emqttd_access_rule_tests.erl

@@ -53,8 +53,8 @@ compile_test() ->
     ?assertEqual({deny, all},  compile({deny, all})).
 
 match_test() ->
-    User = #mqtt_user{ipaddr = {127,0,0,1}, clientid = <<"testClient">>, username = <<"TestUser">>},
-    User2 = #mqtt_user{ipaddr = {192,168,0,10}, clientid = <<"testClient">>, username = <<"TestUser">>},
+    User = #mqtt_client{ipaddr = {127,0,0,1}, clientid = <<"testClient">>, username = <<"TestUser">>},
+    User2 = #mqtt_client{ipaddr = {192,168,0,10}, clientid = <<"testClient">>, username = <<"TestUser">>},
     
     ?assertEqual({matched, allow}, match(User, <<"Test/Topic">>, {allow, all})),
     ?assertEqual({matched, deny},  match(User, <<"Test/Topic">>, {deny, all})),
@@ -68,7 +68,7 @@ match_test() ->
                  compile({allow, {client, "testClient"}, publish, ["testTopics/testClient"]}))),
     ?assertMatch({matched, allow}, match(User, <<"clients/testClient">>,
                                                        compile({allow, all, pubsub, ["clients/$c"]}))),
-    ?assertMatch({matched, allow}, match(#mqtt_user{username = <<"user2">>}, <<"users/user2/abc/def">>,
+    ?assertMatch({matched, allow}, match(#mqtt_client{username = <<"user2">>}, <<"users/user2/abc/def">>,
                                                                   compile({allow, all, subscribe, ["users/$u/#"]}))),
     ?assertMatch({matched, deny}, 
                  match(User, <<"d/e/f">>,

+ 39 - 0
apps/emqttd/test/emqttd_auth_anonymous_test_mod.erl

@@ -0,0 +1,39 @@
+%%%-----------------------------------------------------------------------------
+%%% @Copyright (C) 2012-2015, Feng Lee <feng@emqtt.io>
+%%%
+%%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%%% of this software and associated documentation files (the "Software"), to deal
+%%% in the Software without restriction, including without limitation the rights
+%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%%% copies of the Software, and to permit persons to whom the Software is
+%%% furnished to do so, subject to the following conditions:
+%%%
+%%% The above copyright notice and this permission notice shall be included in all
+%%% copies or substantial portions of the Software.
+%%%
+%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+%%% SOFTWARE.
+%%%-----------------------------------------------------------------------------
+%%% @doc
+%%% Test ACL Module.
+%%%
+%%% @end
+%%%-----------------------------------------------------------------------------
+-module(emqttd_auth_anonymous_test_mod).
+
+%% ACL callbacks
+-export([init/1, check/3, description/0]).
+
+init(AclOpts) ->
+    {ok, AclOpts}.
+
+check(_Client, _Password, _Opts) ->
+    allow.
+
+description() ->
+    "Test emqttd_auth_anonymous Mod".