chore(emqx_authz): rename rules to sources in emqx_authz

This commit is contained in:
zhanghongtong 2021-08-27 17:15:58 +08:00 committed by Rory Z
parent 9d9eb2095b
commit 46fb99d44e
13 changed files with 192 additions and 191 deletions

View File

@ -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")}
]; ];

View File

@ -1,5 +1,5 @@
authorization { authorization {
rules = [ sources = [
# { # {
# type: http # type: http
# config: { # config: {

View File

@ -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

View File

@ -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)),

View File

@ -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)

View File

@ -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}},

View File

@ -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}},

View File

@ -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).

View File

@ -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">>)),

View File

@ -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">>)),

View File

@ -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">>)),

View File

@ -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, <<"#">>)),

View File

@ -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.