From 54d29160f6417e7220adb670cb4cecb4a77e1738 Mon Sep 17 00:00:00 2001 From: huangdan Date: Wed, 20 May 2015 10:43:34 +0800 Subject: [PATCH 1/3] access_control test --- .../test/emqttd_access_control_tests.erl | 96 +++++++++++++++++++ apps/emqttd/test/emqttd_access_rule_tests.erl | 6 +- 2 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 apps/emqttd/test/emqttd_access_control_tests.erl diff --git a/apps/emqttd/test/emqttd_access_control_tests.erl b/apps/emqttd/test/emqttd_access_control_tests.erl new file mode 100644 index 000000000..c9553924b --- /dev/null +++ b/apps/emqttd/test/emqttd_access_control_tests.erl @@ -0,0 +1,96 @@ +%%%----------------------------------------------------------------------------- +%%% @Copyright (C) 2012-2015, Feng Lee +%%% +%%% 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)) + 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)) + 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. + diff --git a/apps/emqttd/test/emqttd_access_rule_tests.erl b/apps/emqttd/test/emqttd_access_rule_tests.erl index 66632c663..e0a5427df 100644 --- a/apps/emqttd/test/emqttd_access_rule_tests.erl +++ b/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">>, From e674d003304e35f8d3256330d0ea806af5f8e58c Mon Sep 17 00:00:00 2001 From: huangdan Date: Wed, 20 May 2015 10:59:57 +0800 Subject: [PATCH 2/3] access get_env --- apps/emqttd/src/emqttd_access_control.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/emqttd/src/emqttd_access_control.erl b/apps/emqttd/src/emqttd_access_control.erl index eb4344b38..3f1ca1b36 100644 --- a/apps/emqttd/src/emqttd_access_control.erl +++ b/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))}), From bd0c49329b5689cf6fa7e63307b0c33d68c9b90a Mon Sep 17 00:00:00 2001 From: huangdan Date: Wed, 20 May 2015 12:48:34 +0800 Subject: [PATCH 3/3] access test --- .../test/emqttd_access_control_tests.erl | 17 ++++++-- .../test/emqttd_auth_anonymous_test_mod.erl | 39 +++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 apps/emqttd/test/emqttd_auth_anonymous_test_mod.erl diff --git a/apps/emqttd/test/emqttd_access_control_tests.erl b/apps/emqttd/test/emqttd_access_control_tests.erl index c9553924b..5c906804e 100644 --- a/apps/emqttd/test/emqttd_access_control_tests.erl +++ b/apps/emqttd/test/emqttd_access_control_tests.erl @@ -43,7 +43,10 @@ register_mod_test() -> 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: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() -> @@ -54,7 +57,15 @@ unregister_mod_test() -> 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)) + ?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() -> @@ -64,7 +75,7 @@ check_acl_test() -> 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(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">>)) diff --git a/apps/emqttd/test/emqttd_auth_anonymous_test_mod.erl b/apps/emqttd/test/emqttd_auth_anonymous_test_mod.erl new file mode 100644 index 000000000..a69d24630 --- /dev/null +++ b/apps/emqttd/test/emqttd_auth_anonymous_test_mod.erl @@ -0,0 +1,39 @@ +%%%----------------------------------------------------------------------------- +%%% @Copyright (C) 2012-2015, Feng Lee +%%% +%%% 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".