chore(authz): improve and clarify types
This commit is contained in:
parent
a0e0a27f87
commit
aaf57ecfbc
|
@ -29,13 +29,15 @@
|
|||
compile/4
|
||||
]).
|
||||
|
||||
-export_type([action/0, action_precompile/0]).
|
||||
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("emqx/include/emqx_placeholder.hrl").
|
||||
-include("emqx_authz.hrl").
|
||||
|
||||
-type permission() :: allow | deny.
|
||||
%%--------------------------------------------------------------------
|
||||
%% "condition" types describe compiled rules used internally for matching
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-type permission_resolution() :: allow | deny.
|
||||
|
||||
-type who_condition() ::
|
||||
ipaddress()
|
||||
|
@ -61,7 +63,18 @@
|
|||
|
||||
-type topic_condition() :: list(emqx_types:topic() | {eq, emqx_types:topic()}).
|
||||
|
||||
-type rule() :: {permission(), who_condition(), action_condition(), topic_condition()}.
|
||||
-type rule() :: {permission_resolution(), who_condition(), action_condition(), topic_condition()}.
|
||||
|
||||
-export_type([
|
||||
permission_resolution/0,
|
||||
action_condition/0,
|
||||
topic_condition/0
|
||||
]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% `action()` type describes client's actions that are mached
|
||||
%% against the compiled "condition" rules
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-type qos() :: emqx_types:qos().
|
||||
-type retain() :: boolean().
|
||||
|
@ -69,32 +82,54 @@
|
|||
#{action_type := subscribe, qos := qos()}
|
||||
| #{action_type := publish, qos := qos(), retain := retain()}.
|
||||
|
||||
-export_type([
|
||||
permission/0,
|
||||
who_condition/0,
|
||||
action_condition/0,
|
||||
topic_condition/0
|
||||
]).
|
||||
-export_type([action/0, qos/0, retain/0]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% "precompiled" types describe rule DSL that is used in "acl.conf" file
|
||||
%% to describe rules. Also, rules extracted from external sources
|
||||
%% like database, etc. are preprocessed into these types first
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-type permission_resolution_precompile() :: permission_resolution().
|
||||
|
||||
-type who_precompile() :: who_condition().
|
||||
|
||||
-type subscribe_option_precompile() :: {qos, qos() | [qos()]}.
|
||||
-type publish_option_precompile() :: {qos, qos() | [qos()]} | {retain, retain_condition()}.
|
||||
|
||||
-type action_precompile() ::
|
||||
subscribe
|
||||
| {subscribe, [subscribe_option_precompile()]}
|
||||
| publish
|
||||
| {subscribe, list()}
|
||||
| {publish, list()}
|
||||
| all.
|
||||
| {publish, [publish_option_precompile()]}
|
||||
| all
|
||||
| {all, [publish_option_precompile()]}.
|
||||
|
||||
-type topic_filter() :: emqx_types:topic().
|
||||
%% besides exact `topic_condition()` we also accept `<<"eq ...">>` and `"eq ..."`
|
||||
%% as precompiled topic conditions
|
||||
-type topic_precompile() :: topic_condition() | binary() | string().
|
||||
|
||||
-type rule_precompile() :: {permission(), who_condition(), action_precompile(), [topic_filter()]}.
|
||||
-type rule_precompile() :: {
|
||||
permission_resolution_precompile(), who_condition(), action_precompile(), [topic_precompile()]
|
||||
}.
|
||||
|
||||
-export_type([
|
||||
permission_resolution_precompile/0,
|
||||
action_precompile/0,
|
||||
topic_precompile/0,
|
||||
rule_precompile/0
|
||||
]).
|
||||
|
||||
-define(IS_PERMISSION(Permission), (Permission =:= allow orelse Permission =:= deny)).
|
||||
-define(ALLOWED_VARS, [?VAR_USERNAME, ?VAR_CLIENTID, ?VAR_NS_CLIENT_ATTRS]).
|
||||
|
||||
-spec compile(permission(), who_condition(), action_precompile(), [topic_filter()]) -> rule().
|
||||
-spec compile(permission_resolution_precompile(), who_precompile(), action_precompile(), [
|
||||
topic_precompile()
|
||||
]) -> rule().
|
||||
compile(Permission, Who, Action, TopicFilters) ->
|
||||
compile({Permission, Who, Action, TopicFilters}).
|
||||
|
||||
-spec compile({permission(), all} | rule_precompile()) -> rule().
|
||||
-spec compile({permission_resolution_precompile(), all} | rule_precompile()) -> rule().
|
||||
compile({Permission, all}) when
|
||||
?IS_PERMISSION(Permission)
|
||||
->
|
||||
|
|
|
@ -25,6 +25,30 @@
|
|||
|
||||
-include("emqx_authz.hrl").
|
||||
|
||||
%% Raw rules have the following format:
|
||||
%% [
|
||||
%% #{
|
||||
%% %% <<"allow">> | <"deny">>,
|
||||
%% <<"permission">> => <<"allow">>,
|
||||
%%
|
||||
%% %% <<"pub">> | <<"sub">> | <<"all">>
|
||||
%% <<"action">> => <<"pub">>,
|
||||
%%
|
||||
%% %% <<"a/$#">>, <<"eq a/b/+">>, ...
|
||||
%% <<"topic">> => TopicFilter,
|
||||
%%
|
||||
%% %% when 'topic' is not provided
|
||||
%% <<"topics">> => [TopicFilter],
|
||||
%%
|
||||
%% %% 0 | 1 | 2 | [0, 1, 2] | <<"0">> | <<"1">> | ...
|
||||
%% <<"qos">> => 0,
|
||||
%%
|
||||
%% %% true | false | all | 0 | 1 | <<"true">> | ...
|
||||
%% %% only for pub action
|
||||
%% <<"retain">> => true
|
||||
%% },
|
||||
%% ...
|
||||
%% ],
|
||||
-type rule_raw() :: #{binary() => binary() | [binary()]}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -33,9 +57,9 @@
|
|||
|
||||
-spec parse_rule(rule_raw()) ->
|
||||
{ok, {
|
||||
emqx_authz_rule:permission(),
|
||||
emqx_authz_rule:action_condition(),
|
||||
emqx_authz_rule:topic_condition()
|
||||
emqx_authz_rule:permission_resolution_precompile(),
|
||||
emqx_authz_rule:action_precompile(),
|
||||
emqx_authz_rule:topic_precompile()
|
||||
}}
|
||||
| {error, map()}.
|
||||
parse_rule(
|
||||
|
@ -65,9 +89,9 @@ parse_rule(RuleRaw) ->
|
|||
}}.
|
||||
|
||||
-spec format_rule({
|
||||
emqx_authz_rule:permission(),
|
||||
emqx_authz_rule:action_condition(),
|
||||
emqx_authz_rule:topic_condition()
|
||||
emqx_authz_rule:permission_resolution_precompile(),
|
||||
emqx_authz_rule:action_precompile(),
|
||||
emqx_authz_rule:topic_precompile()
|
||||
}) -> map().
|
||||
format_rule({Permission, Action, Topics}) when is_list(Topics) ->
|
||||
maps:merge(
|
||||
|
|
|
@ -75,22 +75,35 @@ destroy(_Source) -> ok.
|
|||
%% v2: (rules are checked in sequence, passthrough when no match)
|
||||
%%
|
||||
%% [{
|
||||
%% Permission :: emqx_authz_rule:permission(),
|
||||
%% Permission :: emqx_authz_rule:permission_resolution(),
|
||||
%% Action :: emqx_authz_rule:action_condition(),
|
||||
%% Topics :: emqx_authz_rule:topic_condition()
|
||||
%% }]
|
||||
%%
|
||||
%% which is compiled from raw rules like below by emqx_authz_rule_raw
|
||||
%% which is compiled from raw rule maps like below by `emqx_authz_rule_raw`
|
||||
%%
|
||||
%% [
|
||||
%% #{
|
||||
%% permission := allow | deny
|
||||
%% action := pub | sub | all
|
||||
%% topic => TopicFilter,
|
||||
%% topics => [TopicFilter] %% when 'topic' is not provided
|
||||
%% qos => 0 | 1 | 2 | [0, 1, 2]
|
||||
%% retain => true | false | all %% only for pub action
|
||||
%% }
|
||||
%% %% <<"allow">> | <"deny">>,
|
||||
%% <<"permission">> => <<"allow">>,
|
||||
%%
|
||||
%% %% <<"pub">> | <<"sub">> | <<"all">>
|
||||
%% <<"action">> => <<"pub">>,
|
||||
%%
|
||||
%% %% <<"a/$#">>, <<"eq a/b/+">>, ...
|
||||
%% <<"topic">> => TopicFilter,
|
||||
%%
|
||||
%% %% when 'topic' is not provided
|
||||
%% <<"topics">> => [TopicFilter],
|
||||
%%
|
||||
%% %% 0 | 1 | 2 | [0, 1, 2] | <<"0">> | <<"1">> | ...
|
||||
%% <<"qos">> => 0,
|
||||
%%
|
||||
%% %% true | false | all | 0 | 1 | <<"true">> | ...
|
||||
%% %% only for pub action
|
||||
%% <<"retain">> => true
|
||||
%% },
|
||||
%% ...
|
||||
%% ]
|
||||
%%
|
||||
authorize(#{acl := Acl} = Client, PubSub, Topic, _Source) ->
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
-type who() :: username() | clientid() | all.
|
||||
|
||||
-type rule() :: {
|
||||
emqx_authz_rule:permission(), emqx_authz_rule:action_precompile(), emqx_types:topic()
|
||||
emqx_authz_rule:permission_resolution_precompile(),
|
||||
emqx_authz_rule:action_precompile(),
|
||||
emqx_authz_rule:topic_precompile()
|
||||
}.
|
||||
-type rules() :: [rule()].
|
||||
|
||||
|
|
Loading…
Reference in New Issue