Jelajahi Sumber

Replace credentials with client

Feng Lee 6 tahun lalu
induk
melakukan
d99c9daf76
2 mengubah file dengan 69 tambahan dan 68 penghapusan
  1. 38 33
      src/emqx_access_control.erl
  2. 31 35
      src/emqx_access_rule.erl

+ 38 - 33
src/emqx_access_control.erl

@@ -28,52 +28,57 @@
 %% APIs
 %%--------------------------------------------------------------------
 
--spec(authenticate(emqx_types:credentials())
-      -> {ok, emqx_types:credentials()} | {error, term()}).
-authenticate(Credentials) ->
-    case emqx_hooks:run_fold('client.authenticate', [], init_auth_result(Credentials)) of
-    	#{auth_result := success, anonymous := true} = NewCredentials ->
+-spec(authenticate(emqx_types:client())
+      -> {ok, #{auth_result := emqx_types:auth_result(),
+                anonymous := boolean}} | {error, term()}).
+authenticate(Client = #{zone := Zone}) ->
+    case emqx_hooks:run_fold('client.authenticate',
+                             [Client], default_auth_result(Zone)) of
+    	Result = #{auth_result := success, anonymous := true} ->
             emqx_metrics:inc('auth.mqtt.anonymous'),
-	        {ok, NewCredentials};
-        #{auth_result := success} = NewCredentials ->
-	        {ok, NewCredentials};
-	    NewCredentials ->
-	        {error, maps:get(auth_result, NewCredentials, unknown_error)}
-	end.
+	        {ok, Result};
+        Result = #{auth_result := success} ->
+	        {ok, Result};
+	    Result ->
+	        {error, maps:get(auth_result, Result, unknown_error)}
+    end.
 
 %% @doc Check ACL
--spec(check_acl(emqx_types:credentials(), emqx_types:pubsub(), emqx_types:topic())
+-spec(check_acl(emqx_types:cient(), emqx_types:pubsub(), emqx_types:topic())
       -> allow | deny).
-check_acl(Credentials, PubSub, Topic) ->
+check_acl(Client, PubSub, Topic) ->
     case emqx_acl_cache:is_enabled() of
-        false ->
-            do_check_acl(Credentials, PubSub, Topic);
         true ->
-            case emqx_acl_cache:get_acl_cache(PubSub, Topic) of
-                not_found ->
-                    AclResult = do_check_acl(Credentials, PubSub, Topic),
-                    emqx_acl_cache:put_acl_cache(PubSub, Topic, AclResult),
-                    AclResult;
-                AclResult -> AclResult
-            end
+            check_acl_cache(Client, PubSub, Topic);
+        false ->
+            do_check_acl(Client, PubSub, Topic)
+    end.
+
+check_acl_cache(Client, PubSub, Topic) ->
+    case emqx_acl_cache:get_acl_cache(PubSub, Topic) of
+        not_found ->
+            AclResult = do_check_acl(Client, PubSub, Topic),
+            emqx_acl_cache:put_acl_cache(PubSub, Topic, AclResult),
+            AclResult;
+        AclResult -> AclResult
     end.
 
-do_check_acl(#{zone := Zone} = Credentials, PubSub, Topic) ->
-    case emqx_hooks:run_fold('client.check_acl', [Credentials, PubSub, Topic],
-                             emqx_zone:get_env(Zone, acl_nomatch, deny)) of
-        allow -> allow;
-        _ -> deny
+do_check_acl(#{zone := Zone} = Client, PubSub, Topic) ->
+    Default = emqx_zone:get_env(Zone, acl_nomatch, deny),
+    case emqx_hooks:run_fold('client.check_acl', [Client, PubSub, Topic], Default) of
+        allow  -> allow;
+        _Other -> deny
     end.
 
 -spec(reload_acl() -> ok | {error, term()}).
 reload_acl() ->
-    emqx_acl_cache:is_enabled() andalso
-        emqx_acl_cache:empty_acl_cache(),
+    emqx_acl_cache:is_enabled()
+        andalso emqx_acl_cache:empty_acl_cache(),
     emqx_mod_acl_internal:reload_acl().
 
-init_auth_result(Credentials) ->
-    case emqx_zone:get_env(maps:get(zone, Credentials, undefined), allow_anonymous, false) of
-	    true -> Credentials#{auth_result => success, anonymous => true};
-	    false -> Credentials#{auth_result => not_authorized, anonymous => false}
+default_auth_result(Zone) ->
+    case emqx_zone:get_env(Zone, allow_anonymous, false) of
+	    true  -> #{auth_result => success, anonymous => true};
+	    false -> #{auth_result => not_authorized, anonymous => false}
     end.
 

+ 31 - 35
src/emqx_access_rule.erl

@@ -40,10 +40,6 @@
 -define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= deny))).
 -define(PUBSUB(A), ((A =:= subscribe) orelse (A =:= publish) orelse (A =:= pubsub))).
 
-%%--------------------------------------------------------------------
-%% APIs
-%%--------------------------------------------------------------------
-
 %% @doc Compile Access Rule.
 compile({A, all}) when ?ALLOW_DENY(A) ->
     {A, all};
@@ -92,21 +88,21 @@ bin(B) when is_binary(B) ->
 %% @doc Match access rule
 -spec(match(emqx_types:credentials(), emqx_types:topic(), rule())
       -> {matched, allow} | {matched, deny} | nomatch).
-match(_Credentials, _Topic, {AllowDeny, all}) when ?ALLOW_DENY(AllowDeny) ->
+match(_Client, _Topic, {AllowDeny, all}) when ?ALLOW_DENY(AllowDeny) ->
     {matched, AllowDeny};
-match(Credentials, Topic, {AllowDeny, Who, _PubSub, TopicFilters})
+match(Client, Topic, {AllowDeny, Who, _PubSub, TopicFilters})
     when ?ALLOW_DENY(AllowDeny) ->
-    case match_who(Credentials, Who)
-         andalso match_topics(Credentials, Topic, TopicFilters) of
+    case match_who(Client, Who)
+         andalso match_topics(Client, Topic, TopicFilters) of
         true  -> {matched, AllowDeny};
         false -> nomatch
     end.
 
-match_who(_Credentials, all) ->
+match_who(_Client, all) ->
     true;
-match_who(_Credentials, {user, all}) ->
+match_who(_Client, {user, all}) ->
     true;
-match_who(_Credentials, {client, all}) ->
+match_who(_Client, {client, all}) ->
     true;
 match_who(#{client_id := ClientId}, {client, ClientId}) ->
     true;
@@ -116,44 +112,44 @@ match_who(#{peername := undefined}, {ipaddr, _Tup}) ->
     false;
 match_who(#{peername := {IP, _}}, {ipaddr, CIDR}) ->
     esockd_cidr:match(IP, CIDR);
-match_who(Credentials, {'and', Conds}) when is_list(Conds) ->
+match_who(Client, {'and', Conds}) when is_list(Conds) ->
     lists:foldl(fun(Who, Allow) ->
-                  match_who(Credentials, Who) andalso Allow
+                  match_who(Client, Who) andalso Allow
                 end, true, Conds);
-match_who(Credentials, {'or', Conds}) when is_list(Conds) ->
+match_who(Client, {'or', Conds}) when is_list(Conds) ->
     lists:foldl(fun(Who, Allow) ->
-                  match_who(Credentials, Who) orelse Allow
+                  match_who(Client, Who) orelse Allow
                 end, false, Conds);
-match_who(_Credentials, _Who) ->
+match_who(_Client, _Who) ->
     false.
 
-match_topics(_Credentials, _Topic, []) ->
+match_topics(_Client, _Topic, []) ->
     false;
-match_topics(Credentials, Topic, [{pattern, PatternFilter}|Filters]) ->
-    TopicFilter = feed_var(Credentials, PatternFilter),
+match_topics(Client, Topic, [{pattern, PatternFilter}|Filters]) ->
+    TopicFilter = feed_var(Client, PatternFilter),
     match_topic(emqx_topic:words(Topic), TopicFilter)
-        orelse match_topics(Credentials, Topic, Filters);
-match_topics(Credentials, Topic, [TopicFilter|Filters]) ->
+        orelse match_topics(Client, Topic, Filters);
+match_topics(Client, Topic, [TopicFilter|Filters]) ->
    match_topic(emqx_topic:words(Topic), TopicFilter)
-       orelse match_topics(Credentials, Topic, Filters).
+       orelse match_topics(Client, Topic, Filters).
 
 match_topic(Topic, {eq, TopicFilter}) ->
     Topic == TopicFilter;
 match_topic(Topic, TopicFilter) ->
     emqx_topic:match(Topic, TopicFilter).
 
-feed_var(Credentials, Pattern) ->
-    feed_var(Credentials, Pattern, []).
-feed_var(_Credentials, [], Acc) ->
+feed_var(Client, Pattern) ->
+    feed_var(Client, Pattern, []).
+feed_var(_Client, [], Acc) ->
     lists:reverse(Acc);
-feed_var(Credentials = #{client_id := undefined}, [<<"%c">>|Words], Acc) ->
-    feed_var(Credentials, Words, [<<"%c">>|Acc]);
-feed_var(Credentials = #{client_id := ClientId}, [<<"%c">>|Words], Acc) ->
-    feed_var(Credentials, Words, [ClientId |Acc]);
-feed_var(Credentials = #{username := undefined}, [<<"%u">>|Words], Acc) ->
-    feed_var(Credentials, Words, [<<"%u">>|Acc]);
-feed_var(Credentials = #{username := Username}, [<<"%u">>|Words], Acc) ->
-    feed_var(Credentials, Words, [Username|Acc]);
-feed_var(Credentials, [W|Words], Acc) ->
-    feed_var(Credentials, Words, [W|Acc]).
+feed_var(Client = #{client_id := undefined}, [<<"%c">>|Words], Acc) ->
+    feed_var(Client, Words, [<<"%c">>|Acc]);
+feed_var(Client = #{client_id := ClientId}, [<<"%c">>|Words], Acc) ->
+    feed_var(Client, Words, [ClientId |Acc]);
+feed_var(Client = #{username := undefined}, [<<"%u">>|Words], Acc) ->
+    feed_var(Client, Words, [<<"%u">>|Acc]);
+feed_var(Client = #{username := Username}, [<<"%u">>|Words], Acc) ->
+    feed_var(Client, Words, [Username|Acc]);
+feed_var(Client, [W|Words], Acc) ->
+    feed_var(Client, Words, [W|Acc]).