redesign acl

This commit is contained in:
Feng Lee 2015-04-08 00:45:46 +08:00
parent 8ee3433315
commit fa24100514
4 changed files with 28 additions and 16 deletions

View File

@ -36,6 +36,11 @@
-define(ERTS_MINIMUM, "6.0"). -define(ERTS_MINIMUM, "6.0").
%%------------------------------------------------------------------------------
%% PubSub Type
%%------------------------------------------------------------------------------
-type pubsub() :: publish | subscribe.
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
%% MQTT Client %% MQTT Client
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------

View File

@ -51,19 +51,23 @@
-ifdef(use_specs). -ifdef(use_specs).
-callback check_acl(User, PubSub, Topic) -> {ok, allow | deny} | ignore | {error, any()} when -callback init(AclOpts :: list()) -> {ok, State :: any()}.
-callback check_acl(User, PubSub, Topic) -> allow | deny | ignore when
User :: mqtt_user(), User :: mqtt_user(),
PubSub :: publish | subscribe, PubSub :: pubsub(),
Topic :: binary(). Topic :: binary().
-callback reload_acl() -> ok | {error, any()}. -callback reload_acl() -> ok | {error, any()}.
-callback description() -> string().
-else. -else.
-export([behaviour_info/1]). -export([behaviour_info/1]).
behaviour_info(callbacks) -> behaviour_info(callbacks) ->
[{check_acl, 3}, {reload_acl, 0}, {description, 0}]; [{init, 1}, {check_acl, 3}, {reload_acl, 0}, {description, 0}];
behaviour_info(_Other) -> behaviour_info(_Other) ->
undefined. undefined.
@ -90,22 +94,24 @@ start_link(AclOpts) ->
%% %%
%% @end %% @end
%%-------------------------------------------------------------------------- %%--------------------------------------------------------------------------
-spec check(User, PubSub, Topic) -> {ok, allow | deny} | {error, any()} when -spec check(User, PubSub, Topic) -> allow | deny | ignore when
User :: mqtt_user(), User :: mqtt_user(),
PubSub :: publish | subscribe, PubSub :: pubsub(),
Topic :: binary(). Topic :: binary().
check(User, PubSub, Topic) when PubSub =:= publish orelse PubSub =:= subscribe -> check(User, PubSub, Topic) when PubSub =:= publish orelse PubSub =:= subscribe ->
case ets:lookup(?ACL_TABLE, acl_modules) of case ets:lookup(?ACL_TABLE, acl_modules) of
[] -> {error, "No ACL mods!"}; [] -> allow;
[{_, Mods}] -> check(User, PubSub, Topic, Mods) [{_, Mods}] -> check(User, PubSub, Topic, Mods)
end. end.
check(_User, _PubSub, _Topic, []) -> check(#mqtt_user{clientid = ClientId}, PubSub, Topic, []) ->
{error, "All ACL mods ignored!"}; lager:error("ACL: nomatch when ~s ~s ~s", [ClientId, PubSub, Topic]),
allow;
check(User, PubSub, Topic, [Mod|Mods]) -> check(User, PubSub, Topic, [Mod|Mods]) ->
case Mod:check_acl(User, PubSub, Topic) of case Mod:check_acl(User, PubSub, Topic) of
{ok, AllowDeny} -> {ok, AllowDeny}; allow -> allow;
deny -> deny;
ignore -> check(User, PubSub, Topic, Mods) ignore -> check(User, PubSub, Topic, Mods)
end. end.
@ -167,7 +173,7 @@ handle_call({register_mod, Mod}, _From, State) ->
Mods = all_modules(), Mods = all_modules(),
case lists:member(Mod, Mods) of case lists:member(Mod, Mods) of
true -> true ->
{reply, {error, registered}, State}; {reply, {error, existed}, State};
false -> false ->
ets:insert(?ACL_TABLE, {acl_modules, [Mod | Mods]}), ets:insert(?ACL_TABLE, {acl_modules, [Mod | Mods]}),
{reply, ok, State} {reply, ok, State}

View File

@ -77,15 +77,15 @@ stop() ->
%% %%
%% @end %% @end
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
-spec check_acl(User, PubSub, Topic) -> {ok, allow} | {ok, deny} | ignore | {error, any()} when -spec check_acl(User, PubSub, Topic) -> allow | deny | ignore when
User :: mqtt_user(), User :: mqtt_user(),
PubSub :: publish | subscribe, PubSub :: pubsub(),
Topic :: binary(). Topic :: binary().
check_acl(User, PubSub, Topic) -> check_acl(User, PubSub, Topic) ->
case match(User, Topic, lookup(PubSub)) of case match(User, Topic, lookup(PubSub)) of
{matched, allow} -> {ok, allow}; {matched, allow} -> allow;
{matched, deny} -> {ok, deny}; {matched, deny} -> deny;
nomatch -> {error, nomatch} nomatch -> ignore
end. end.
lookup(PubSub) -> lookup(PubSub) ->

View File

@ -49,7 +49,8 @@
]}, ]},
%% ACL config %% ACL config
{acl, [ {acl, [
{file, "etc/acl.config"} %% User internal ACL module
{internal, [{file, "etc/acl.config"}, {nomatch, allow}]}
]}, ]},
%% Packet %% Packet
{packet, [ {packet, [