chore(authz): use atom key for hocon config

This commit is contained in:
zhanghongtong 2021-07-01 15:52:25 +08:00 committed by turtleDeng
parent 47ce507c07
commit bf4c31b745
13 changed files with 167 additions and 149 deletions

View File

@ -1,4 +1,4 @@
authz:{ emqx_authz:{
rules: [ rules: [
# { # {
# type: mysql # type: mysql

View File

@ -1,4 +1,4 @@
-type(rule() :: #{binary() => any()}). -type(rule() :: #{atom() => any()}).
-type(rules() :: [rule()]). -type(rules() :: [rule()]).
-define(APP, emqx_authz). -define(APP, emqx_authz).

View File

@ -38,16 +38,17 @@ init() ->
ok = register_metrics(), ok = register_metrics(),
Conf = filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), Conf = filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'),
{ok, RawConf} = hocon:load(Conf), {ok, RawConf} = hocon:load(Conf),
#{<<"authz">> := #{<<"rules">> := Rules}} = hocon_schema:check_plain(emqx_authz_schema, RawConf), #{emqx_authz := #{rules := Rules}} = hocon_schema:check_plain(emqx_authz_schema, RawConf, #{atom_key => true}),
ok = application:set_env(?APP, rules, Rules), emqx_config:put([emqx_authz], #{rules => Rules}),
% Rules = emqx_config:get([emqx_authz, rules], []),
NRules = [compile(Rule) || Rule <- Rules], NRules = [compile(Rule) || Rule <- Rules],
ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1). ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1).
lookup() -> lookup() ->
application:get_env(?APP, rules, []). emqx_config:get([emqx_authz, rules], []).
update(Rules) -> update(Rules) ->
ok = application:set_env(?APP, rules, Rules), emqx_config:put([emqx_authz], #{rules => Rules}),
NRules = [compile(Rule) || Rule <- Rules], NRules = [compile(Rule) || Rule <- Rules],
Action = find_action_in_hooks(), Action = find_action_in_hooks(),
ok = emqx_hooks:del('client.authorize', Action), ok = emqx_hooks:del('client.authorize', Action),
@ -63,12 +64,12 @@ find_action_in_hooks() ->
[Action] = [Action || {callback,{?MODULE, authorize, _} = Action, _, _} <- Callbacks ], [Action] = [Action || {callback,{?MODULE, authorize, _} = Action, _, _} <- Callbacks ],
Action. Action.
create_resource(#{<<"type">> := DB, create_resource(#{type := DB,
<<"config">> := Config config := Config
} = Rule) -> } = Rule) ->
ResourceID = iolist_to_binary([io_lib:format("~s_~s",[?APP, DB]), "_", integer_to_list(erlang:system_time())]), ResourceID = iolist_to_binary([io_lib:format("~s_~s",[?APP, DB]), "_", integer_to_list(erlang:system_time())]),
NConfig = case DB of NConfig = case DB of
redis -> #{<<"config">> => Config }; redis -> #{config => Config };
_ -> Config _ -> Config
end, end,
case emqx_resource:check_and_create( case emqx_resource:check_and_create(
@ -77,63 +78,63 @@ create_resource(#{<<"type">> := DB,
NConfig) NConfig)
of of
{ok, _} -> {ok, _} ->
Rule#{<<"resource_id">> => ResourceID}; Rule#{resource_id => ResourceID};
{error, already_created} -> {error, already_created} ->
Rule#{<<"resource_id">> => ResourceID}; Rule#{resource_id => ResourceID};
{error, Reason} -> {error, Reason} ->
error({load_config_error, Reason}) error({load_config_error, Reason})
end. end.
-spec(compile(rule()) -> rule()). -spec(compile(rule()) -> rule()).
compile(#{<<"topics">> := Topics, compile(#{topics := Topics,
<<"action">> := Action, action := Action,
<<"permission">> := Permission, permission := Permission,
<<"principal">> := Principal principal := Principal
} = Rule) when ?ALLOW_DENY(Permission), ?PUBSUB(Action), is_list(Topics) -> } = Rule) when ?ALLOW_DENY(Permission), ?PUBSUB(Action), is_list(Topics) ->
NTopics = [compile_topic(Topic) || Topic <- Topics], NTopics = [compile_topic(Topic) || Topic <- Topics],
Rule#{<<"principal">> => compile_principal(Principal), Rule#{principal => compile_principal(Principal),
<<"topics">> => NTopics topics => NTopics
}; };
compile(#{<<"principal">> := Principal, compile(#{principal := Principal,
<<"type">> := redis type := redis
} = Rule) -> } = Rule) ->
NRule = create_resource(Rule), NRule = create_resource(Rule),
NRule#{<<"principal">> => compile_principal(Principal)}; NRule#{principal => compile_principal(Principal)};
compile(#{<<"principal">> := Principal, compile(#{principal := Principal,
<<"type">> := DB, type := DB,
<<"sql">> := SQL sql := SQL
} = Rule) when DB =:= mysql; } = Rule) 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])),
NRule = create_resource(Rule), NRule = create_resource(Rule),
NRule#{<<"principal">> => compile_principal(Principal), NRule#{principal => compile_principal(Principal),
<<"sql">> => Mod:parse_query(SQL) sql => Mod:parse_query(SQL)
}. }.
compile_principal(all) -> all; compile_principal(all) -> all;
compile_principal(#{<<"username">> := Username}) -> compile_principal(#{username := Username}) ->
{ok, MP} = re:compile(bin(Username)), {ok, MP} = re:compile(bin(Username)),
#{<<"username">> => MP}; #{username => MP};
compile_principal(#{<<"clientid">> := Clientid}) -> compile_principal(#{clientid := Clientid}) ->
{ok, MP} = re:compile(bin(Clientid)), {ok, MP} = re:compile(bin(Clientid)),
#{<<"clientid">> => MP}; #{clientid => MP};
compile_principal(#{<<"ipaddress">> := IpAddress}) -> compile_principal(#{ipaddress := IpAddress}) ->
#{<<"ipaddress">> => esockd_cidr:parse(b2l(IpAddress), true)}; #{ipaddress => esockd_cidr:parse(b2l(IpAddress), true)};
compile_principal(#{<<"and">> := Principals}) when is_list(Principals) -> compile_principal(#{'and' := Principals}) when is_list(Principals) ->
#{<<"and">> => [compile_principal(Principal) || Principal <- Principals]}; #{'and' => [compile_principal(Principal) || Principal <- Principals]};
compile_principal(#{<<"or">> := Principals}) when is_list(Principals) -> compile_principal(#{'or' := Principals}) when is_list(Principals) ->
#{<<"or">> => [compile_principal(Principal) || Principal <- Principals]}. #{'or' => [compile_principal(Principal) || Principal <- Principals]}.
compile_topic(<<"eq ", Topic/binary>>) -> compile_topic(<<"eq ", Topic/binary>>) ->
compile_topic(#{<<"eq">> => Topic}); compile_topic(#{'eq' => Topic});
compile_topic(#{<<"eq">> := Topic}) -> compile_topic(#{'eq' := Topic}) ->
#{<<"eq">> => emqx_topic:words(bin(Topic))}; #{'eq' => emqx_topic:words(bin(Topic))};
compile_topic(Topic) when is_binary(Topic)-> compile_topic(Topic) when is_binary(Topic)->
Words = emqx_topic:words(bin(Topic)), Words = emqx_topic:words(bin(Topic)),
case pattern(Words) of case pattern(Words) of
true -> #{<<"pattern">> => Words}; true -> #{pattern => Words};
false -> Words false -> Words
end. end.
@ -173,8 +174,8 @@ authorize(#{username := Username,
end. end.
do_authorize(Client, PubSub, Topic, do_authorize(Client, PubSub, Topic,
[Connector = #{<<"principal">> := Principal, [Connector = #{principal := Principal,
<<"type">> := DB} | Tail] ) -> type := DB} | Tail] ) ->
case match_principal(Client, Principal) of case match_principal(Client, Principal) of
true -> true ->
Mod = list_to_existing_atom(io_lib:format("~s_~s",[emqx_authz, DB])), Mod = list_to_existing_atom(io_lib:format("~s_~s",[emqx_authz, DB])),
@ -185,7 +186,7 @@ do_authorize(Client, PubSub, Topic,
false -> do_authorize(Client, PubSub, Topic, Tail) false -> do_authorize(Client, PubSub, Topic, Tail)
end; end;
do_authorize(Client, PubSub, Topic, do_authorize(Client, PubSub, Topic,
[#{<<"permission">> := Permission} = Rule | Tail]) -> [#{permission := Permission} = Rule | Tail]) ->
case match(Client, PubSub, Topic, Rule) of case match(Client, PubSub, Topic, Rule) of
true -> {matched, Permission}; true -> {matched, Permission};
false -> do_authorize(Client, PubSub, Topic, Tail) false -> do_authorize(Client, PubSub, Topic, Tail)
@ -193,9 +194,9 @@ do_authorize(Client, PubSub, Topic,
do_authorize(_Client, _PubSub, _Topic, []) -> nomatch. do_authorize(_Client, _PubSub, _Topic, []) -> nomatch.
match(Client, PubSub, Topic, match(Client, PubSub, Topic,
#{<<"principal">> := Principal, #{principal := Principal,
<<"topics">> := TopicFilters, topics := TopicFilters,
<<"action">> := Action action := Action
}) -> }) ->
match_action(PubSub, Action) andalso match_action(PubSub, Action) andalso
match_principal(Client, Principal) andalso match_principal(Client, Principal) andalso
@ -207,27 +208,27 @@ match_action(_, all) -> true;
match_action(_, _) -> false. match_action(_, _) -> false.
match_principal(_, all) -> true; match_principal(_, all) -> true;
match_principal(#{username := undefined}, #{<<"username">> := _MP}) -> match_principal(#{username := undefined}, #{username := _MP}) ->
false; false;
match_principal(#{username := Username}, #{<<"username">> := MP}) -> match_principal(#{username := Username}, #{username := MP}) ->
case re:run(Username, MP) of case re:run(Username, MP) of
{match, _} -> true; {match, _} -> true;
_ -> false _ -> false
end; end;
match_principal(#{clientid := Clientid}, #{<<"clientid">> := MP}) -> match_principal(#{clientid := Clientid}, #{clientid := MP}) ->
case re:run(Clientid, MP) of case re:run(Clientid, MP) of
{match, _} -> true; {match, _} -> true;
_ -> false _ -> false
end; end;
match_principal(#{peerhost := undefined}, #{<<"ipaddress">> := _CIDR}) -> match_principal(#{peerhost := undefined}, #{ipaddress := _CIDR}) ->
false; false;
match_principal(#{peerhost := IpAddress}, #{<<"ipaddress">> := CIDR}) -> match_principal(#{peerhost := IpAddress}, #{ipaddress := CIDR}) ->
esockd_cidr:match(IpAddress, CIDR); esockd_cidr:match(IpAddress, CIDR);
match_principal(ClientInfo, #{<<"and">> := Principals}) when is_list(Principals) -> match_principal(ClientInfo, #{'and' := Principals}) when is_list(Principals) ->
lists:foldl(fun(Principal, Permission) -> lists:foldl(fun(Principal, Permission) ->
match_principal(ClientInfo, Principal) andalso Permission match_principal(ClientInfo, Principal) andalso Permission
end, true, Principals); end, true, Principals);
match_principal(ClientInfo, #{<<"or">> := Principals}) when is_list(Principals) -> match_principal(ClientInfo, #{'or' := Principals}) when is_list(Principals) ->
lists:foldl(fun(Principal, Permission) -> lists:foldl(fun(Principal, Permission) ->
match_principal(ClientInfo, Principal) orelse Permission match_principal(ClientInfo, Principal) orelse Permission
end, false, Principals); end, false, Principals);
@ -235,7 +236,7 @@ match_principal(_, _) -> false.
match_topics(_ClientInfo, _Topic, []) -> match_topics(_ClientInfo, _Topic, []) ->
false; false;
match_topics(ClientInfo, Topic, [#{<<"pattern">> := PatternFilter}|Filters]) -> match_topics(ClientInfo, Topic, [#{pattern := PatternFilter}|Filters]) ->
TopicFilter = feed_var(ClientInfo, PatternFilter), TopicFilter = feed_var(ClientInfo, PatternFilter),
match_topic(emqx_topic:words(Topic), TopicFilter) match_topic(emqx_topic:words(Topic), TopicFilter)
orelse match_topics(ClientInfo, Topic, Filters); orelse match_topics(ClientInfo, Topic, Filters);
@ -243,7 +244,7 @@ match_topics(ClientInfo, Topic, [TopicFilter|Filters]) ->
match_topic(emqx_topic:words(Topic), TopicFilter) match_topic(emqx_topic:words(Topic), TopicFilter)
orelse match_topics(ClientInfo, Topic, Filters). orelse match_topics(ClientInfo, Topic, Filters).
match_topic(Topic, #{<<"eq">> := TopicFilter}) -> match_topic(Topic, #{'eq' := TopicFilter}) ->
Topic == TopicFilter; Topic == TopicFilter;
match_topic(Topic, TopicFilter) -> match_topic(Topic, TopicFilter) ->
emqx_topic:match(Topic, TopicFilter). emqx_topic:match(Topic, TopicFilter).

View File

@ -74,10 +74,9 @@ push_authz(_Bindings, Params) ->
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
get_rules(Params) -> get_rules(Params) ->
% #{<<"authz">> := #{<<"rules">> := Rules}} = hocon_schema:check_plain(emqx_authz_schema, #{<<"authz">> => Params}), {ok, Conf} = hocon:binary(jsx:encode(#{<<"emqx_authz">> => Params}), #{format => richmap}),
{ok, Conf} = hocon:binary(jsx:encode(#{<<"authz">> => Params}), #{format => richmap}), CheckConf = hocon_schema:check(emqx_authz_schema, Conf, #{atom_key => true}),
CheckConf = hocon_schema:check(emqx_authz_schema, Conf), #{emqx_authz := #{rules := Rules}} = hocon_schema:richmap_to_map(CheckConf),
#{<<"authz">> := #{<<"rules">> := Rules}} = hocon_schema:richmap_to_map(CheckConf),
Rules. Rules.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------

View File

@ -46,8 +46,8 @@ parse_query(Sql) ->
end. end.
authorize(Client, PubSub, Topic, authorize(Client, PubSub, Topic,
#{<<"resource_id">> := ResourceID, #{resource_id := ResourceID,
<<"sql">> := {SQL, Params} sql := {SQL, Params}
}) -> }) ->
case emqx_resource:query(ResourceID, {sql, SQL, replvar(Params, Client)}) of case emqx_resource:query(ResourceID, {sql, SQL, replvar(Params, Client)}) of
{ok, _Columns, []} -> nomatch; {ok, _Columns, []} -> nomatch;
@ -87,12 +87,12 @@ match(Client, PubSub, Topic,
<<"action">> => Action, <<"action">> => Action,
<<"permission">> => Permission <<"permission">> => Permission
}, },
#{<<"simple_rule">> := #{simple_rule :=
#{<<"permission">> := NPermission} = NRule #{permission := NPermission} = NRule
} = hocon_schema:check_plain( } = hocon_schema:check_plain(
emqx_authz_schema, emqx_authz_schema,
#{<<"simple_rule">> => Rule}, #{<<"simple_rule">> => Rule},
#{}, #{atom_key => true},
[simple_rule]), [simple_rule]),
case emqx_authz:match(Client, PubSub, Topic, emqx_authz:compile(NRule)) of case emqx_authz:match(Client, PubSub, Topic, emqx_authz:compile(NRule)) of
true -> {matched, NPermission}; true -> {matched, NPermission};

View File

@ -50,8 +50,8 @@ parse_query(Sql) ->
end. end.
authorize(Client, PubSub, Topic, authorize(Client, PubSub, Topic,
#{<<"resource_id">> := ResourceID, #{resource_id := ResourceID,
<<"sql">> := {SQL, Params} sql := {SQL, Params}
}) -> }) ->
case emqx_resource:query(ResourceID, {sql, SQL, replvar(Params, Client)}) of case emqx_resource:query(ResourceID, {sql, SQL, replvar(Params, Client)}) of
{ok, _Columns, []} -> nomatch; {ok, _Columns, []} -> nomatch;
@ -91,12 +91,12 @@ match(Client, PubSub, Topic,
<<"action">> => Action, <<"action">> => Action,
<<"permission">> => Permission <<"permission">> => Permission
}, },
#{<<"simple_rule">> := #{simple_rule :=
#{<<"permission">> := NPermission} = NRule #{permission := NPermission} = NRule
} = hocon_schema:check_plain( } = hocon_schema:check_plain(
emqx_authz_schema, emqx_authz_schema,
#{<<"simple_rule">> => Rule}, #{<<"simple_rule">> => Rule},
#{}, #{atom_key => true},
[simple_rule]), [simple_rule]),
case emqx_authz:match(Client, PubSub, Topic, emqx_authz:compile(NRule)) of case emqx_authz:match(Client, PubSub, Topic, emqx_authz:compile(NRule)) of
true -> {matched, NPermission}; true -> {matched, NPermission};

View File

@ -34,8 +34,8 @@ description() ->
"AuthZ with redis". "AuthZ with redis".
authorize(Client, PubSub, Topic, authorize(Client, PubSub, Topic,
#{<<"resource_id">> := ResourceID, #{resource_id := ResourceID,
<<"cmd">> := CMD cmd := CMD
}) -> }) ->
NCMD = string:tokens(replvar(CMD, Client), " "), NCMD = string:tokens(replvar(CMD, Client), " "),
case emqx_resource:query(ResourceID, {cmd, NCMD}) of case emqx_resource:query(ResourceID, {cmd, NCMD}) of
@ -68,11 +68,11 @@ match(Client, PubSub, Topic,
<<"action">> => Action, <<"action">> => Action,
<<"permission">> => allow <<"permission">> => allow
}, },
#{<<"simple_rule">> := NRule #{simple_rule := NRule
} = hocon_schema:check_plain( } = hocon_schema:check_plain(
emqx_authz_schema, emqx_authz_schema,
#{<<"simple_rule">> => Rule}, #{<<"simple_rule">> => Rule},
#{}, #{atom_key => true},
[simple_rule]), [simple_rule]),
case emqx_authz:match(Client, PubSub, Topic, emqx_authz:compile(NRule)) of case emqx_authz:match(Client, PubSub, Topic, emqx_authz:compile(NRule)) of
true -> {matched, allow}; true -> {matched, allow};

View File

@ -11,9 +11,9 @@
-export([structs/0, fields/1]). -export([structs/0, fields/1]).
structs() -> [authz]. structs() -> ["emqx_authz"].
fields(authz) -> fields("emqx_authz") ->
[ {rules, rules()} [ {rules, rules()}
]; ];
fields(redis_connector) -> fields(redis_connector) ->
@ -39,7 +39,7 @@ fields(simple_rule) ->
, {action, #{type => action()}} , {action, #{type => action()}}
, {topics, #{type => union_array( , {topics, #{type => union_array(
[ binary() [ binary()
, hoconsc:ref(eq_topic) , hoconsc:ref(?MODULE, eq_topic)
] ]
)}} )}}
, {principal, principal()} , {principal, principal()}
@ -52,18 +52,18 @@ fields(ipaddress) ->
[{ipaddress, #{type => string()}}]; [{ipaddress, #{type => string()}}];
fields(andlist) -> fields(andlist) ->
[{'and', #{type => union_array( [{'and', #{type => union_array(
[ hoconsc:ref(username) [ hoconsc:ref(?MODULE, username)
, hoconsc:ref(clientid) , hoconsc:ref(?MODULE, clientid)
, hoconsc:ref(ipaddress) , hoconsc:ref(?MODULE, ipaddress)
]) ])
} }
} }
]; ];
fields(orlist) -> fields(orlist) ->
[{'or', #{type => union_array( [{'or', #{type => union_array(
[ hoconsc:ref(username) [ hoconsc:ref(?MODULE, username)
, hoconsc:ref(clientid) , hoconsc:ref(?MODULE, clientid)
, hoconsc:ref(ipaddress) , hoconsc:ref(?MODULE, ipaddress)
]) ])
} }
} }
@ -81,9 +81,9 @@ union_array(Item) when is_list(Item) ->
rules() -> rules() ->
#{type => union_array( #{type => union_array(
[ hoconsc:ref(simple_rule) [ hoconsc:ref(?MODULE, simple_rule)
, hoconsc:ref(sql_connector) , hoconsc:ref(?MODULE, sql_connector)
, hoconsc:ref(redis_connector) , hoconsc:ref(?MODULE, redis_connector)
]) ])
}. }.
@ -91,11 +91,11 @@ principal() ->
#{default => all, #{default => all,
type => hoconsc:union( type => hoconsc:union(
[ all [ all
, hoconsc:ref(username) , hoconsc:ref(?MODULE, username)
, hoconsc:ref(clientid) , hoconsc:ref(?MODULE, clientid)
, hoconsc:ref(ipaddress) , hoconsc:ref(?MODULE, ipaddress)
, hoconsc:ref(andlist) , hoconsc:ref(?MODULE, andlist)
, hoconsc:ref(orlist) , hoconsc:ref(?MODULE, orlist)
]) ])
}. }.

View File

@ -43,41 +43,42 @@ set_special_configs(emqx) ->
set_special_configs(emqx_authz) -> set_special_configs(emqx_authz) ->
application:set_env(emqx, plugins_etc_dir, application:set_env(emqx, plugins_etc_dir,
emqx_ct_helpers:deps_path(emqx_authz, "test")), emqx_ct_helpers:deps_path(emqx_authz, "test")),
Conf = #{<<"authz">> => #{<<"rules">> => []}}, Conf = #{<<"emqx_authz">> => #{<<"rules">> => []}},
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)), ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
% emqx_config:put([emqx_authz], #{rules => []}),
ok; ok;
set_special_configs(_App) -> set_special_configs(_App) ->
ok. ok.
-define(RULE1, #{<<"principal">> => all, -define(RULE1, #{principal => all,
<<"topics">> => [<<"#">>], topics => [<<"#">>],
<<"action">> => all, action => all,
<<"permission">> => deny} permission => deny}
). ).
-define(RULE2, #{<<"principal">> => -define(RULE2, #{principal =>
#{<<"ipaddress">> => <<"127.0.0.1">>}, #{ipaddress => <<"127.0.0.1">>},
<<"topics">> => topics =>
[#{<<"eq">> => <<"#">>}, [#{eq => <<"#">>},
#{<<"eq">> => <<"+">>} #{eq => <<"+">>}
] , ] ,
<<"action">> => all, action => all,
<<"permission">> => allow} permission => allow}
). ).
-define(RULE3,#{<<"principal">> => -define(RULE3,#{principal =>
#{<<"and">> => [#{<<"username">> => "^test?"}, #{'and' => [#{username => "^test?"},
#{<<"clientid">> => "^test?"} #{clientid => "^test?"}
]}, ]},
<<"topics">> => [<<"test">>], topics => [<<"test">>],
<<"action">> => publish, action => publish,
<<"permission">> => allow} permission => allow}
). ).
-define(RULE4,#{<<"principal">> => -define(RULE4,#{principal =>
#{<<"or">> => [#{<<"username">> => <<"^test">>}, #{'or' => [#{username => <<"^test">>},
#{<<"clientid">> => <<"test?">>} #{clientid => <<"test?">>}
]}, ]},
<<"topics">> => [<<"%u">>,<<"%c">>], topics => [<<"%u">>,<<"%c">>],
<<"action">> => publish, action => publish,
<<"permission">> => deny} permission => deny}
). ).
@ -85,38 +86,38 @@ set_special_configs(_App) ->
%% Testcases %% Testcases
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------
t_compile(_) -> t_compile(_) ->
?assertEqual(#{<<"permission">> => deny, ?assertEqual(#{permission => deny,
<<"action">> => all, action => all,
<<"principal">> => all, principal => all,
<<"topics">> => [['#']] topics => [['#']]
},emqx_authz:compile(?RULE1)), },emqx_authz:compile(?RULE1)),
?assertEqual(#{<<"permission">> => allow, ?assertEqual(#{permission => allow,
<<"action">> => all, action => all,
<<"principal">> => principal =>
#{<<"ipaddress">> => {{127,0,0,1},{127,0,0,1},32}}, #{ipaddress => {{127,0,0,1},{127,0,0,1},32}},
<<"topics">> => [#{<<"eq">> => ['#']}, topics => [#{eq => ['#']},
#{<<"eq">> => ['+']}] #{eq => ['+']}]
}, emqx_authz:compile(?RULE2)), }, emqx_authz:compile(?RULE2)),
?assertMatch( ?assertMatch(
#{<<"permission">> := allow, #{permission := allow,
<<"action">> := publish, action := publish,
<<"principal">> := principal :=
#{<<"and">> := [#{<<"username">> := {re_pattern, _, _, _, _}}, #{'and' := [#{username := {re_pattern, _, _, _, _}},
#{<<"clientid">> := {re_pattern, _, _, _, _}} #{clientid := {re_pattern, _, _, _, _}}
] ]
}, },
<<"topics">> := [[<<"test">>]] topics := [[<<"test">>]]
}, emqx_authz:compile(?RULE3)), }, emqx_authz:compile(?RULE3)),
?assertMatch( ?assertMatch(
#{<<"permission">> := deny, #{permission := deny,
<<"action">> := publish, action := publish,
<<"principal">> := principal :=
#{<<"or">> := [#{<<"username">> := {re_pattern, _, _, _, _}}, #{'or' := [#{username := {re_pattern, _, _, _, _}},
#{<<"clientid">> := {re_pattern, _, _, _, _}} #{clientid := {re_pattern, _, _, _, _}}
] ]
}, },
<<"topics">> := [#{<<"pattern">> := [<<"%u">>]}, topics := [#{pattern := [<<"%u">>]},
#{<<"pattern">> := [<<"%c">>]} #{pattern := [<<"%c">>]}
] ]
}, emqx_authz:compile(?RULE4)), }, emqx_authz:compile(?RULE4)),
ok. ok.

View File

@ -57,11 +57,10 @@ set_special_configs(emqx) ->
set_special_configs(emqx_authz) -> set_special_configs(emqx_authz) ->
application:set_env(emqx, plugins_etc_dir, application:set_env(emqx, plugins_etc_dir,
emqx_ct_helpers:deps_path(emqx_authz, "test")), emqx_ct_helpers:deps_path(emqx_authz, "test")),
Conf = #{<<"authz">> => #{<<"rules">> => []}}, Conf = #{<<"emqx_authz">> => #{<<"rules">> => []}},
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)), ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
% emqx_config:put([emqx_authz], #{rules => []}),
ok; ok;
set_special_configs(_App) -> set_special_configs(_App) ->
ok. ok.

View File

@ -49,7 +49,7 @@ set_special_configs(emqx) ->
set_special_configs(emqx_authz) -> set_special_configs(emqx_authz) ->
application:set_env(emqx, plugins_etc_dir, application:set_env(emqx, plugins_etc_dir,
emqx_ct_helpers:deps_path(emqx_authz, "test")), emqx_ct_helpers:deps_path(emqx_authz, "test")),
Conf = #{<<"authz">> => Conf = #{<<"emqx_authz">> =>
#{<<"rules">> => #{<<"rules">> =>
[#{<<"config">> =>#{<<"meck">> => <<"fake">>}, [#{<<"config">> =>#{<<"meck">> => <<"fake">>},
<<"principal">> => all, <<"principal">> => all,
@ -57,6 +57,12 @@ set_special_configs(emqx_authz) ->
<<"type">> => mysql} <<"type">> => mysql}
]}}, ]}},
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)), ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
% Rules = [#{config =>#{<<"meck">> => <<"fake">>},
% principal => all,
% sql => <<"fake sql">>,
% type => mysql}
% ],
% emqx_config:put([emqx_authz], #{rules => Rules}),
ok; ok;
set_special_configs(_App) -> set_special_configs(_App) ->
ok. ok.

View File

@ -49,7 +49,7 @@ set_special_configs(emqx) ->
set_special_configs(emqx_authz) -> set_special_configs(emqx_authz) ->
application:set_env(emqx, plugins_etc_dir, application:set_env(emqx, plugins_etc_dir,
emqx_ct_helpers:deps_path(emqx_authz, "test")), emqx_ct_helpers:deps_path(emqx_authz, "test")),
Conf = #{<<"authz">> => Conf = #{<<"emqx_authz">> =>
#{<<"rules">> => #{<<"rules">> =>
[#{<<"config">> =>#{<<"meck">> => <<"fake">>}, [#{<<"config">> =>#{<<"meck">> => <<"fake">>},
<<"principal">> => all, <<"principal">> => all,
@ -57,6 +57,12 @@ set_special_configs(emqx_authz) ->
<<"type">> => pgsql} <<"type">> => pgsql}
]}}, ]}},
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)), ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
% Rules = [#{config =>#{<<"meck">> => <<"fake">>},
% principal => all,
% sql => <<"fake sql">>,
% type => pgsql}
% ],
% emqx_config:put([emqx_authz], #{rules => Rules}),
ok; ok;
set_special_configs(_App) -> set_special_configs(_App) ->
ok. ok.

View File

@ -49,7 +49,7 @@ set_special_configs(emqx) ->
set_special_configs(emqx_authz) -> set_special_configs(emqx_authz) ->
application:set_env(emqx, plugins_etc_dir, application:set_env(emqx, plugins_etc_dir,
emqx_ct_helpers:deps_path(emqx_authz, "test")), emqx_ct_helpers:deps_path(emqx_authz, "test")),
Conf = #{<<"authz">> => Conf = #{<<"emqx_authz">> =>
#{<<"rules">> => #{<<"rules">> =>
[#{<<"config">> =>#{ [#{<<"config">> =>#{
<<"server">> => <<"127.0.0.1:6379">>, <<"server">> => <<"127.0.0.1:6379">>,
@ -63,6 +63,12 @@ set_special_configs(emqx_authz) ->
<<"type">> => redis} <<"type">> => redis}
]}}, ]}},
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)), ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
% Rules = [#{config =>#{<<"meck">> => <<"fake">>},
% principal => all,
% cmd => <<"fake cmd">>,
% type => redis}
% ],
% emqx_config:put([emqx_authz], #{rules => Rules}),
ok; ok;
set_special_configs(_App) -> set_special_configs(_App) ->
ok. ok.