Replace credentials with client
This commit is contained in:
parent
32b2a01d68
commit
d99c9daf76
|
@ -28,52 +28,57 @@
|
||||||
%% APIs
|
%% APIs
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
-spec(authenticate(emqx_types:credentials())
|
-spec(authenticate(emqx_types:client())
|
||||||
-> {ok, emqx_types:credentials()} | {error, term()}).
|
-> {ok, #{auth_result := emqx_types:auth_result(),
|
||||||
authenticate(Credentials) ->
|
anonymous := boolean}} | {error, term()}).
|
||||||
case emqx_hooks:run_fold('client.authenticate', [], init_auth_result(Credentials)) of
|
authenticate(Client = #{zone := Zone}) ->
|
||||||
#{auth_result := success, anonymous := true} = NewCredentials ->
|
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'),
|
emqx_metrics:inc('auth.mqtt.anonymous'),
|
||||||
{ok, NewCredentials};
|
{ok, Result};
|
||||||
#{auth_result := success} = NewCredentials ->
|
Result = #{auth_result := success} ->
|
||||||
{ok, NewCredentials};
|
{ok, Result};
|
||||||
NewCredentials ->
|
Result ->
|
||||||
{error, maps:get(auth_result, NewCredentials, unknown_error)}
|
{error, maps:get(auth_result, Result, unknown_error)}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc Check ACL
|
%% @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).
|
-> allow | deny).
|
||||||
check_acl(Credentials, PubSub, Topic) ->
|
check_acl(Client, PubSub, Topic) ->
|
||||||
case emqx_acl_cache:is_enabled() of
|
case emqx_acl_cache:is_enabled() of
|
||||||
false ->
|
|
||||||
do_check_acl(Credentials, PubSub, Topic);
|
|
||||||
true ->
|
true ->
|
||||||
|
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
|
case emqx_acl_cache:get_acl_cache(PubSub, Topic) of
|
||||||
not_found ->
|
not_found ->
|
||||||
AclResult = do_check_acl(Credentials, PubSub, Topic),
|
AclResult = do_check_acl(Client, PubSub, Topic),
|
||||||
emqx_acl_cache:put_acl_cache(PubSub, Topic, AclResult),
|
emqx_acl_cache:put_acl_cache(PubSub, Topic, AclResult),
|
||||||
AclResult;
|
AclResult;
|
||||||
AclResult -> AclResult
|
AclResult -> AclResult
|
||||||
end
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_check_acl(#{zone := Zone} = Credentials, PubSub, Topic) ->
|
do_check_acl(#{zone := Zone} = Client, PubSub, Topic) ->
|
||||||
case emqx_hooks:run_fold('client.check_acl', [Credentials, PubSub, Topic],
|
Default = emqx_zone:get_env(Zone, acl_nomatch, deny),
|
||||||
emqx_zone:get_env(Zone, acl_nomatch, deny)) of
|
case emqx_hooks:run_fold('client.check_acl', [Client, PubSub, Topic], Default) of
|
||||||
allow -> allow;
|
allow -> allow;
|
||||||
_ -> deny
|
_Other -> deny
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec(reload_acl() -> ok | {error, term()}).
|
-spec(reload_acl() -> ok | {error, term()}).
|
||||||
reload_acl() ->
|
reload_acl() ->
|
||||||
emqx_acl_cache:is_enabled() andalso
|
emqx_acl_cache:is_enabled()
|
||||||
emqx_acl_cache:empty_acl_cache(),
|
andalso emqx_acl_cache:empty_acl_cache(),
|
||||||
emqx_mod_acl_internal:reload_acl().
|
emqx_mod_acl_internal:reload_acl().
|
||||||
|
|
||||||
init_auth_result(Credentials) ->
|
default_auth_result(Zone) ->
|
||||||
case emqx_zone:get_env(maps:get(zone, Credentials, undefined), allow_anonymous, false) of
|
case emqx_zone:get_env(Zone, allow_anonymous, false) of
|
||||||
true -> Credentials#{auth_result => success, anonymous => true};
|
true -> #{auth_result => success, anonymous => true};
|
||||||
false -> Credentials#{auth_result => not_authorized, anonymous => false}
|
false -> #{auth_result => not_authorized, anonymous => false}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,6 @@
|
||||||
-define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= deny))).
|
-define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= deny))).
|
||||||
-define(PUBSUB(A), ((A =:= subscribe) orelse (A =:= publish) orelse (A =:= pubsub))).
|
-define(PUBSUB(A), ((A =:= subscribe) orelse (A =:= publish) orelse (A =:= pubsub))).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% APIs
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
|
|
||||||
%% @doc Compile Access Rule.
|
%% @doc Compile Access Rule.
|
||||||
compile({A, all}) when ?ALLOW_DENY(A) ->
|
compile({A, all}) when ?ALLOW_DENY(A) ->
|
||||||
{A, all};
|
{A, all};
|
||||||
|
@ -92,21 +88,21 @@ bin(B) when is_binary(B) ->
|
||||||
%% @doc Match access rule
|
%% @doc Match access rule
|
||||||
-spec(match(emqx_types:credentials(), emqx_types:topic(), rule())
|
-spec(match(emqx_types:credentials(), emqx_types:topic(), rule())
|
||||||
-> {matched, allow} | {matched, deny} | nomatch).
|
-> {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};
|
{matched, AllowDeny};
|
||||||
match(Credentials, Topic, {AllowDeny, Who, _PubSub, TopicFilters})
|
match(Client, Topic, {AllowDeny, Who, _PubSub, TopicFilters})
|
||||||
when ?ALLOW_DENY(AllowDeny) ->
|
when ?ALLOW_DENY(AllowDeny) ->
|
||||||
case match_who(Credentials, Who)
|
case match_who(Client, Who)
|
||||||
andalso match_topics(Credentials, Topic, TopicFilters) of
|
andalso match_topics(Client, Topic, TopicFilters) of
|
||||||
true -> {matched, AllowDeny};
|
true -> {matched, AllowDeny};
|
||||||
false -> nomatch
|
false -> nomatch
|
||||||
end.
|
end.
|
||||||
|
|
||||||
match_who(_Credentials, all) ->
|
match_who(_Client, all) ->
|
||||||
true;
|
true;
|
||||||
match_who(_Credentials, {user, all}) ->
|
match_who(_Client, {user, all}) ->
|
||||||
true;
|
true;
|
||||||
match_who(_Credentials, {client, all}) ->
|
match_who(_Client, {client, all}) ->
|
||||||
true;
|
true;
|
||||||
match_who(#{client_id := ClientId}, {client, ClientId}) ->
|
match_who(#{client_id := ClientId}, {client, ClientId}) ->
|
||||||
true;
|
true;
|
||||||
|
@ -116,44 +112,44 @@ match_who(#{peername := undefined}, {ipaddr, _Tup}) ->
|
||||||
false;
|
false;
|
||||||
match_who(#{peername := {IP, _}}, {ipaddr, CIDR}) ->
|
match_who(#{peername := {IP, _}}, {ipaddr, CIDR}) ->
|
||||||
esockd_cidr:match(IP, 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) ->
|
lists:foldl(fun(Who, Allow) ->
|
||||||
match_who(Credentials, Who) andalso Allow
|
match_who(Client, Who) andalso Allow
|
||||||
end, true, Conds);
|
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) ->
|
lists:foldl(fun(Who, Allow) ->
|
||||||
match_who(Credentials, Who) orelse Allow
|
match_who(Client, Who) orelse Allow
|
||||||
end, false, Conds);
|
end, false, Conds);
|
||||||
match_who(_Credentials, _Who) ->
|
match_who(_Client, _Who) ->
|
||||||
false.
|
false.
|
||||||
|
|
||||||
match_topics(_Credentials, _Topic, []) ->
|
match_topics(_Client, _Topic, []) ->
|
||||||
false;
|
false;
|
||||||
match_topics(Credentials, Topic, [{pattern, PatternFilter}|Filters]) ->
|
match_topics(Client, Topic, [{pattern, PatternFilter}|Filters]) ->
|
||||||
TopicFilter = feed_var(Credentials, PatternFilter),
|
TopicFilter = feed_var(Client, PatternFilter),
|
||||||
match_topic(emqx_topic:words(Topic), TopicFilter)
|
match_topic(emqx_topic:words(Topic), TopicFilter)
|
||||||
orelse match_topics(Credentials, Topic, Filters);
|
orelse match_topics(Client, Topic, Filters);
|
||||||
match_topics(Credentials, Topic, [TopicFilter|Filters]) ->
|
match_topics(Client, Topic, [TopicFilter|Filters]) ->
|
||||||
match_topic(emqx_topic:words(Topic), TopicFilter)
|
match_topic(emqx_topic:words(Topic), TopicFilter)
|
||||||
orelse match_topics(Credentials, Topic, Filters).
|
orelse match_topics(Client, Topic, Filters).
|
||||||
|
|
||||||
match_topic(Topic, {eq, TopicFilter}) ->
|
match_topic(Topic, {eq, TopicFilter}) ->
|
||||||
Topic == TopicFilter;
|
Topic == TopicFilter;
|
||||||
match_topic(Topic, TopicFilter) ->
|
match_topic(Topic, TopicFilter) ->
|
||||||
emqx_topic:match(Topic, TopicFilter).
|
emqx_topic:match(Topic, TopicFilter).
|
||||||
|
|
||||||
feed_var(Credentials, Pattern) ->
|
feed_var(Client, Pattern) ->
|
||||||
feed_var(Credentials, Pattern, []).
|
feed_var(Client, Pattern, []).
|
||||||
feed_var(_Credentials, [], Acc) ->
|
feed_var(_Client, [], Acc) ->
|
||||||
lists:reverse(Acc);
|
lists:reverse(Acc);
|
||||||
feed_var(Credentials = #{client_id := undefined}, [<<"%c">>|Words], Acc) ->
|
feed_var(Client = #{client_id := undefined}, [<<"%c">>|Words], Acc) ->
|
||||||
feed_var(Credentials, Words, [<<"%c">>|Acc]);
|
feed_var(Client, Words, [<<"%c">>|Acc]);
|
||||||
feed_var(Credentials = #{client_id := ClientId}, [<<"%c">>|Words], Acc) ->
|
feed_var(Client = #{client_id := ClientId}, [<<"%c">>|Words], Acc) ->
|
||||||
feed_var(Credentials, Words, [ClientId |Acc]);
|
feed_var(Client, Words, [ClientId |Acc]);
|
||||||
feed_var(Credentials = #{username := undefined}, [<<"%u">>|Words], Acc) ->
|
feed_var(Client = #{username := undefined}, [<<"%u">>|Words], Acc) ->
|
||||||
feed_var(Credentials, Words, [<<"%u">>|Acc]);
|
feed_var(Client, Words, [<<"%u">>|Acc]);
|
||||||
feed_var(Credentials = #{username := Username}, [<<"%u">>|Words], Acc) ->
|
feed_var(Client = #{username := Username}, [<<"%u">>|Words], Acc) ->
|
||||||
feed_var(Credentials, Words, [Username|Acc]);
|
feed_var(Client, Words, [Username|Acc]);
|
||||||
feed_var(Credentials, [W|Words], Acc) ->
|
feed_var(Client, [W|Words], Acc) ->
|
||||||
feed_var(Credentials, Words, [W|Acc]).
|
feed_var(Client, Words, [W|Acc]).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue