chore(emqx_authz): rename rules to sources in emqx_authz
This commit is contained in:
parent
9d9eb2095b
commit
46fb99d44e
|
@ -80,7 +80,6 @@ fields("stats") ->
|
||||||
|
|
||||||
fields("authorization") ->
|
fields("authorization") ->
|
||||||
[ {"no_match", t(union(allow, deny), undefined, allow)}
|
[ {"no_match", t(union(allow, deny), undefined, allow)}
|
||||||
, {"enable", t(boolean(), undefined, true)}
|
|
||||||
, {"deny_action", t(union(ignore, disconnect), undefined, ignore)}
|
, {"deny_action", t(union(ignore, disconnect), undefined, ignore)}
|
||||||
, {"cache", ref("authorization_cache")}
|
, {"cache", ref("authorization_cache")}
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
authorization {
|
authorization {
|
||||||
rules = [
|
sources = [
|
||||||
# {
|
# {
|
||||||
# type: http
|
# type: http
|
||||||
# config: {
|
# config: {
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
-type(rule() :: {permission(), who(), action(), list(emqx_topic:topic())}).
|
-type(rule() :: {permission(), who(), action(), list(emqx_topic:topic())}).
|
||||||
-type(rules() :: [rule()]).
|
-type(rules() :: [rule()]).
|
||||||
|
|
||||||
|
-type(sources() :: [map()]).
|
||||||
|
|
||||||
-define(APP, emqx_authz).
|
-define(APP, emqx_authz).
|
||||||
|
|
||||||
-define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= <<"allow">>) orelse
|
-define(ALLOW_DENY(A), ((A =:= allow) orelse (A =:= <<"allow">>) orelse
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
-export([post_config_update/4, pre_config_update/2]).
|
-export([post_config_update/4, pre_config_update/2]).
|
||||||
|
|
||||||
-define(CONF_KEY_PATH, [authorization, rules]).
|
-define(CONF_KEY_PATH, [authorization, sources]).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
-spec(register_metrics() -> ok).
|
||||||
register_metrics() ->
|
register_metrics() ->
|
||||||
|
@ -45,15 +45,15 @@ register_metrics() ->
|
||||||
init() ->
|
init() ->
|
||||||
ok = register_metrics(),
|
ok = register_metrics(),
|
||||||
emqx_config_handler:add_handler(?CONF_KEY_PATH, ?MODULE),
|
emqx_config_handler:add_handler(?CONF_KEY_PATH, ?MODULE),
|
||||||
NRules = [init_provider(Rule) || Rule <- emqx:get_config(?CONF_KEY_PATH, [])],
|
NSources = [init_source(Source) || Source <- emqx:get_config(?CONF_KEY_PATH, [])],
|
||||||
ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1).
|
ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NSources]}, -1).
|
||||||
|
|
||||||
lookup() ->
|
lookup() ->
|
||||||
{_M, _F, [A]}= find_action_in_hooks(),
|
{_M, _F, [A]}= find_action_in_hooks(),
|
||||||
A.
|
A.
|
||||||
lookup(Id) ->
|
lookup(Id) ->
|
||||||
try find_rule_by_id(Id, lookup()) of
|
try find_source_by_id(Id, lookup()) of
|
||||||
{_, Rule} -> Rule
|
{_, Source} -> Source
|
||||||
catch
|
catch
|
||||||
error:Reason -> {error, Reason}
|
error:Reason -> {error, Reason}
|
||||||
end.
|
end.
|
||||||
|
@ -61,23 +61,23 @@ lookup(Id) ->
|
||||||
move(Id, Position) ->
|
move(Id, Position) ->
|
||||||
emqx:update_config(?CONF_KEY_PATH, {move, Id, Position}).
|
emqx:update_config(?CONF_KEY_PATH, {move, Id, Position}).
|
||||||
|
|
||||||
update(Cmd, Rules) ->
|
update(Cmd, Sources) ->
|
||||||
emqx:update_config(?CONF_KEY_PATH, {Cmd, Rules}).
|
emqx:update_config(?CONF_KEY_PATH, {Cmd, Sources}).
|
||||||
|
|
||||||
pre_config_update({move, Id, <<"top">>}, Conf) when is_list(Conf) ->
|
pre_config_update({move, Id, <<"top">>}, Conf) when is_list(Conf) ->
|
||||||
{Index, _} = find_rule_by_id(Id),
|
{Index, _} = find_source_by_id(Id),
|
||||||
{List1, List2} = lists:split(Index, Conf),
|
{List1, List2} = lists:split(Index, Conf),
|
||||||
{ok, [lists:nth(Index, Conf)] ++ lists:droplast(List1) ++ List2};
|
{ok, [lists:nth(Index, Conf)] ++ lists:droplast(List1) ++ List2};
|
||||||
|
|
||||||
pre_config_update({move, Id, <<"bottom">>}, Conf) when is_list(Conf) ->
|
pre_config_update({move, Id, <<"bottom">>}, Conf) when is_list(Conf) ->
|
||||||
{Index, _} = find_rule_by_id(Id),
|
{Index, _} = find_source_by_id(Id),
|
||||||
{List1, List2} = lists:split(Index, Conf),
|
{List1, List2} = lists:split(Index, Conf),
|
||||||
{ok, lists:droplast(List1) ++ List2 ++ [lists:nth(Index, Conf)]};
|
{ok, lists:droplast(List1) ++ List2 ++ [lists:nth(Index, Conf)]};
|
||||||
|
|
||||||
pre_config_update({move, Id, #{<<"before">> := BeforeId}}, Conf) when is_list(Conf) ->
|
pre_config_update({move, Id, #{<<"before">> := BeforeId}}, Conf) when is_list(Conf) ->
|
||||||
{Index1, _} = find_rule_by_id(Id),
|
{Index1, _} = find_source_by_id(Id),
|
||||||
Conf1 = lists:nth(Index1, Conf),
|
Conf1 = lists:nth(Index1, Conf),
|
||||||
{Index2, _} = find_rule_by_id(BeforeId),
|
{Index2, _} = find_source_by_id(BeforeId),
|
||||||
Conf2 = lists:nth(Index2, Conf),
|
Conf2 = lists:nth(Index2, Conf),
|
||||||
|
|
||||||
{List1, List2} = lists:split(Index2, Conf),
|
{List1, List2} = lists:split(Index2, Conf),
|
||||||
|
@ -86,117 +86,117 @@ pre_config_update({move, Id, #{<<"before">> := BeforeId}}, Conf) when is_list(Co
|
||||||
++ lists:delete(Conf1, List2)};
|
++ lists:delete(Conf1, List2)};
|
||||||
|
|
||||||
pre_config_update({move, Id, #{<<"after">> := AfterId}}, Conf) when is_list(Conf) ->
|
pre_config_update({move, Id, #{<<"after">> := AfterId}}, Conf) when is_list(Conf) ->
|
||||||
{Index1, _} = find_rule_by_id(Id),
|
{Index1, _} = find_source_by_id(Id),
|
||||||
Conf1 = lists:nth(Index1, Conf),
|
Conf1 = lists:nth(Index1, Conf),
|
||||||
{Index2, _} = find_rule_by_id(AfterId),
|
{Index2, _} = find_source_by_id(AfterId),
|
||||||
|
|
||||||
{List1, List2} = lists:split(Index2, Conf),
|
{List1, List2} = lists:split(Index2, Conf),
|
||||||
{ok, lists:delete(Conf1, List1)
|
{ok, lists:delete(Conf1, List1)
|
||||||
++ [Conf1]
|
++ [Conf1]
|
||||||
++ lists:delete(Conf1, List2)};
|
++ lists:delete(Conf1, List2)};
|
||||||
|
|
||||||
pre_config_update({head, Rules}, Conf) when is_list(Rules), is_list(Conf) ->
|
pre_config_update({head, Sources}, Conf) when is_list(Sources), is_list(Conf) ->
|
||||||
{ok, Rules ++ Conf};
|
{ok, Sources ++ Conf};
|
||||||
pre_config_update({tail, Rules}, Conf) when is_list(Rules), is_list(Conf) ->
|
pre_config_update({tail, Sources}, Conf) when is_list(Sources), is_list(Conf) ->
|
||||||
{ok, Conf ++ Rules};
|
{ok, Conf ++ Sources};
|
||||||
pre_config_update({{replace_once, Id}, Rule}, Conf) when is_map(Rule), is_list(Conf) ->
|
pre_config_update({{replace_once, Id}, Source}, Conf) when is_map(Source), is_list(Conf) ->
|
||||||
{Index, _} = find_rule_by_id(Id),
|
{Index, _} = find_source_by_id(Id),
|
||||||
{List1, List2} = lists:split(Index, Conf),
|
{List1, List2} = lists:split(Index, Conf),
|
||||||
{ok, lists:droplast(List1) ++ [Rule] ++ List2};
|
{ok, lists:droplast(List1) ++ [Source] ++ List2};
|
||||||
pre_config_update({_, Rules}, _Conf) when is_list(Rules)->
|
pre_config_update({_, Sources}, _Conf) when is_list(Sources)->
|
||||||
%% overwrite the entire config!
|
%% overwrite the entire config!
|
||||||
{ok, Rules}.
|
{ok, Sources}.
|
||||||
|
|
||||||
post_config_update(_, undefined, _Conf, _AppEnvs) ->
|
post_config_update(_, undefined, _Conf, _AppEnvs) ->
|
||||||
ok;
|
ok;
|
||||||
post_config_update({move, Id, <<"top">>}, _NewRules, _OldRules, _AppEnvs) ->
|
post_config_update({move, Id, <<"top">>}, _NewSources, _OldSources, _AppEnvs) ->
|
||||||
InitedRules = lookup(),
|
InitedSources = lookup(),
|
||||||
{Index, Rule} = find_rule_by_id(Id, InitedRules),
|
{Index, Source} = find_source_by_id(Id, InitedSources),
|
||||||
{Rules1, Rules2 } = lists:split(Index, InitedRules),
|
{Sources1, Sources2 } = lists:split(Index, InitedSources),
|
||||||
Rules3 = [Rule] ++ lists:droplast(Rules1) ++ Rules2,
|
Sources3 = [Source] ++ lists:droplast(Sources1) ++ Sources2,
|
||||||
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Rules3]}, -1),
|
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Sources3]}, -1),
|
||||||
ok = emqx_authz_cache:drain_cache();
|
ok = emqx_authz_cache:drain_cache();
|
||||||
post_config_update({move, Id, <<"bottom">>}, _NewRules, _OldRules, _AppEnvs) ->
|
post_config_update({move, Id, <<"bottom">>}, _NewSources, _OldSources, _AppEnvs) ->
|
||||||
InitedRules = lookup(),
|
InitedSources = lookup(),
|
||||||
{Index, Rule} = find_rule_by_id(Id, InitedRules),
|
{Index, Source} = find_source_by_id(Id, InitedSources),
|
||||||
{Rules1, Rules2 } = lists:split(Index, InitedRules),
|
{Sources1, Sources2 } = lists:split(Index, InitedSources),
|
||||||
Rules3 = lists:droplast(Rules1) ++ Rules2 ++ [Rule],
|
Sources3 = lists:droplast(Sources1) ++ Sources2 ++ [Source],
|
||||||
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Rules3]}, -1),
|
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Sources3]}, -1),
|
||||||
ok = emqx_authz_cache:drain_cache();
|
ok = emqx_authz_cache:drain_cache();
|
||||||
post_config_update({move, Id, #{<<"before">> := BeforeId}}, _NewRules, _OldRules, _AppEnvs) ->
|
post_config_update({move, Id, #{<<"before">> := BeforeId}}, _NewSources, _OldSources, _AppEnvs) ->
|
||||||
InitedRules = lookup(),
|
InitedSources = lookup(),
|
||||||
{_, Rule0} = find_rule_by_id(Id, InitedRules),
|
{_, Source0} = find_source_by_id(Id, InitedSources),
|
||||||
{Index, Rule1} = find_rule_by_id(BeforeId, InitedRules),
|
{Index, Source1} = find_source_by_id(BeforeId, InitedSources),
|
||||||
{Rules1, Rules2} = lists:split(Index, InitedRules),
|
{Sources1, Sources2} = lists:split(Index, InitedSources),
|
||||||
Rules3 = lists:delete(Rule0, lists:droplast(Rules1))
|
Sources3 = lists:delete(Source0, lists:droplast(Sources1))
|
||||||
++ [Rule0] ++ [Rule1]
|
++ [Source0] ++ [Source1]
|
||||||
++ lists:delete(Rule0, Rules2),
|
++ lists:delete(Source0, Sources2),
|
||||||
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Rules3]}, -1),
|
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Sources3]}, -1),
|
||||||
ok = emqx_authz_cache:drain_cache();
|
ok = emqx_authz_cache:drain_cache();
|
||||||
|
|
||||||
post_config_update({move, Id, #{<<"after">> := AfterId}}, _NewRules, _OldRules, _AppEnvs) ->
|
post_config_update({move, Id, #{<<"after">> := AfterId}}, _NewSources, _OldSources, _AppEnvs) ->
|
||||||
InitedRules = lookup(),
|
InitedSources = lookup(),
|
||||||
{_, Rule} = find_rule_by_id(Id, InitedRules),
|
{_, Source} = find_source_by_id(Id, InitedSources),
|
||||||
{Index, _} = find_rule_by_id(AfterId, InitedRules),
|
{Index, _} = find_source_by_id(AfterId, InitedSources),
|
||||||
{Rules1, Rules2} = lists:split(Index, InitedRules),
|
{Sources1, Sources2} = lists:split(Index, InitedSources),
|
||||||
Rules3 = lists:delete(Rule, Rules1)
|
Sources3 = lists:delete(Source, Sources1)
|
||||||
++ [Rule]
|
++ [Source]
|
||||||
++ lists:delete(Rule, Rules2),
|
++ lists:delete(Source, Sources2),
|
||||||
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Rules3]}, -1),
|
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [Sources3]}, -1),
|
||||||
ok = emqx_authz_cache:drain_cache();
|
ok = emqx_authz_cache:drain_cache();
|
||||||
|
|
||||||
post_config_update({head, Rules}, _NewRules, _OldConf, _AppEnvs) ->
|
post_config_update({head, Sources}, _NewSources, _OldConf, _AppEnvs) ->
|
||||||
InitedRules = [init_provider(R) || R <- check_rules(Rules)],
|
InitedSources = [init_source(R) || R <- check_sources(Sources)],
|
||||||
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [InitedRules ++ lookup()]}, -1),
|
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [InitedSources ++ lookup()]}, -1),
|
||||||
ok = emqx_authz_cache:drain_cache();
|
ok = emqx_authz_cache:drain_cache();
|
||||||
|
|
||||||
post_config_update({tail, Rules}, _NewRules, _OldConf, _AppEnvs) ->
|
post_config_update({tail, Sources}, _NewSources, _OldConf, _AppEnvs) ->
|
||||||
InitedRules = [init_provider(R) || R <- check_rules(Rules)],
|
InitedSources = [init_source(R) || R <- check_sources(Sources)],
|
||||||
emqx_hooks:put('client.authorize', {?MODULE, authorize, [lookup() ++ InitedRules]}, -1),
|
emqx_hooks:put('client.authorize', {?MODULE, authorize, [lookup() ++ InitedSources]}, -1),
|
||||||
ok = emqx_authz_cache:drain_cache();
|
ok = emqx_authz_cache:drain_cache();
|
||||||
|
|
||||||
post_config_update({{replace_once, Id}, Rule}, _NewRules, _OldConf, _AppEnvs) when is_map(Rule) ->
|
post_config_update({{replace_once, Id}, Source}, _NewSources, _OldConf, _AppEnvs) when is_map(Source) ->
|
||||||
OldInitedRules = lookup(),
|
OldInitedSources = lookup(),
|
||||||
{Index, OldRule} = find_rule_by_id(Id, OldInitedRules),
|
{Index, OldSource} = find_source_by_id(Id, OldInitedSources),
|
||||||
case maps:get(type, OldRule, undefined) of
|
case maps:get(type, OldSource, undefined) of
|
||||||
undefined -> ok;
|
undefined -> ok;
|
||||||
_ ->
|
_ ->
|
||||||
#{annotations := #{id := Id}} = OldRule,
|
#{annotations := #{id := Id}} = OldSource,
|
||||||
ok = emqx_resource:remove(Id)
|
ok = emqx_resource:remove(Id)
|
||||||
end,
|
end,
|
||||||
{OldRules1, OldRules2 } = lists:split(Index, OldInitedRules),
|
{OldSources1, OldSources2 } = lists:split(Index, OldInitedSources),
|
||||||
InitedRules = [init_provider(R#{annotations => #{id => Id}}) || R <- check_rules([Rule])],
|
InitedSources = [init_source(R#{annotations => #{id => Id}}) || R <- check_sources([Source])],
|
||||||
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [lists:droplast(OldRules1) ++ InitedRules ++ OldRules2]}, -1),
|
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [lists:droplast(OldSources1) ++ InitedSources ++ OldSources2]}, -1),
|
||||||
ok = emqx_authz_cache:drain_cache();
|
ok = emqx_authz_cache:drain_cache();
|
||||||
|
|
||||||
post_config_update(_, NewRules, _OldConf, _AppEnvs) ->
|
post_config_update(_, NewSources, _OldConf, _AppEnvs) ->
|
||||||
%% overwrite the entire config!
|
%% overwrite the entire config!
|
||||||
OldInitedRules = lookup(),
|
OldInitedSources = lookup(),
|
||||||
InitedRules = [init_provider(Rule) || Rule <- NewRules],
|
InitedSources = [init_source(Source) || Source <- NewSources],
|
||||||
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [InitedRules]}, -1),
|
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [InitedSources]}, -1),
|
||||||
lists:foreach(fun (#{type := _Type, enable := true, annotations := #{id := Id}}) ->
|
lists:foreach(fun (#{type := _Type, enable := true, annotations := #{id := Id}}) ->
|
||||||
ok = emqx_resource:remove(Id);
|
ok = emqx_resource:remove(Id);
|
||||||
(_) -> ok
|
(_) -> ok
|
||||||
end, OldInitedRules),
|
end, OldInitedSources),
|
||||||
ok = emqx_authz_cache:drain_cache().
|
ok = emqx_authz_cache:drain_cache().
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
check_rules(RawRules) ->
|
check_sources(RawSources) ->
|
||||||
{ok, Conf} = hocon:binary(jsx:encode(#{<<"authorization">> => #{<<"rules">> => RawRules}}), #{format => richmap}),
|
{ok, Conf} = hocon:binary(jsx:encode(#{<<"authorization">> => #{<<"sources">> => RawSources}}), #{format => richmap}),
|
||||||
CheckConf = hocon_schema:check(emqx_authz_schema, Conf, #{atom_key => true}),
|
CheckConf = hocon_schema:check(emqx_authz_schema, Conf, #{atom_key => true}),
|
||||||
#{authorization:= #{rules := Rules}} = hocon_schema:richmap_to_map(CheckConf),
|
#{authorization:= #{sources := Sources}} = hocon_schema:richmap_to_map(CheckConf),
|
||||||
Rules.
|
Sources.
|
||||||
|
|
||||||
find_rule_by_id(Id) -> find_rule_by_id(Id, lookup()).
|
find_source_by_id(Id) -> find_source_by_id(Id, lookup()).
|
||||||
find_rule_by_id(Id, Rules) -> find_rule_by_id(Id, Rules, 1).
|
find_source_by_id(Id, Sources) -> find_source_by_id(Id, Sources, 1).
|
||||||
find_rule_by_id(_RuleId, [], _N) -> error(not_found_rule);
|
find_source_by_id(_SourceId, [], _N) -> error(not_found_rule);
|
||||||
find_rule_by_id(RuleId, [ Rule = #{annotations := #{id := Id}} | Tail], N) ->
|
find_source_by_id(SourceId, [ Source = #{annotations := #{id := Id}} | Tail], N) ->
|
||||||
case RuleId =:= Id of
|
case SourceId =:= Id of
|
||||||
true -> {N, Rule};
|
true -> {N, Source};
|
||||||
false -> find_rule_by_id(RuleId, Tail, N + 1)
|
false -> find_source_by_id(SourceId, Tail, N + 1)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
find_action_in_hooks() ->
|
find_action_in_hooks() ->
|
||||||
|
@ -232,10 +232,10 @@ create_resource(#{type := DB,
|
||||||
{error, Reason} -> {error, Reason}
|
{error, Reason} -> {error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
init_provider(#{enable := true,
|
init_source(#{enable := true,
|
||||||
type := file,
|
type := file,
|
||||||
path := Path
|
path := Path
|
||||||
} = Rule) ->
|
} = Source) ->
|
||||||
Rules = case file:consult(Path) of
|
Rules = case file:consult(Path) of
|
||||||
{ok, Terms} ->
|
{ok, Terms} ->
|
||||||
[emqx_authz_rule:compile(Term) || Term <- Terms];
|
[emqx_authz_rule:compile(Term) || Term <- Terms];
|
||||||
|
@ -249,58 +249,58 @@ init_provider(#{enable := true,
|
||||||
?LOG(alert, "Failed to read ~s: ~p", [Path, Reason]),
|
?LOG(alert, "Failed to read ~s: ~p", [Path, Reason]),
|
||||||
error(Reason)
|
error(Reason)
|
||||||
end,
|
end,
|
||||||
Rule#{annotations =>
|
Source#{annotations =>
|
||||||
#{id => gen_id(file),
|
#{id => gen_id(file),
|
||||||
rules => Rules
|
rules => Rules
|
||||||
}};
|
}};
|
||||||
init_provider(#{enable := true,
|
init_source(#{enable := true,
|
||||||
type := http,
|
type := http,
|
||||||
config := #{url := Url} = Config
|
config := #{url := Url} = Config
|
||||||
} = Rule) ->
|
} = Source) ->
|
||||||
NConfig = maps:merge(Config, #{base_url => maps:remove(query, Url)}),
|
NConfig = maps:merge(Config, #{base_url => maps:remove(query, Url)}),
|
||||||
case create_resource(Rule#{config := NConfig}) of
|
case create_resource(Source#{config := NConfig}) of
|
||||||
{error, Reason} -> error({load_config_error, Reason});
|
{error, Reason} -> error({load_config_error, Reason});
|
||||||
Id -> Rule#{annotations =>
|
Id -> Source#{annotations =>
|
||||||
#{id => Id}
|
#{id => Id}
|
||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
init_provider(#{enable := true,
|
init_source(#{enable := true,
|
||||||
type := DB
|
type := DB
|
||||||
} = Rule) when DB =:= redis;
|
} = Source) when DB =:= redis;
|
||||||
DB =:= mongo ->
|
DB =:= mongo ->
|
||||||
case create_resource(Rule) of
|
case create_resource(Source) of
|
||||||
{error, Reason} -> error({load_config_error, Reason});
|
{error, Reason} -> error({load_config_error, Reason});
|
||||||
Id -> Rule#{annotations =>
|
Id -> Source#{annotations =>
|
||||||
#{id => Id}
|
#{id => Id}
|
||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
init_provider(#{enable := true,
|
init_source(#{enable := true,
|
||||||
type := DB,
|
type := DB,
|
||||||
sql := SQL
|
sql := SQL
|
||||||
} = Rule) when DB =:= mysql;
|
} = Source) when DB =:= mysql;
|
||||||
DB =:= pgsql ->
|
DB =:= pgsql ->
|
||||||
Mod = list_to_existing_atom(io_lib:format("~s_~s",[?APP, DB])),
|
Mod = list_to_existing_atom(io_lib:format("~s_~s",[?APP, DB])),
|
||||||
case create_resource(Rule) of
|
case create_resource(Source) of
|
||||||
{error, Reason} -> error({load_config_error, Reason});
|
{error, Reason} -> error({load_config_error, Reason});
|
||||||
Id -> Rule#{annotations =>
|
Id -> Source#{annotations =>
|
||||||
#{id => Id,
|
#{id => Id,
|
||||||
sql => Mod:parse_query(SQL)
|
sql => Mod:parse_query(SQL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
init_provider(#{enable := false} = Rule) ->Rule.
|
init_source(#{enable := false} = Source) ->Source.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% AuthZ callbacks
|
%% AuthZ callbacks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% @doc Check AuthZ
|
%% @doc Check AuthZ
|
||||||
-spec(authorize(emqx_types:clientinfo(), emqx_types:all(), emqx_topic:topic(), allow | deny, rules())
|
-spec(authorize(emqx_types:clientinfo(), emqx_types:all(), emqx_topic:topic(), allow | deny, sources())
|
||||||
-> {stop, allow} | {ok, deny}).
|
-> {stop, allow} | {ok, deny}).
|
||||||
authorize(#{username := Username,
|
authorize(#{username := Username,
|
||||||
peerhost := IpAddress
|
peerhost := IpAddress
|
||||||
} = Client, PubSub, Topic, DefaultResult, Rules) ->
|
} = Client, PubSub, Topic, DefaultResult, Sources) ->
|
||||||
case do_authorize(Client, PubSub, Topic, Rules) of
|
case do_authorize(Client, PubSub, Topic, Sources) of
|
||||||
{matched, allow} ->
|
{matched, allow} ->
|
||||||
?LOG(info, "Client succeeded authorization: Username: ~p, IP: ~p, Topic: ~p, Permission: allow", [Username, IpAddress, Topic]),
|
?LOG(info, "Client succeeded authorization: Username: ~p, IP: ~p, Topic: ~p, Permission: allow", [Username, IpAddress, Topic]),
|
||||||
emqx_metrics:inc(?AUTHZ_METRICS(allow)),
|
emqx_metrics:inc(?AUTHZ_METRICS(allow)),
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
structs() -> ["authorization"].
|
structs() -> ["authorization"].
|
||||||
|
|
||||||
fields("authorization") ->
|
fields("authorization") ->
|
||||||
[ {rules, rules()}
|
[ {sources, sources()}
|
||||||
];
|
];
|
||||||
fields(file) ->
|
fields(file) ->
|
||||||
[ {type, #{type => file}}
|
[ {type, #{type => file}}
|
||||||
|
@ -146,7 +146,7 @@ fields(eq_topic) ->
|
||||||
union_array(Item) when is_list(Item) ->
|
union_array(Item) when is_list(Item) ->
|
||||||
hoconsc:array(hoconsc:union(Item)).
|
hoconsc:array(hoconsc:union(Item)).
|
||||||
|
|
||||||
rules() ->
|
sources() ->
|
||||||
#{type => union_array(
|
#{type => union_array(
|
||||||
[ hoconsc:ref(?MODULE, file)
|
[ hoconsc:ref(?MODULE, file)
|
||||||
, hoconsc:ref(?MODULE, http)
|
, hoconsc:ref(?MODULE, http)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_ct:all(?MODULE).
|
emqx_ct:all(?MODULE).
|
||||||
|
@ -60,14 +60,14 @@ init_per_testcase(_, Config) ->
|
||||||
{ok, _} = emqx_authz:update(replace, []),
|
{ok, _} = emqx_authz:update(replace, []),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
-define(RULE1, #{<<"type">> => <<"http">>,
|
-define(SOURCE1, #{<<"type">> => <<"http">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"url">> => <<"https://fake.com:443/">>,
|
<<"url">> => <<"https://fake.com:443/">>,
|
||||||
<<"headers">> => #{},
|
<<"headers">> => #{},
|
||||||
<<"method">> => <<"get">>,
|
<<"method">> => <<"get">>,
|
||||||
<<"request_timeout">> => 5000}
|
<<"request_timeout">> => 5000}
|
||||||
}).
|
}).
|
||||||
-define(RULE2, #{<<"type">> => <<"mongo">>,
|
-define(SOURCE2, #{<<"type">> => <<"mongo">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"mongo_type">> => <<"single">>,
|
<<"mongo_type">> => <<"single">>,
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
|
@ -77,7 +77,7 @@ init_per_testcase(_, Config) ->
|
||||||
<<"collection">> => <<"fake">>,
|
<<"collection">> => <<"fake">>,
|
||||||
<<"find">> => #{<<"a">> => <<"b">>}
|
<<"find">> => #{<<"a">> => <<"b">>}
|
||||||
}).
|
}).
|
||||||
-define(RULE3, #{<<"type">> => <<"mysql">>,
|
-define(SOURCE3, #{<<"type">> => <<"mysql">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
<<"pool_size">> => 1,
|
<<"pool_size">> => 1,
|
||||||
|
@ -88,7 +88,7 @@ init_per_testcase(_, Config) ->
|
||||||
<<"ssl">> => #{<<"enable">> => false}},
|
<<"ssl">> => #{<<"enable">> => false}},
|
||||||
<<"sql">> => <<"abcb">>
|
<<"sql">> => <<"abcb">>
|
||||||
}).
|
}).
|
||||||
-define(RULE4, #{<<"type">> => <<"pgsql">>,
|
-define(SOURCE4, #{<<"type">> => <<"pgsql">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
<<"pool_size">> => 1,
|
<<"pool_size">> => 1,
|
||||||
|
@ -99,7 +99,7 @@ init_per_testcase(_, Config) ->
|
||||||
<<"ssl">> => #{<<"enable">> => false}},
|
<<"ssl">> => #{<<"enable">> => false}},
|
||||||
<<"sql">> => <<"abcb">>
|
<<"sql">> => <<"abcb">>
|
||||||
}).
|
}).
|
||||||
-define(RULE5, #{<<"type">> => <<"redis">>,
|
-define(SOURCE5, #{<<"type">> => <<"redis">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
<<"pool_size">> => 1,
|
<<"pool_size">> => 1,
|
||||||
|
@ -114,21 +114,21 @@ init_per_testcase(_, Config) ->
|
||||||
%% Testcases
|
%% Testcases
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
t_update_rule(_) ->
|
t_update_source(_) ->
|
||||||
{ok, _} = emqx_authz:update(replace, [?RULE2]),
|
{ok, _} = emqx_authz:update(replace, [?SOURCE2]),
|
||||||
{ok, _} = emqx_authz:update(head, [?RULE1]),
|
{ok, _} = emqx_authz:update(head, [?SOURCE1]),
|
||||||
{ok, _} = emqx_authz:update(tail, [?RULE3]),
|
{ok, _} = emqx_authz:update(tail, [?SOURCE3]),
|
||||||
|
|
||||||
?assertMatch([#{type := http}, #{type := mongo}, #{type := mysql}], emqx:get_config([authorization, rules], [])),
|
?assertMatch([#{type := http}, #{type := mongo}, #{type := mysql}], emqx:get_config([authorization, sources], [])),
|
||||||
|
|
||||||
[#{annotations := #{id := Id1}, type := http},
|
[#{annotations := #{id := Id1}, type := http},
|
||||||
#{annotations := #{id := Id2}, type := mongo},
|
#{annotations := #{id := Id2}, type := mongo},
|
||||||
#{annotations := #{id := Id3}, type := mysql}
|
#{annotations := #{id := Id3}, type := mysql}
|
||||||
] = emqx_authz:lookup(),
|
] = emqx_authz:lookup(),
|
||||||
|
|
||||||
{ok, _} = emqx_authz:update({replace_once, Id1}, ?RULE5),
|
{ok, _} = emqx_authz:update({replace_once, Id1}, ?SOURCE5),
|
||||||
{ok, _} = emqx_authz:update({replace_once, Id3}, ?RULE4),
|
{ok, _} = emqx_authz:update({replace_once, Id3}, ?SOURCE4),
|
||||||
?assertMatch([#{type := redis}, #{type := mongo}, #{type := pgsql}], emqx:get_config([authorization, rules], [])),
|
?assertMatch([#{type := redis}, #{type := mongo}, #{type := pgsql}], emqx:get_config([authorization, sources], [])),
|
||||||
|
|
||||||
[#{annotations := #{id := Id1}, type := redis},
|
[#{annotations := #{id := Id1}, type := redis},
|
||||||
#{annotations := #{id := Id2}, type := mongo},
|
#{annotations := #{id := Id2}, type := mongo},
|
||||||
|
@ -137,8 +137,8 @@ t_update_rule(_) ->
|
||||||
|
|
||||||
{ok, _} = emqx_authz:update(replace, []).
|
{ok, _} = emqx_authz:update(replace, []).
|
||||||
|
|
||||||
t_move_rule(_) ->
|
t_move_source(_) ->
|
||||||
{ok, _} = emqx_authz:update(replace, [?RULE1, ?RULE2, ?RULE3, ?RULE4, ?RULE5]),
|
{ok, _} = emqx_authz:update(replace, [?SOURCE1, ?SOURCE2, ?SOURCE3, ?SOURCE4, ?SOURCE5]),
|
||||||
[#{annotations := #{id := Id1}},
|
[#{annotations := #{id := Id1}},
|
||||||
#{annotations := #{id := Id2}},
|
#{annotations := #{id := Id2}},
|
||||||
#{annotations := #{id := Id3}},
|
#{annotations := #{id := Id3}},
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
-import(emqx_ct_http, [ request_api/3
|
-import(emqx_ct_http, [ request_api/3
|
||||||
, request_api/5
|
, request_api/5
|
||||||
|
@ -37,14 +37,14 @@
|
||||||
-define(API_VERSION, "v5").
|
-define(API_VERSION, "v5").
|
||||||
-define(BASE_PATH, "api").
|
-define(BASE_PATH, "api").
|
||||||
|
|
||||||
-define(RULE1, #{<<"type">> => <<"http">>,
|
-define(SOURCE1, #{<<"type">> => <<"http">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"url">> => <<"https://fake.com:443/">>,
|
<<"url">> => <<"https://fake.com:443/">>,
|
||||||
<<"headers">> => #{},
|
<<"headers">> => #{},
|
||||||
<<"method">> => <<"get">>,
|
<<"method">> => <<"get">>,
|
||||||
<<"request_timeout">> => 5000}
|
<<"request_timeout">> => 5000}
|
||||||
}).
|
}).
|
||||||
-define(RULE2, #{<<"type">> => <<"mongo">>,
|
-define(SOURCE2, #{<<"type">> => <<"mongo">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"mongo_type">> => <<"single">>,
|
<<"mongo_type">> => <<"single">>,
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
<<"collection">> => <<"fake">>,
|
<<"collection">> => <<"fake">>,
|
||||||
<<"find">> => #{<<"a">> => <<"b">>}
|
<<"find">> => #{<<"a">> => <<"b">>}
|
||||||
}).
|
}).
|
||||||
-define(RULE3, #{<<"type">> => <<"mysql">>,
|
-define(SOURCE3, #{<<"type">> => <<"mysql">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
<<"pool_size">> => 1,
|
<<"pool_size">> => 1,
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
<<"ssl">> => #{<<"enable">> => false}},
|
<<"ssl">> => #{<<"enable">> => false}},
|
||||||
<<"sql">> => <<"abcb">>
|
<<"sql">> => <<"abcb">>
|
||||||
}).
|
}).
|
||||||
-define(RULE4, #{<<"type">> => <<"pgsql">>,
|
-define(SOURCE4, #{<<"type">> => <<"pgsql">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
<<"pool_size">> => 1,
|
<<"pool_size">> => 1,
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
<<"ssl">> => #{<<"enable">> => false}},
|
<<"ssl">> => #{<<"enable">> => false}},
|
||||||
<<"sql">> => <<"abcb">>
|
<<"sql">> => <<"abcb">>
|
||||||
}).
|
}).
|
||||||
-define(RULE5, #{<<"type">> => <<"redis">>,
|
-define(SOURCE5, #{<<"type">> => <<"redis">>,
|
||||||
<<"config">> => #{
|
<<"config">> => #{
|
||||||
<<"server">> => <<"127.0.0.1:27017">>,
|
<<"server">> => <<"127.0.0.1:27017">>,
|
||||||
<<"pool_size">> => 1,
|
<<"pool_size">> => 1,
|
||||||
|
@ -148,7 +148,7 @@ t_api(_) ->
|
||||||
?assertEqual([], get_rules(Result1)),
|
?assertEqual([], get_rules(Result1)),
|
||||||
|
|
||||||
lists:foreach(fun(_) ->
|
lists:foreach(fun(_) ->
|
||||||
{ok, 204, _} = request(post, uri(["authorization"]), ?RULE1)
|
{ok, 204, _} = request(post, uri(["authorization"]), ?SOURCE1)
|
||||||
end, lists:seq(1, 20)),
|
end, lists:seq(1, 20)),
|
||||||
{ok, 200, Result2} = request(get, uri(["authorization"]), []),
|
{ok, 200, Result2} = request(get, uri(["authorization"]), []),
|
||||||
?assertEqual(20, length(get_rules(Result2))),
|
?assertEqual(20, length(get_rules(Result2))),
|
||||||
|
@ -160,7 +160,7 @@ t_api(_) ->
|
||||||
?assertEqual(10, length(get_rules(Result)))
|
?assertEqual(10, length(get_rules(Result)))
|
||||||
end, lists:seq(1, 2)),
|
end, lists:seq(1, 2)),
|
||||||
|
|
||||||
{ok, 204, _} = request(put, uri(["authorization"]), [?RULE1, ?RULE2, ?RULE3, ?RULE4]),
|
{ok, 204, _} = request(put, uri(["authorization"]), [?SOURCE1, ?SOURCE2, ?SOURCE3, ?SOURCE4]),
|
||||||
|
|
||||||
{ok, 200, Result3} = request(get, uri(["authorization"]), []),
|
{ok, 200, Result3} = request(get, uri(["authorization"]), []),
|
||||||
Rules = get_rules(Result3),
|
Rules = get_rules(Result3),
|
||||||
|
@ -173,7 +173,7 @@ t_api(_) ->
|
||||||
|
|
||||||
#{<<"annotations">> := #{<<"id">> := Id}} = lists:nth(2, Rules),
|
#{<<"annotations">> := #{<<"id">> := Id}} = lists:nth(2, Rules),
|
||||||
|
|
||||||
{ok, 204, _} = request(put, uri(["authorization", binary_to_list(Id)]), ?RULE5),
|
{ok, 204, _} = request(put, uri(["authorization", binary_to_list(Id)]), ?SOURCE5),
|
||||||
|
|
||||||
{ok, 200, Result4} = request(get, uri(["authorization", binary_to_list(Id)]), []),
|
{ok, 200, Result4} = request(get, uri(["authorization", binary_to_list(Id)]), []),
|
||||||
?assertMatch(#{<<"type">> := <<"redis">>}, jsx:decode(Result4)),
|
?assertMatch(#{<<"type">> := <<"redis">>}, jsx:decode(Result4)),
|
||||||
|
@ -186,7 +186,7 @@ t_api(_) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_move_rule(_) ->
|
t_move_rule(_) ->
|
||||||
{ok, _} = emqx_authz:update(replace, [?RULE1, ?RULE2, ?RULE3, ?RULE4, ?RULE5]),
|
{ok, _} = emqx_authz:update(replace, [?SOURCE1, ?SOURCE2, ?SOURCE3, ?SOURCE4, ?SOURCE5]),
|
||||||
[#{annotations := #{id := Id1}},
|
[#{annotations := #{id := Id1}},
|
||||||
#{annotations := #{id := Id2}},
|
#{annotations := #{id := Id2}},
|
||||||
#{annotations := #{id := Id3}},
|
#{annotations := #{id := Id3}},
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
-include("emqx_authz.hrl").
|
-include("emqx_authz.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_ct:all(?MODULE).
|
emqx_ct:all(?MODULE).
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_ct:all(?MODULE).
|
emqx_ct:all(?MODULE).
|
||||||
|
@ -66,16 +66,16 @@ end_per_suite(_Config) ->
|
||||||
meck:unload(emqx_schema),
|
meck:unload(emqx_schema),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
-define(RULE1,[#{<<"topics">> => [<<"#">>],
|
-define(SOURCE1,[#{<<"topics">> => [<<"#">>],
|
||||||
<<"permission">> => <<"deny">>,
|
<<"permission">> => <<"deny">>,
|
||||||
<<"action">> => <<"all">>}]).
|
<<"action">> => <<"all">>}]).
|
||||||
-define(RULE2,[#{<<"topics">> => [<<"eq #">>],
|
-define(SOURCE2,[#{<<"topics">> => [<<"eq #">>],
|
||||||
<<"permission">> => <<"allow">>,
|
<<"permission">> => <<"allow">>,
|
||||||
<<"action">> => <<"all">>}]).
|
<<"action">> => <<"all">>}]).
|
||||||
-define(RULE3,[#{<<"topics">> => [<<"test/%c">>],
|
-define(SOURCE3,[#{<<"topics">> => [<<"test/%c">>],
|
||||||
<<"permission">> => <<"allow">>,
|
<<"permission">> => <<"allow">>,
|
||||||
<<"action">> => <<"subscribe">>}]).
|
<<"action">> => <<"subscribe">>}]).
|
||||||
-define(RULE4,[#{<<"topics">> => [<<"test/%u">>],
|
-define(SOURCE4,[#{<<"topics">> => [<<"test/%u">>],
|
||||||
<<"permission">> => <<"allow">>,
|
<<"permission">> => <<"allow">>,
|
||||||
<<"action">> => <<"publish">>}]).
|
<<"action">> => <<"publish">>}]).
|
||||||
|
|
||||||
|
@ -107,15 +107,15 @@ t_authz(_) ->
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)), % nomatch
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)), % nomatch
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"#">>)), % nomatch
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"#">>)), % nomatch
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> ?RULE1 ++ ?RULE2 end),
|
meck:expect(emqx_resource, query, fun(_, _) -> ?SOURCE1 ++ ?SOURCE2 end),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"+">>)),
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> ?RULE2 ++ ?RULE1 end),
|
meck:expect(emqx_resource, query, fun(_, _) -> ?SOURCE2 ++ ?SOURCE1 end),
|
||||||
?assertEqual(allow, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)),
|
?assertEqual(allow, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> ?RULE3 ++ ?RULE4 end),
|
meck:expect(emqx_resource, query, fun(_, _) -> ?SOURCE3 ++ ?SOURCE4 end),
|
||||||
?assertEqual(allow, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_clientid">>)),
|
?assertEqual(allow, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_clientid">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, publish, <<"test/test_clientid">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, publish, <<"test/test_clientid">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_username">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_username">>)),
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_ct:all(?MODULE).
|
emqx_ct:all(?MODULE).
|
||||||
|
@ -72,10 +72,10 @@ end_per_suite(_Config) ->
|
||||||
, <<"permission">>
|
, <<"permission">>
|
||||||
, <<"topic">>
|
, <<"topic">>
|
||||||
]).
|
]).
|
||||||
-define(RULE1, [[<<"all">>, <<"deny">>, <<"#">>]]).
|
-define(SOURCE1, [[<<"all">>, <<"deny">>, <<"#">>]]).
|
||||||
-define(RULE2, [[<<"all">>, <<"allow">>, <<"eq #">>]]).
|
-define(SOURCE2, [[<<"all">>, <<"allow">>, <<"eq #">>]]).
|
||||||
-define(RULE3, [[<<"subscribe">>, <<"allow">>, <<"test/%c">>]]).
|
-define(SOURCE3, [[<<"subscribe">>, <<"allow">>, <<"test/%c">>]]).
|
||||||
-define(RULE4, [[<<"publish">>, <<"allow">>, <<"test/%u">>]]).
|
-define(SOURCE4, [[<<"publish">>, <<"allow">>, <<"test/%u">>]]).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Testcases
|
%% Testcases
|
||||||
|
@ -105,15 +105,15 @@ t_authz(_) ->
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)), % nomatch
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)), % nomatch
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"#">>)), % nomatch
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"#">>)), % nomatch
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?RULE1 ++ ?RULE2} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?SOURCE1 ++ ?SOURCE2} end),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"+">>)),
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?RULE2 ++ ?RULE1} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?SOURCE2 ++ ?SOURCE1} end),
|
||||||
?assertEqual(allow, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)),
|
?assertEqual(allow, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?RULE3 ++ ?RULE4} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?SOURCE3 ++ ?SOURCE4} end),
|
||||||
?assertEqual(allow, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_clientid">>)),
|
?assertEqual(allow, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_clientid">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, publish, <<"test/test_clientid">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, publish, <<"test/test_clientid">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_username">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_username">>)),
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_ct:all(?MODULE).
|
emqx_ct:all(?MODULE).
|
||||||
|
@ -72,10 +72,10 @@ end_per_suite(_Config) ->
|
||||||
, {column, <<"permission">>, meck, meck, meck, meck, meck, meck, meck}
|
, {column, <<"permission">>, meck, meck, meck, meck, meck, meck, meck}
|
||||||
, {column, <<"topic">>, meck, meck, meck, meck, meck, meck, meck}
|
, {column, <<"topic">>, meck, meck, meck, meck, meck, meck, meck}
|
||||||
]).
|
]).
|
||||||
-define(RULE1, [{<<"all">>, <<"deny">>, <<"#">>}]).
|
-define(SOURCE1, [{<<"all">>, <<"deny">>, <<"#">>}]).
|
||||||
-define(RULE2, [{<<"all">>, <<"allow">>, <<"eq #">>}]).
|
-define(SOURCE2, [{<<"all">>, <<"allow">>, <<"eq #">>}]).
|
||||||
-define(RULE3, [{<<"subscribe">>, <<"allow">>, <<"test/%c">>}]).
|
-define(SOURCE3, [{<<"subscribe">>, <<"allow">>, <<"test/%c">>}]).
|
||||||
-define(RULE4, [{<<"publish">>, <<"allow">>, <<"test/%u">>}]).
|
-define(SOURCE4, [{<<"publish">>, <<"allow">>, <<"test/%u">>}]).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Testcases
|
%% Testcases
|
||||||
|
@ -105,15 +105,15 @@ t_authz(_) ->
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)), % nomatch
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)), % nomatch
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"#">>)), % nomatch
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"#">>)), % nomatch
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?RULE1 ++ ?RULE2} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?SOURCE1 ++ ?SOURCE2} end),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, subscribe, <<"+">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo1, publish, <<"+">>)),
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?RULE2 ++ ?RULE1} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?SOURCE2 ++ ?SOURCE1} end),
|
||||||
?assertEqual(allow, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)),
|
?assertEqual(allow, emqx_access_control:authorize(ClientInfo1, subscribe, <<"#">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"+">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"+">>)),
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?RULE3 ++ ?RULE4} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?COLUMNS, ?SOURCE3 ++ ?SOURCE4} end),
|
||||||
?assertEqual(allow, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_clientid">>)),
|
?assertEqual(allow, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_clientid">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, publish, <<"test/test_clientid">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, publish, <<"test/test_clientid">>)),
|
||||||
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_username">>)),
|
?assertEqual(deny, emqx_access_control:authorize(ClientInfo2, subscribe, <<"test/test_username">>)),
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
-include("emqx_authz.hrl").
|
-include("emqx_authz.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_ct:all(?MODULE).
|
emqx_ct:all(?MODULE).
|
||||||
|
@ -66,9 +66,9 @@ end_per_suite(_Config) ->
|
||||||
meck:unload(emqx_schema),
|
meck:unload(emqx_schema),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
-define(RULE1, [<<"test/%u">>, <<"publish">>]).
|
-define(SOURCE1, [<<"test/%u">>, <<"publish">>]).
|
||||||
-define(RULE2, [<<"test/%c">>, <<"publish">>]).
|
-define(SOURCE2, [<<"test/%c">>, <<"publish">>]).
|
||||||
-define(RULE3, [<<"#">>, <<"subscribe">>]).
|
-define(SOURCE3, [<<"#">>, <<"subscribe">>]).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Testcases
|
%% Testcases
|
||||||
|
@ -90,7 +90,7 @@ t_authz(_) ->
|
||||||
emqx_access_control:authorize(ClientInfo, publish, <<"#">>)),
|
emqx_access_control:authorize(ClientInfo, publish, <<"#">>)),
|
||||||
|
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?RULE1 ++ ?RULE2} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?SOURCE1 ++ ?SOURCE2} end),
|
||||||
% nomatch
|
% nomatch
|
||||||
?assertEqual(deny,
|
?assertEqual(deny,
|
||||||
emqx_access_control:authorize(ClientInfo, subscribe, <<"+">>)),
|
emqx_access_control:authorize(ClientInfo, subscribe, <<"+">>)),
|
||||||
|
@ -103,7 +103,7 @@ t_authz(_) ->
|
||||||
?assertEqual(allow,
|
?assertEqual(allow,
|
||||||
emqx_access_control:authorize(ClientInfo, publish, <<"test/clientid">>)),
|
emqx_access_control:authorize(ClientInfo, publish, <<"test/clientid">>)),
|
||||||
|
|
||||||
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?RULE3} end),
|
meck:expect(emqx_resource, query, fun(_, _) -> {ok, ?SOURCE3} end),
|
||||||
|
|
||||||
?assertEqual(allow,
|
?assertEqual(allow,
|
||||||
emqx_access_control:authorize(ClientInfo, subscribe, <<"#">>)),
|
emqx_access_control:authorize(ClientInfo, subscribe, <<"#">>)),
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
-define(RULE1, {deny, all, all, ["#"]}).
|
-define(SOURCE1, {deny, all, all, ["#"]}).
|
||||||
-define(RULE2, {allow, {ipaddr, "127.0.0.1"}, all, [{eq, "#"}, {eq, "+"}]}).
|
-define(SOURCE2, {allow, {ipaddr, "127.0.0.1"}, all, [{eq, "#"}, {eq, "+"}]}).
|
||||||
-define(RULE3, {allow, {ipaddrs, ["127.0.0.1", "192.168.1.0/24"]}, subscribe, ["%c"]}).
|
-define(SOURCE3, {allow, {ipaddrs, ["127.0.0.1", "192.168.1.0/24"]}, subscribe, ["%c"]}).
|
||||||
-define(RULE4, {allow, {'and', [{clientid, "^test?"}, {username, "^test?"}]}, publish, ["topic/test"]}).
|
-define(SOURCE4, {allow, {'and', [{clientid, "^test?"}, {username, "^test?"}]}, publish, ["topic/test"]}).
|
||||||
-define(RULE5, {allow, {'or', [{username, "^test"}, {clientid, "test?"}]}, publish, ["%u", "%c"]}).
|
-define(SOURCE5, {allow, {'or', [{username, "^test"}, {clientid, "test?"}]}, publish, ["%u", "%c"]}).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
emqx_ct:all(?MODULE).
|
emqx_ct:all(?MODULE).
|
||||||
|
@ -40,28 +40,28 @@ end_per_suite(_Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_compile(_) ->
|
t_compile(_) ->
|
||||||
?assertEqual({deny, all, all, [['#']]}, emqx_authz_rule:compile(?RULE1)),
|
?assertEqual({deny, all, all, [['#']]}, emqx_authz_rule:compile(?SOURCE1)),
|
||||||
|
|
||||||
?assertEqual({allow, {ipaddr, {{127,0,0,1}, {127,0,0,1}, 32}}, all, [{eq, ['#']}, {eq, ['+']}]}, emqx_authz_rule:compile(?RULE2)),
|
?assertEqual({allow, {ipaddr, {{127,0,0,1}, {127,0,0,1}, 32}}, all, [{eq, ['#']}, {eq, ['+']}]}, emqx_authz_rule:compile(?SOURCE2)),
|
||||||
|
|
||||||
?assertEqual({allow,
|
?assertEqual({allow,
|
||||||
{ipaddrs,[{{127,0,0,1},{127,0,0,1},32},
|
{ipaddrs,[{{127,0,0,1},{127,0,0,1},32},
|
||||||
{{192,168,1,0},{192,168,1,255},24}]},
|
{{192,168,1,0},{192,168,1,255},24}]},
|
||||||
subscribe,
|
subscribe,
|
||||||
[{pattern,[<<"%c">>]}]
|
[{pattern,[<<"%c">>]}]
|
||||||
}, emqx_authz_rule:compile(?RULE3)),
|
}, emqx_authz_rule:compile(?SOURCE3)),
|
||||||
|
|
||||||
?assertMatch({allow,
|
?assertMatch({allow,
|
||||||
{'and', [{clientid, {re_pattern, _, _, _, _}}, {username, {re_pattern, _, _, _, _}}]},
|
{'and', [{clientid, {re_pattern, _, _, _, _}}, {username, {re_pattern, _, _, _, _}}]},
|
||||||
publish,
|
publish,
|
||||||
[[<<"topic">>, <<"test">>]]
|
[[<<"topic">>, <<"test">>]]
|
||||||
}, emqx_authz_rule:compile(?RULE4)),
|
}, emqx_authz_rule:compile(?SOURCE4)),
|
||||||
|
|
||||||
?assertMatch({allow,
|
?assertMatch({allow,
|
||||||
{'or', [{username, {re_pattern, _, _, _, _}}, {clientid, {re_pattern, _, _, _, _}}]},
|
{'or', [{username, {re_pattern, _, _, _, _}}, {clientid, {re_pattern, _, _, _, _}}]},
|
||||||
publish,
|
publish,
|
||||||
[{pattern, [<<"%u">>]}, {pattern, [<<"%c">>]}]
|
[{pattern, [<<"%u">>]}, {pattern, [<<"%c">>]}]
|
||||||
}, emqx_authz_rule:compile(?RULE5)),
|
}, emqx_authz_rule:compile(?SOURCE5)),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,47 +92,47 @@ t_match(_) ->
|
||||||
},
|
},
|
||||||
|
|
||||||
?assertEqual({matched, deny},
|
?assertEqual({matched, deny},
|
||||||
emqx_authz_rule:match(ClientInfo1, subscribe, <<"#">>, emqx_authz_rule:compile(?RULE1))),
|
emqx_authz_rule:match(ClientInfo1, subscribe, <<"#">>, emqx_authz_rule:compile(?SOURCE1))),
|
||||||
?assertEqual({matched, deny},
|
?assertEqual({matched, deny},
|
||||||
emqx_authz_rule:match(ClientInfo2, subscribe, <<"+">>, emqx_authz_rule:compile(?RULE1))),
|
emqx_authz_rule:match(ClientInfo2, subscribe, <<"+">>, emqx_authz_rule:compile(?SOURCE1))),
|
||||||
?assertEqual({matched, deny},
|
?assertEqual({matched, deny},
|
||||||
emqx_authz_rule:match(ClientInfo3, subscribe, <<"topic/test">>, emqx_authz_rule:compile(?RULE1))),
|
emqx_authz_rule:match(ClientInfo3, subscribe, <<"topic/test">>, emqx_authz_rule:compile(?SOURCE1))),
|
||||||
|
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo1, subscribe, <<"#">>, emqx_authz_rule:compile(?RULE2))),
|
emqx_authz_rule:match(ClientInfo1, subscribe, <<"#">>, emqx_authz_rule:compile(?SOURCE2))),
|
||||||
?assertEqual(nomatch,
|
?assertEqual(nomatch,
|
||||||
emqx_authz_rule:match(ClientInfo1, subscribe, <<"topic/test">>, emqx_authz_rule:compile(?RULE2))),
|
emqx_authz_rule:match(ClientInfo1, subscribe, <<"topic/test">>, emqx_authz_rule:compile(?SOURCE2))),
|
||||||
?assertEqual(nomatch,
|
?assertEqual(nomatch,
|
||||||
emqx_authz_rule:match(ClientInfo2, subscribe, <<"#">>, emqx_authz_rule:compile(?RULE2))),
|
emqx_authz_rule:match(ClientInfo2, subscribe, <<"#">>, emqx_authz_rule:compile(?SOURCE2))),
|
||||||
|
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo1, subscribe, <<"test">>, emqx_authz_rule:compile(?RULE3))),
|
emqx_authz_rule:match(ClientInfo1, subscribe, <<"test">>, emqx_authz_rule:compile(?SOURCE3))),
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo2, subscribe, <<"test">>, emqx_authz_rule:compile(?RULE3))),
|
emqx_authz_rule:match(ClientInfo2, subscribe, <<"test">>, emqx_authz_rule:compile(?SOURCE3))),
|
||||||
?assertEqual(nomatch,
|
?assertEqual(nomatch,
|
||||||
emqx_authz_rule:match(ClientInfo2, subscribe, <<"topic/test">>, emqx_authz_rule:compile(?RULE3))),
|
emqx_authz_rule:match(ClientInfo2, subscribe, <<"topic/test">>, emqx_authz_rule:compile(?SOURCE3))),
|
||||||
|
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo1, publish, <<"topic/test">>, emqx_authz_rule:compile(?RULE4))),
|
emqx_authz_rule:match(ClientInfo1, publish, <<"topic/test">>, emqx_authz_rule:compile(?SOURCE4))),
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo2, publish, <<"topic/test">>, emqx_authz_rule:compile(?RULE4))),
|
emqx_authz_rule:match(ClientInfo2, publish, <<"topic/test">>, emqx_authz_rule:compile(?SOURCE4))),
|
||||||
?assertEqual(nomatch,
|
?assertEqual(nomatch,
|
||||||
emqx_authz_rule:match(ClientInfo3, publish, <<"topic/test">>, emqx_authz_rule:compile(?RULE4))),
|
emqx_authz_rule:match(ClientInfo3, publish, <<"topic/test">>, emqx_authz_rule:compile(?SOURCE4))),
|
||||||
?assertEqual(nomatch,
|
?assertEqual(nomatch,
|
||||||
emqx_authz_rule:match(ClientInfo4, publish, <<"topic/test">>, emqx_authz_rule:compile(?RULE4))),
|
emqx_authz_rule:match(ClientInfo4, publish, <<"topic/test">>, emqx_authz_rule:compile(?SOURCE4))),
|
||||||
|
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo1, publish, <<"test">>, emqx_authz_rule:compile(?RULE5))),
|
emqx_authz_rule:match(ClientInfo1, publish, <<"test">>, emqx_authz_rule:compile(?SOURCE5))),
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo2, publish, <<"test">>, emqx_authz_rule:compile(?RULE5))),
|
emqx_authz_rule:match(ClientInfo2, publish, <<"test">>, emqx_authz_rule:compile(?SOURCE5))),
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo3, publish, <<"test">>, emqx_authz_rule:compile(?RULE5))),
|
emqx_authz_rule:match(ClientInfo3, publish, <<"test">>, emqx_authz_rule:compile(?SOURCE5))),
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo3, publish, <<"fake">>, emqx_authz_rule:compile(?RULE5))),
|
emqx_authz_rule:match(ClientInfo3, publish, <<"fake">>, emqx_authz_rule:compile(?SOURCE5))),
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo4, publish, <<"test">>, emqx_authz_rule:compile(?RULE5))),
|
emqx_authz_rule:match(ClientInfo4, publish, <<"test">>, emqx_authz_rule:compile(?SOURCE5))),
|
||||||
?assertEqual({matched, allow},
|
?assertEqual({matched, allow},
|
||||||
emqx_authz_rule:match(ClientInfo4, publish, <<"fake">>, emqx_authz_rule:compile(?RULE5))),
|
emqx_authz_rule:match(ClientInfo4, publish, <<"fake">>, emqx_authz_rule:compile(?SOURCE5))),
|
||||||
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue