diff --git a/apps/emqx_authz/src/emqx_authz.erl b/apps/emqx_authz/src/emqx_authz.erl index 286d8f472..c420a1d78 100644 --- a/apps/emqx_authz/src/emqx_authz.erl +++ b/apps/emqx_authz/src/emqx_authz.erl @@ -87,20 +87,16 @@ gen_id(Type) -> iolist_to_binary([io_lib:format("~s_~s",[?APP, Type]), "_", integer_to_list(erlang:system_time())]). create_resource(#{type := DB, - config := Config - } = Rule) -> + config := Config}) -> ResourceID = gen_id(DB), case emqx_resource:create( ResourceID, list_to_existing_atom(io_lib:format("~s_~s",[emqx_connector, DB])), Config) of - {ok, _} -> - Rule#{id => ResourceID}; - {error, already_created} -> - Rule#{id => ResourceID}; - {error, Reason} -> - error({load_config_error, Reason}) + {ok, _} -> ResourceID; + {error, already_created} -> ResourceID; + {error, Reason} -> {error, Reason} end. -spec(init_rule(rule()) -> rule()). @@ -109,10 +105,10 @@ init_rule(#{topics := Topics, permission := Permission, principal := Principal } = Rule) when ?ALLOW_DENY(Permission), ?PUBSUB(Action), is_list(Topics) -> - NTopics = [compile_topic(Topic) || Topic <- Topics], - Rule#{principal => compile_principal(Principal), - topics => NTopics, - id => gen_id(simple) + Rule#{annotations => + #{id => gen_id(simple), + principal => compile_principal(Principal), + topics => [compile_topic(Topic) || Topic <- Topics]} }; init_rule(#{principal := Principal, @@ -121,16 +117,28 @@ init_rule(#{principal := Principal, config := #{url := Url} = Config } = Rule) -> NConfig = maps:merge(Config, #{base_url => maps:remove(query, Url)}), - NRule = create_resource(Rule#{config := NConfig}), - NRule#{principal => compile_principal(Principal)}; + case create_resource(Rule#{config := NConfig}) of + {error, Reason} -> error({load_config_error, Reason}); + Id -> Rule#{annotations => + #{id => Id, + principal => compile_principal(Principal) + } + } + end; init_rule(#{principal := Principal, enable := true, type := DB } = Rule) when DB =:= redis; DB =:= mongo -> - NRule = create_resource(Rule), - NRule#{principal => compile_principal(Principal)}; + case create_resource(Rule) of + {error, Reason} -> error({load_config_error, Reason}); + Id -> Rule#{annotations => + #{id => Id, + principal => compile_principal(Principal) + } + } + end; init_rule(#{principal := Principal, enable := true, @@ -139,10 +147,16 @@ init_rule(#{principal := Principal, } = Rule) when DB =:= mysql; DB =:= pgsql -> Mod = list_to_existing_atom(io_lib:format("~s_~s",[?APP, DB])), - NRule = create_resource(Rule), - NRule#{principal => compile_principal(Principal), - sql => Mod:parse_query(SQL) - }; + case create_resource(Rule) of + {error, Reason} -> error({load_config_error, Reason}); + Id -> Rule#{annotations => + #{id => Id, + principal => compile_principal(Principal), + sql => Mod:parse_query(SQL) + } + } + end; + init_rule(#{enable := false, type := _DB } = Rule) -> @@ -209,9 +223,10 @@ authorize(#{username := Username, end. do_authorize(Client, PubSub, Topic, - [Connector = #{principal := Principal, - type := DB, - enable := true} | Tail] ) -> + [Connector = #{type := DB, + enable := true, + annotations := #{principal := Principal} + } | Tail] ) -> case match_principal(Client, Principal) of true -> Mod = list_to_existing_atom(io_lib:format("~s_~s",[emqx_authz, DB])), @@ -230,9 +245,11 @@ do_authorize(Client, PubSub, Topic, do_authorize(_Client, _PubSub, _Topic, []) -> nomatch. match(Client, PubSub, Topic, - #{principal := Principal, - topics := TopicFilters, - action := Action + #{action := Action, + annotations := #{ + principal := Principal, + topics := TopicFilters + } }) -> match_action(PubSub, Action) andalso match_principal(Client, Principal) andalso diff --git a/apps/emqx_authz/src/emqx_authz_http.erl b/apps/emqx_authz/src/emqx_authz_http.erl index a058fda21..c95d200e1 100644 --- a/apps/emqx_authz/src/emqx_authz_http.erl +++ b/apps/emqx_authz/src/emqx_authz_http.erl @@ -34,12 +34,12 @@ description() -> "AuthZ with http". authorize(Client, PubSub, Topic, - #{id := ResourceID, - type := http, + #{type := http, config := #{url := #{path := Path} = Url, headers := Headers, method := Method, - request_timeout := RequestTimeout} = Config + request_timeout := RequestTimeout} = Config, + annotations := #{id := ResourceID} }) -> Request = case Method of get -> diff --git a/apps/emqx_authz/src/emqx_authz_mongo.erl b/apps/emqx_authz/src/emqx_authz_mongo.erl index 4407b9784..c015f8208 100644 --- a/apps/emqx_authz/src/emqx_authz_mongo.erl +++ b/apps/emqx_authz/src/emqx_authz_mongo.erl @@ -34,9 +34,9 @@ description() -> "AuthZ with Mongo". authorize(Client, PubSub, Topic, - #{id := ResourceID, - collection := Collection, - find := Find + #{collection := Collection, + find := Find, + annotations := #{id := ResourceID} }) -> case emqx_resource:query(ResourceID, {find, Collection, replvar(Find, Client), #{}}) of {error, Reason} -> diff --git a/apps/emqx_authz/src/emqx_authz_mysql.erl b/apps/emqx_authz/src/emqx_authz_mysql.erl index 9972ca2a4..e8ec300b3 100644 --- a/apps/emqx_authz/src/emqx_authz_mysql.erl +++ b/apps/emqx_authz/src/emqx_authz_mysql.erl @@ -46,8 +46,9 @@ parse_query(Sql) -> end. authorize(Client, PubSub, Topic, - #{id := ResourceID, - sql := {SQL, Params} + #{annotations := #{id := ResourceID, + sql := {SQL, Params} + } }) -> case emqx_resource:query(ResourceID, {sql, SQL, replvar(Params, Client)}) of {ok, _Columns, []} -> nomatch; diff --git a/apps/emqx_authz/src/emqx_authz_pgsql.erl b/apps/emqx_authz/src/emqx_authz_pgsql.erl index b55904f95..c94afd885 100644 --- a/apps/emqx_authz/src/emqx_authz_pgsql.erl +++ b/apps/emqx_authz/src/emqx_authz_pgsql.erl @@ -50,8 +50,9 @@ parse_query(Sql) -> end. authorize(Client, PubSub, Topic, - #{id := ResourceID, - sql := {SQL, Params} + #{annotations := #{id := ResourceID, + sql := {SQL, Params} + } }) -> case emqx_resource:query(ResourceID, {sql, SQL, replvar(Params, Client)}) of {ok, _Columns, []} -> nomatch; diff --git a/apps/emqx_authz/src/emqx_authz_redis.erl b/apps/emqx_authz/src/emqx_authz_redis.erl index 869ebb1eb..8f6731fd8 100644 --- a/apps/emqx_authz/src/emqx_authz_redis.erl +++ b/apps/emqx_authz/src/emqx_authz_redis.erl @@ -34,8 +34,8 @@ description() -> "AuthZ with redis". authorize(Client, PubSub, Topic, - #{id := ResourceID, - cmd := CMD + #{cmd := CMD, + annotations := #{id := ResourceID} }) -> NCMD = string:tokens(replvar(CMD, Client), " "), case emqx_resource:query(ResourceID, {cmd, NCMD}) of diff --git a/apps/emqx_authz/test/emqx_authz_SUITE.erl b/apps/emqx_authz/test/emqx_authz_SUITE.erl index 5c10d22ee..dd3f38519 100644 --- a/apps/emqx_authz/test/emqx_authz_SUITE.erl +++ b/apps/emqx_authz/test/emqx_authz_SUITE.erl @@ -74,44 +74,36 @@ end_per_suite(_Config) -> %% Testcases %%------------------------------------------------------------------------------ t_init_rule(_) -> - ?assertMatch(#{permission := deny, - action := all, - principal := all, - topics := [['#']], - id := _ID + ?assertMatch(#{annotations := #{id := _ID, + principal := all, + topics := [['#']]} }, emqx_authz:init_rule(?RULE1)), - ?assertMatch(#{permission := allow, - action := all, - principal := - #{ipaddress := {{127,0,0,1},{127,0,0,1},32}}, - topics := [#{eq := ['#']}, - #{eq := ['+']}], - id := _ID + ?assertMatch(#{annotations := #{principal := + #{ipaddress := {{127,0,0,1},{127,0,0,1},32}}, + topics := [#{eq := ['#']}, + #{eq := ['+']}], + id := _ID} }, emqx_authz:init_rule(?RULE2)), - ?assertMatch( - #{permission := allow, - action := publish, - principal := - #{'and' := [#{username := {re_pattern, _, _, _, _}}, - #{clientid := {re_pattern, _, _, _, _}} - ] - }, - topics := [[<<"test">>]], - id := _ID - }, emqx_authz:init_rule(?RULE3)), - ?assertMatch( - #{permission := deny, - action := publish, - principal := - #{'or' := [#{username := {re_pattern, _, _, _, _}}, - #{clientid := {re_pattern, _, _, _, _}} - ] - }, - topics := [#{pattern := [<<"%u">>]}, - #{pattern := [<<"%c">>]} - ], - id := _ID - }, emqx_authz:init_rule(?RULE4)), + ?assertMatch(#{annotations := + #{principal := + #{'and' := [#{username := {re_pattern, _, _, _, _}}, + #{clientid := {re_pattern, _, _, _, _}} + ] + }, + topics := [[<<"test">>]], + id := _ID} + }, emqx_authz:init_rule(?RULE3)), + ?assertMatch(#{annotations := + #{principal := + #{'or' := [#{username := {re_pattern, _, _, _, _}}, + #{clientid := {re_pattern, _, _, _, _}} + ] + }, + topics := [#{pattern := [<<"%u">>]}, + #{pattern := [<<"%c">>]} + ], + id := _ID} + }, emqx_authz:init_rule(?RULE4)), ok. t_authz(_) ->