chore(authz): add annotations for rules
Signed-off-by: zhanghongtong <rory-z@outlook.com>
This commit is contained in:
parent
0ef38c75ed
commit
4ef00072b9
|
@ -87,20 +87,16 @@ gen_id(Type) ->
|
||||||
iolist_to_binary([io_lib:format("~s_~s",[?APP, Type]), "_", integer_to_list(erlang:system_time())]).
|
iolist_to_binary([io_lib:format("~s_~s",[?APP, Type]), "_", integer_to_list(erlang:system_time())]).
|
||||||
|
|
||||||
create_resource(#{type := DB,
|
create_resource(#{type := DB,
|
||||||
config := Config
|
config := Config}) ->
|
||||||
} = Rule) ->
|
|
||||||
ResourceID = gen_id(DB),
|
ResourceID = gen_id(DB),
|
||||||
case emqx_resource:create(
|
case emqx_resource:create(
|
||||||
ResourceID,
|
ResourceID,
|
||||||
list_to_existing_atom(io_lib:format("~s_~s",[emqx_connector, DB])),
|
list_to_existing_atom(io_lib:format("~s_~s",[emqx_connector, DB])),
|
||||||
Config)
|
Config)
|
||||||
of
|
of
|
||||||
{ok, _} ->
|
{ok, _} -> ResourceID;
|
||||||
Rule#{id => ResourceID};
|
{error, already_created} -> ResourceID;
|
||||||
{error, already_created} ->
|
{error, Reason} -> {error, Reason}
|
||||||
Rule#{id => ResourceID};
|
|
||||||
{error, Reason} ->
|
|
||||||
error({load_config_error, Reason})
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec(init_rule(rule()) -> rule()).
|
-spec(init_rule(rule()) -> rule()).
|
||||||
|
@ -109,10 +105,10 @@ init_rule(#{topics := Topics,
|
||||||
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],
|
Rule#{annotations =>
|
||||||
Rule#{principal => compile_principal(Principal),
|
#{id => gen_id(simple),
|
||||||
topics => NTopics,
|
principal => compile_principal(Principal),
|
||||||
id => gen_id(simple)
|
topics => [compile_topic(Topic) || Topic <- Topics]}
|
||||||
};
|
};
|
||||||
|
|
||||||
init_rule(#{principal := Principal,
|
init_rule(#{principal := Principal,
|
||||||
|
@ -121,16 +117,28 @@ init_rule(#{principal := Principal,
|
||||||
config := #{url := Url} = Config
|
config := #{url := Url} = Config
|
||||||
} = Rule) ->
|
} = Rule) ->
|
||||||
NConfig = maps:merge(Config, #{base_url => maps:remove(query, Url)}),
|
NConfig = maps:merge(Config, #{base_url => maps:remove(query, Url)}),
|
||||||
NRule = create_resource(Rule#{config := NConfig}),
|
case create_resource(Rule#{config := NConfig}) of
|
||||||
NRule#{principal => compile_principal(Principal)};
|
{error, Reason} -> error({load_config_error, Reason});
|
||||||
|
Id -> Rule#{annotations =>
|
||||||
|
#{id => Id,
|
||||||
|
principal => compile_principal(Principal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end;
|
||||||
|
|
||||||
init_rule(#{principal := Principal,
|
init_rule(#{principal := Principal,
|
||||||
enable := true,
|
enable := true,
|
||||||
type := DB
|
type := DB
|
||||||
} = Rule) when DB =:= redis;
|
} = Rule) when DB =:= redis;
|
||||||
DB =:= mongo ->
|
DB =:= mongo ->
|
||||||
NRule = create_resource(Rule),
|
case create_resource(Rule) of
|
||||||
NRule#{principal => compile_principal(Principal)};
|
{error, Reason} -> error({load_config_error, Reason});
|
||||||
|
Id -> Rule#{annotations =>
|
||||||
|
#{id => Id,
|
||||||
|
principal => compile_principal(Principal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end;
|
||||||
|
|
||||||
init_rule(#{principal := Principal,
|
init_rule(#{principal := Principal,
|
||||||
enable := true,
|
enable := true,
|
||||||
|
@ -139,10 +147,16 @@ init_rule(#{principal := Principal,
|
||||||
} = 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),
|
case create_resource(Rule) of
|
||||||
NRule#{principal => compile_principal(Principal),
|
{error, Reason} -> error({load_config_error, Reason});
|
||||||
sql => Mod:parse_query(SQL)
|
Id -> Rule#{annotations =>
|
||||||
};
|
#{id => Id,
|
||||||
|
principal => compile_principal(Principal),
|
||||||
|
sql => Mod:parse_query(SQL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end;
|
||||||
|
|
||||||
init_rule(#{enable := false,
|
init_rule(#{enable := false,
|
||||||
type := _DB
|
type := _DB
|
||||||
} = Rule) ->
|
} = Rule) ->
|
||||||
|
@ -209,9 +223,10 @@ authorize(#{username := Username,
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_authorize(Client, PubSub, Topic,
|
do_authorize(Client, PubSub, Topic,
|
||||||
[Connector = #{principal := Principal,
|
[Connector = #{type := DB,
|
||||||
type := DB,
|
enable := true,
|
||||||
enable := true} | Tail] ) ->
|
annotations := #{principal := Principal}
|
||||||
|
} | 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])),
|
||||||
|
@ -230,9 +245,11 @@ 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,
|
#{action := Action,
|
||||||
topics := TopicFilters,
|
annotations := #{
|
||||||
action := Action
|
principal := Principal,
|
||||||
|
topics := TopicFilters
|
||||||
|
}
|
||||||
}) ->
|
}) ->
|
||||||
match_action(PubSub, Action) andalso
|
match_action(PubSub, Action) andalso
|
||||||
match_principal(Client, Principal) andalso
|
match_principal(Client, Principal) andalso
|
||||||
|
|
|
@ -34,12 +34,12 @@ description() ->
|
||||||
"AuthZ with http".
|
"AuthZ with http".
|
||||||
|
|
||||||
authorize(Client, PubSub, Topic,
|
authorize(Client, PubSub, Topic,
|
||||||
#{id := ResourceID,
|
#{type := http,
|
||||||
type := http,
|
|
||||||
config := #{url := #{path := Path} = Url,
|
config := #{url := #{path := Path} = Url,
|
||||||
headers := Headers,
|
headers := Headers,
|
||||||
method := Method,
|
method := Method,
|
||||||
request_timeout := RequestTimeout} = Config
|
request_timeout := RequestTimeout} = Config,
|
||||||
|
annotations := #{id := ResourceID}
|
||||||
}) ->
|
}) ->
|
||||||
Request = case Method of
|
Request = case Method of
|
||||||
get ->
|
get ->
|
||||||
|
|
|
@ -34,9 +34,9 @@ description() ->
|
||||||
"AuthZ with Mongo".
|
"AuthZ with Mongo".
|
||||||
|
|
||||||
authorize(Client, PubSub, Topic,
|
authorize(Client, PubSub, Topic,
|
||||||
#{id := ResourceID,
|
#{collection := Collection,
|
||||||
collection := Collection,
|
find := Find,
|
||||||
find := Find
|
annotations := #{id := ResourceID}
|
||||||
}) ->
|
}) ->
|
||||||
case emqx_resource:query(ResourceID, {find, Collection, replvar(Find, Client), #{}}) of
|
case emqx_resource:query(ResourceID, {find, Collection, replvar(Find, Client), #{}}) of
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
|
|
|
@ -46,8 +46,9 @@ parse_query(Sql) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
authorize(Client, PubSub, Topic,
|
authorize(Client, PubSub, Topic,
|
||||||
#{id := ResourceID,
|
#{annotations := #{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;
|
||||||
|
|
|
@ -50,8 +50,9 @@ parse_query(Sql) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
authorize(Client, PubSub, Topic,
|
authorize(Client, PubSub, Topic,
|
||||||
#{id := ResourceID,
|
#{annotations := #{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;
|
||||||
|
|
|
@ -34,8 +34,8 @@ description() ->
|
||||||
"AuthZ with redis".
|
"AuthZ with redis".
|
||||||
|
|
||||||
authorize(Client, PubSub, Topic,
|
authorize(Client, PubSub, Topic,
|
||||||
#{id := ResourceID,
|
#{cmd := CMD,
|
||||||
cmd := CMD
|
annotations := #{id := ResourceID}
|
||||||
}) ->
|
}) ->
|
||||||
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
|
||||||
|
|
|
@ -74,44 +74,36 @@ end_per_suite(_Config) ->
|
||||||
%% Testcases
|
%% Testcases
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
t_init_rule(_) ->
|
t_init_rule(_) ->
|
||||||
?assertMatch(#{permission := deny,
|
?assertMatch(#{annotations := #{id := _ID,
|
||||||
action := all,
|
principal := all,
|
||||||
principal := all,
|
topics := [['#']]}
|
||||||
topics := [['#']],
|
|
||||||
id := _ID
|
|
||||||
}, emqx_authz:init_rule(?RULE1)),
|
}, emqx_authz:init_rule(?RULE1)),
|
||||||
?assertMatch(#{permission := allow,
|
?assertMatch(#{annotations := #{principal :=
|
||||||
action := all,
|
#{ipaddress := {{127,0,0,1},{127,0,0,1},32}},
|
||||||
principal :=
|
topics := [#{eq := ['#']},
|
||||||
#{ipaddress := {{127,0,0,1},{127,0,0,1},32}},
|
#{eq := ['+']}],
|
||||||
topics := [#{eq := ['#']},
|
id := _ID}
|
||||||
#{eq := ['+']}],
|
|
||||||
id := _ID
|
|
||||||
}, emqx_authz:init_rule(?RULE2)),
|
}, emqx_authz:init_rule(?RULE2)),
|
||||||
?assertMatch(
|
?assertMatch(#{annotations :=
|
||||||
#{permission := allow,
|
#{principal :=
|
||||||
action := publish,
|
#{'and' := [#{username := {re_pattern, _, _, _, _}},
|
||||||
principal :=
|
#{clientid := {re_pattern, _, _, _, _}}
|
||||||
#{'and' := [#{username := {re_pattern, _, _, _, _}},
|
]
|
||||||
#{clientid := {re_pattern, _, _, _, _}}
|
},
|
||||||
]
|
topics := [[<<"test">>]],
|
||||||
},
|
id := _ID}
|
||||||
topics := [[<<"test">>]],
|
}, emqx_authz:init_rule(?RULE3)),
|
||||||
id := _ID
|
?assertMatch(#{annotations :=
|
||||||
}, emqx_authz:init_rule(?RULE3)),
|
#{principal :=
|
||||||
?assertMatch(
|
#{'or' := [#{username := {re_pattern, _, _, _, _}},
|
||||||
#{permission := deny,
|
#{clientid := {re_pattern, _, _, _, _}}
|
||||||
action := publish,
|
]
|
||||||
principal :=
|
},
|
||||||
#{'or' := [#{username := {re_pattern, _, _, _, _}},
|
topics := [#{pattern := [<<"%u">>]},
|
||||||
#{clientid := {re_pattern, _, _, _, _}}
|
#{pattern := [<<"%c">>]}
|
||||||
]
|
],
|
||||||
},
|
id := _ID}
|
||||||
topics := [#{pattern := [<<"%u">>]},
|
}, emqx_authz:init_rule(?RULE4)),
|
||||||
#{pattern := [<<"%c">>]}
|
|
||||||
],
|
|
||||||
id := _ID
|
|
||||||
}, emqx_authz:init_rule(?RULE4)),
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_authz(_) ->
|
t_authz(_) ->
|
||||||
|
|
Loading…
Reference in New Issue