diff --git a/apps/emqttd/include/emqttd.hrl b/apps/emqttd/include/emqttd.hrl index 0727d3291..112f86806 100644 --- a/apps/emqttd/include/emqttd.hrl +++ b/apps/emqttd/include/emqttd.hrl @@ -36,6 +36,11 @@ -define(ERTS_MINIMUM, "6.0"). +%%------------------------------------------------------------------------------ +%% PubSub Type +%%------------------------------------------------------------------------------ +-type pubsub() :: publish | subscribe. + %%------------------------------------------------------------------------------ %% MQTT Client %%------------------------------------------------------------------------------ diff --git a/apps/emqttd/src/emqttd_acl.erl b/apps/emqttd/src/emqttd_acl.erl index 7dfef1e5d..46abb5373 100644 --- a/apps/emqttd/src/emqttd_acl.erl +++ b/apps/emqttd/src/emqttd_acl.erl @@ -51,19 +51,23 @@ -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(), - PubSub :: publish | subscribe, + PubSub :: pubsub(), Topic :: binary(). -callback reload_acl() -> ok | {error, any()}. +-callback description() -> string(). + -else. -export([behaviour_info/1]). behaviour_info(callbacks) -> - [{check_acl, 3}, {reload_acl, 0}, {description, 0}]; + [{init, 1}, {check_acl, 3}, {reload_acl, 0}, {description, 0}]; behaviour_info(_Other) -> undefined. @@ -90,22 +94,24 @@ start_link(AclOpts) -> %% %% @end %%-------------------------------------------------------------------------- --spec check(User, PubSub, Topic) -> {ok, allow | deny} | {error, any()} when +-spec check(User, PubSub, Topic) -> allow | deny | ignore when User :: mqtt_user(), - PubSub :: publish | subscribe, + PubSub :: pubsub(), Topic :: binary(). check(User, PubSub, Topic) when PubSub =:= publish orelse PubSub =:= subscribe -> case ets:lookup(?ACL_TABLE, acl_modules) of - [] -> {error, "No ACL mods!"}; + [] -> allow; [{_, Mods}] -> check(User, PubSub, Topic, Mods) end. -check(_User, _PubSub, _Topic, []) -> - {error, "All ACL mods ignored!"}; +check(#mqtt_user{clientid = ClientId}, PubSub, Topic, []) -> + lager:error("ACL: nomatch when ~s ~s ~s", [ClientId, PubSub, Topic]), + allow; check(User, PubSub, Topic, [Mod|Mods]) -> case Mod:check_acl(User, PubSub, Topic) of - {ok, AllowDeny} -> {ok, AllowDeny}; + allow -> allow; + deny -> deny; ignore -> check(User, PubSub, Topic, Mods) end. @@ -167,7 +173,7 @@ handle_call({register_mod, Mod}, _From, State) -> Mods = all_modules(), case lists:member(Mod, Mods) of true -> - {reply, {error, registered}, State}; + {reply, {error, existed}, State}; false -> ets:insert(?ACL_TABLE, {acl_modules, [Mod | Mods]}), {reply, ok, State} diff --git a/apps/emqttd/src/emqttd_acl_internal.erl b/apps/emqttd/src/emqttd_acl_internal.erl index 773c1611c..3de356874 100644 --- a/apps/emqttd/src/emqttd_acl_internal.erl +++ b/apps/emqttd/src/emqttd_acl_internal.erl @@ -77,15 +77,15 @@ stop() -> %% %% @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(), - PubSub :: publish | subscribe, + PubSub :: pubsub(), Topic :: binary(). check_acl(User, PubSub, Topic) -> case match(User, Topic, lookup(PubSub)) of - {matched, allow} -> {ok, allow}; - {matched, deny} -> {ok, deny}; - nomatch -> {error, nomatch} + {matched, allow} -> allow; + {matched, deny} -> deny; + nomatch -> ignore end. lookup(PubSub) -> diff --git a/rel/files/app.config b/rel/files/app.config index 1c7db05b0..f21c25096 100644 --- a/rel/files/app.config +++ b/rel/files/app.config @@ -49,7 +49,8 @@ ]}, %% ACL config {acl, [ - {file, "etc/acl.config"} + %% User internal ACL module + {internal, [{file, "etc/acl.config"}, {nomatch, allow}]} ]}, %% Packet {packet, [