feat(authz): more better update function

Signed-off-by: zhanghongtong <rory-z@outlook.com>
This commit is contained in:
zhanghongtong 2021-08-06 18:04:03 +08:00 committed by Rory Z
parent c26ec5c0dd
commit 4bb1e9c964
8 changed files with 369 additions and 166 deletions

View File

@ -20,11 +20,16 @@
-include("emqx_authz.hrl").
-include_lib("emqx/include/logger.hrl").
-ifdef(TEST).
-compile(export_all).
-compile(nowarn_export_all).
-endif.
-export([ register_metrics/0
, init/0
, init_rule/1
, lookup/0
, lookup/1
, update/2
, authorize/5
, match/4
@ -45,8 +50,13 @@ init() ->
ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1).
lookup() ->
{_M, _F, A}= find_action_in_hooks(),
{_M, _F, [A]}= find_action_in_hooks(),
A.
lookup(Id) ->
case find_rule_by_id(Id, lookup()) of
{error, Reason} -> {error, Reason};
{_, Rule} -> Rule
end.
update(Cmd, Rules) ->
emqx_config:update(emqx_authz_schema, ?CONF_KEY_PATH, {Cmd, Rules}).
@ -56,6 +66,13 @@ pre_config_update({head, Rules}, OldConf) when is_list(Rules), is_list(OldConf)
Rules ++ OldConf;
pre_config_update({tail, Rules}, OldConf) when is_list(Rules), is_list(OldConf) ->
OldConf ++ Rules;
pre_config_update({{replace_once, Id}, Rule}, OldConf) when is_map(Rule), is_list(OldConf) ->
{Index, _} = case find_rule_by_id(Id, lookup()) of
{error, Reason} -> error(Reason);
R -> R
end,
{OldConf1, OldConf2} = lists:split(Index, OldConf),
lists:droplast(OldConf1) ++ [Rule] ++ OldConf2;
pre_config_update({_, Rules}, _OldConf) when is_list(Rules)->
%% overwrite the entire config!
Rules.
@ -63,19 +80,38 @@ pre_config_update({_, Rules}, _OldConf) when is_list(Rules)->
post_config_update(_, undefined, _OldConf) ->
ok;
post_config_update({head, Rules}, _NewRules, _OldConf) ->
InitedRules = [init_rule(Rule) || Rule <- check_rules(Rules)],
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [lists:append(InitedRules, lookup())]}, -1),
InitedRules = [init_rule(R) || R <- check_rules(Rules)],
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [InitedRules ++ lookup()]}, -1),
ok = emqx_authz_cache:drain_cache();
post_config_update({tail, Rules}, _NewRules, _OldConf) ->
InitedRules = [init_rule(Rule) || Rule <- check_rules(Rules)],
emqx_hooks:put('client.authorize', {?MODULE, authorize, [lists:append(InitedRules, lookup())]}, -1),
InitedRules = [init_rule(R) || R <- check_rules(Rules)],
emqx_hooks:put('client.authorize', {?MODULE, authorize, [lookup() ++ InitedRules]}, -1),
ok = emqx_authz_cache:drain_cache();
post_config_update({{replace_once, Id}, Rule}, _NewRules, _OldConf) when is_map(Rule) ->
OldInitedRules = lookup(),
{Index, OldRule} = case find_rule_by_id(Id, OldInitedRules) of
{error, Reason} -> error(Reason);
R -> R
end,
case maps:get(type, OldRule, undefined) of
undefined -> ok;
_ ->
#{annotations := #{id := Id}} = OldRule,
ok = emqx_resource:remove(Id)
end,
{OldRules1, OldRules2 } = lists:split(Index, OldInitedRules),
InitedRules = [init_rule(R#{annotations => #{id => Id}}) || R <- check_rules([Rule])],
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [lists:droplast(OldRules1) ++ InitedRules ++ OldRules2]}, -1),
ok = emqx_authz_cache:drain_cache();
post_config_update(_, NewRules, _OldConf) ->
%% overwrite the entire config!
OldInitedRules = lookup(),
InitedRules = [init_rule(Rule) || Rule <- NewRules],
ok = emqx_hooks:put('client.authorize', {?MODULE, authorize, [InitedRules]}, -1),
lists:foreach(fun (#{type := _Type, enable := true, metadata := #{id := Id}}) ->
lists:foreach(fun (#{type := _Type, enable := true, annotations := #{id := Id}}) ->
ok = emqx_resource:remove(Id);
(_) -> ok
end, OldInitedRules),
@ -91,6 +127,14 @@ check_rules(RawRules) ->
#{authorization := #{rules := Rules}} = hocon_schema:richmap_to_map(CheckConf),
Rules.
find_rule_by_id(Id, Rules) -> find_rule_by_id(Id, Rules, 1).
find_rule_by_id(_RuleId, [], _N) -> {error, not_found_rule};
find_rule_by_id(RuleId, [ Rule = #{annotations := #{id := Id}} | Tail], N) ->
case RuleId =:= Id of
true -> {N, Rule};
false -> find_rule_by_id(RuleId, Tail, N + 1)
end.
find_action_in_hooks() ->
Callbacks = emqx_hooks:lookup('client.authorize'),
[Action] = [Action || {callback,{?MODULE, authorize, _} = Action, _, _} <- Callbacks ],
@ -99,6 +143,19 @@ find_action_in_hooks() ->
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,
annotations := #{id := ResourceID}}) ->
case emqx_resource:update(
ResourceID,
list_to_existing_atom(io_lib:format("~s_~s",[emqx_connector, DB])),
Config,
[])
of
{ok, _} -> ResourceID;
{error, already_created} -> ResourceID;
{error, Reason} -> {error, Reason}
end;
create_resource(#{type := DB,
config := Config}) ->
ResourceID = gen_id(DB),
@ -116,13 +173,19 @@ create_resource(#{type := DB,
init_rule(#{topics := Topics,
action := Action,
permission := Permission,
principal := Principal
} = Rule) when ?ALLOW_DENY(Permission), ?PUBSUB(Action), is_list(Topics) ->
principal := Principal,
annotations := #{id := Id}
} = Rule) when ?ALLOW_DENY(Permission), ?PUBSUB(Action), is_list(Topics) ->
Rule#{annotations =>
#{id => gen_id(simple),
#{id => Id,
principal => compile_principal(Principal),
topics => [compile_topic(Topic) || Topic <- Topics]}
};
init_rule(#{topics := Topics,
action := Action,
permission := Permission
} = Rule) when ?ALLOW_DENY(Permission), ?PUBSUB(Action), is_list(Topics) ->
init_rule(Rule#{annotations =>#{id => gen_id(simple)}});
init_rule(#{principal := Principal,
enable := true,

View File

@ -20,13 +20,17 @@
-include("emqx_authz.hrl").
-define(EXAMPLE_RETURNED_RULE1,
#{principal => <<"all">>,
permission => <<"allow">>,
action => <<"all">>,
topics => [<<"#">>],
annotations => #{id => 1}
}).
-define(EXAMPLE_RETURNED_RULES,
#{rules => [ #{principal => <<"all">>,
permission => <<"allow">>,
action => <<"all">>,
topics => [<<"#">>],
metadata => #{id => 1}
}
#{rules => [?EXAMPLE_RETURNED_RULE1
]
}).
@ -37,10 +41,12 @@
-export([ api_spec/0
, authorization/2
, authorization_once/2
]).
api_spec() ->
{[ authorization_api()
{[ authorization_api(),
authorization_api2()
], definitions()}.
definitions() -> emqx_authz_api_schema:definitions().
@ -99,13 +105,79 @@ authorization_api() ->
},
{"/authorization", Metadata, authorization}.
authorization_api2() ->
Metadata = #{
get => #{
description => "List authorization rules",
parameters => [
#{
name => id,
in => path,
schema => #{
type => string
},
required => true
}
],
responses => #{
<<"200">> => #{
description => <<"OK">>,
content => #{
'application/json' => #{
schema => minirest:ref(<<"returned_rules">>),
examples => #{
rules => #{
summary => <<"Rules">>,
value => jsx:encode(?EXAMPLE_RETURNED_RULE1)
}
}
}
}
},
<<"404">> => #{description => <<"Not Found">>}
}
},
put => #{
description => "Update rule",
parameters => [
#{
name => id,
in => path,
schema => #{
type => string
},
required => true
}
],
requestBody => #{
content => #{
'application/json' => #{
schema => minirest:ref(<<"rules">>),
examples => #{
simple_rule => #{
summary => <<"Rules">>,
value => jsx:encode(?EXAMPLE_RULE1)
}
}
}
}
},
responses => #{
<<"201">> => #{description => <<"Created">>},
<<"400">> => #{description => <<"Bad Request">>}
}
}
},
{"/authorization/:id", Metadata, authorization_once}.
authorization(get, _Request) ->
Rules = lists:foldl(fun (#{type := _Type, enable := true, metadata := #{id := Id} = MataData} = Rule, AccIn) ->
Rules = lists:foldl(fun (#{type := _Type, enable := true, annotations := #{id := Id} = Annotations} = Rule, AccIn) ->
NRule = case emqx_resource:health_check(Id) of
ok ->
Rule#{metadata => MataData#{status => healthy}};
Rule#{annotations => Annotations#{status => healthy}};
_ ->
Rule#{metadata => MataData#{status => unhealthy}}
Rule#{annotations => Annotations#{status => unhealthy}}
end,
lists:append(AccIn, [NRule]);
(Rule, AccIn) ->
@ -120,4 +192,29 @@ authorization(post, Request) ->
{error, Reason} -> {400, #{messgae => atom_to_binary(Reason)}}
end.
authorization_once(get, Request) ->
Id = cowboy_req:binding(id, Request),
case emqx_authz:lookup(Id) of
{error, Reason} -> {404, #{messgae => atom_to_binary(Reason)}};
Rule ->
case maps:get(type, Rule, undefined) of
undefined -> {200, Rule};
_ ->
case emqx_resource:health_check(Id) of
ok ->
{200, Rule#{annotations => #{status => healthy}}};
_ ->
{200, Rule#{annotations => #{status => unhealthy}}}
end
end
end;
authorization_once(put, Request) ->
RuleId = cowboy_req:binding(id, Request),
{ok, Body, _} = cowboy_req:read_body(Request),
RawConfig = jsx:decode(Body, [return_maps]),
case emqx_authz:update({replace_once, RuleId}, RawConfig) of
ok -> {200};
{error, Reason} -> {400, #{messgae => atom_to_binary(Reason)}}
end.

View File

@ -22,6 +22,8 @@
-include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl").
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
all() ->
emqx_ct:all(?MODULE).
@ -29,82 +31,104 @@ groups() ->
[].
init_per_suite(Config) ->
ok = emqx_config:init_load(emqx_authz_schema, ?CONF_DEFAULT),
ok = emqx_ct_helpers:start_apps([emqx_authz]),
ok = emqx_config:update([zones, default, authorization, cache, enable], false),
ok = emqx_config:update([zones, default, authorization, enable], true),
emqx_authz:update(replace, []),
Config.
end_per_suite(_Config) ->
emqx_ct_helpers:stop_apps([emqx_authz]).
ok = emqx_authz:update(replace, []),
emqx_ct_helpers:stop_apps([emqx_authz]),
ok.
-define(RULE1, #{principal => all,
topics => [<<"#">>],
action => all,
permission => deny}
-define(RULE1, #{<<"principal">> => <<"all">>,
<<"topics">> => [<<"#">>],
<<"action">> => <<"all">>,
<<"permission">> => <<"deny">>}
).
-define(RULE2, #{principal =>
#{ipaddress => <<"127.0.0.1">>},
topics =>
[#{eq => <<"#">>},
#{eq => <<"+">>}
-define(RULE2, #{<<"principal">> =>
#{<<"ipaddress">> => <<"127.0.0.1">>},
<<"topics">> =>
[#{<<"eq">> => <<"#">>},
#{<<"eq">> => <<"+">>}
] ,
action => all,
permission => allow}
<<"action">> => <<"all">>,
<<"permission">> => <<"allow">>}
).
-define(RULE3,#{principal =>
#{'and' => [#{username => "^test?"},
#{clientid => "^test?"}
-define(RULE3,#{<<"principal">> =>
#{<<"and">> => [#{<<"username">> => <<"^test?">>},
#{<<"clientid">> => <<"^test?">>}
]},
topics => [<<"test">>],
action => publish,
permission => allow}
<<"topics">> => [<<"test">>],
<<"action">> => <<"publish">>,
<<"permission">> => <<"allow">>}
).
-define(RULE4,#{principal =>
#{'or' => [#{username => <<"^test">>},
#{clientid => <<"test?">>}
]},
topics => [<<"%u">>,<<"%c">>],
action => publish,
permission => deny}
-define(RULE4,#{<<"principal">> =>
#{<<"or">> => [#{<<"username">> => <<"^test">>},
#{<<"clientid">> => <<"test?">>}
]},
<<"topics">> => [<<"%u">>,<<"%c">>],
<<"action">> => <<"publish">>,
<<"permission">> => <<"deny">>}
).
%%------------------------------------------------------------------------------
%% Testcases
%%------------------------------------------------------------------------------
t_init_rule(_) ->
?assertMatch(#{annotations := #{id := _ID,
principal := all,
topics := [['#']]}
}, emqx_authz:init_rule(?RULE1)),
?assertMatch(#{annotations := #{principal :=
#{ipaddress := {{127,0,0,1},{127,0,0,1},32}},
topics := [#{eq := ['#']},
#{eq := ['+']}],
id := _ID}
}, emqx_authz:init_rule(?RULE2)),
?assertMatch(#{annotations :=
#{principal :=
t_update_rule(_) ->
ok = emqx_authz:update(replace, [?RULE2]),
ok = emqx_authz:update(head, [?RULE1]),
ok = emqx_authz:update(tail, [?RULE3]),
Lists1 = emqx_authz:check_rules([?RULE1, ?RULE2, ?RULE3]),
?assertMatch(Lists1, emqx_config:get([authorization, rules], [])),
[#{annotations := #{id := Id1,
principal := all,
topics := [['#']]}
},
#{annotations := #{id := Id2,
principal := #{ipaddress := {{127,0,0,1},{127,0,0,1},32}},
topics := [#{eq := ['#']}, #{eq := ['+']}]}
},
#{annotations := #{id := Id3,
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.
topics := [[<<"test">>]]}
}
] = emqx_authz:lookup(),
ok = emqx_authz:update({replace_once, Id3}, ?RULE4),
Lists2 = emqx_authz:check_rules([?RULE1, ?RULE2, ?RULE4]),
?assertMatch(Lists2, emqx_config:get([authorization, rules], [])),
[#{annotations := #{id := Id1,
principal := all,
topics := [['#']]}
},
#{annotations := #{id := Id2,
principal := #{ipaddress := {{127,0,0,1},{127,0,0,1},32}},
topics := [#{eq := ['#']},
#{eq := ['+']}]}
},
#{annotations := #{id := Id3,
principal :=
#{'or' := [#{username := {re_pattern, _, _, _, _}},
#{clientid := {re_pattern, _, _, _, _}}
]
},
topics := [#{pattern := [<<"%u">>]},
#{pattern := [<<"%c">>]}
]}
}
] = emqx_authz:lookup(),
ok = emqx_authz:update(replace, []).
t_authz(_) ->
ClientInfo1 = #{clientid => <<"test">>,
@ -132,10 +156,10 @@ t_authz(_) ->
listener => mqtt_tcp
},
Rules1 = [emqx_authz:init_rule(Rule) || Rule <- [?RULE1, ?RULE2]],
Rules2 = [emqx_authz:init_rule(Rule) || Rule <- [?RULE2, ?RULE1]],
Rules3 = [emqx_authz:init_rule(Rule) || Rule <- [?RULE3, ?RULE4]],
Rules4 = [emqx_authz:init_rule(Rule) || Rule <- [?RULE4, ?RULE1]],
Rules1 = [emqx_authz:init_rule(Rule) || Rule <- emqx_authz:check_rules([?RULE1, ?RULE2])],
Rules2 = [emqx_authz:init_rule(Rule) || Rule <- emqx_authz:check_rules([?RULE2, ?RULE1])],
Rules3 = [emqx_authz:init_rule(Rule) || Rule <- emqx_authz:check_rules([?RULE3, ?RULE4])],
Rules4 = [emqx_authz:init_rule(Rule) || Rule <- emqx_authz:check_rules([?RULE4, ?RULE1])],
?assertEqual({stop, deny},
emqx_authz:authorize(ClientInfo1, subscribe, <<"#">>, deny, [])),

View File

@ -18,33 +18,26 @@
-compile(nowarn_export_all).
-compile(export_all).
% -include("emqx_authz.hrl").
% -include_lib("eunit/include/eunit.hrl").
% -include_lib("common_test/include/ct.hrl").
-include("emqx_authz.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("common_test/include/ct.hrl").
% -import(emqx_ct_http, [ request_api/3
% , request_api/5
% , get_http_data/1
% , create_default_app/0
% , delete_default_app/0
% , default_auth_header/0
% ]).
-import(emqx_ct_http, [ request_api/3
, request_api/5
, get_http_data/1
, create_default_app/0
, delete_default_app/0
, default_auth_header/0
]).
% -define(HOST, "http://127.0.0.1:8081/").
% -define(API_VERSION, "v4").
% -define(BASE_PATH, "api").
-define(HOST, "http://127.0.0.1:8081/").
-define(API_VERSION, "v5").
-define(BASE_PATH, "api/authorization").
-define(CONF_DEFAULT, <<"""
authorization:{
rules: [
]
}
""">>).
-define(CONF_DEFAULT, <<"authorization: {rules: []}">>).
all() ->
%% TODO: V5 API
%% emqx_ct:all(?MODULE).
[t_api_unit_test].
emqx_ct:all(?MODULE).
groups() ->
[].
@ -52,12 +45,15 @@ groups() ->
init_per_suite(Config) ->
ok = emqx_config:init_load(emqx_authz_schema, ?CONF_DEFAULT),
ok = emqx_ct_helpers:start_apps([emqx_authz]),
ok = emqx_config:update([zones, default, authorization, cache, enable], false),
ok = emqx_config:update([zones, default, authorization, enable], true),
%create_default_app(),
create_default_app(),
Config.
end_per_suite(_Config) ->
ok = emqx_authz:update(replace, []),
delete_default_app(),
emqx_ct_helpers:stop_apps([emqx_authz]),
ok.
@ -77,29 +73,12 @@ end_per_suite(_Config) ->
% set_special_configs(_App) ->
% ok.
% %%------------------------------------------------------------------------------
% %% Testcases
% %%------------------------------------------------------------------------------
%%------------------------------------------------------------------------------
%% Testcases
%%------------------------------------------------------------------------------
t_api_unit_test(_Config) ->
%% TODO: Decode from JSON or HOCON, instead of hand-crafting decode result
Rule1 = #{<<"principal">> =>
#{<<"and">> => [#{<<"username">> => <<"^test?">>},
#{<<"clientid">> => <<"^test?">>}
]},
<<"action">> => <<"subscribe">>,
<<"topics">> => [<<"%u">>],
<<"permission">> => <<"allow">>
},
ok = emqx_authz_api:push_authz(#{}, Rule1),
[#{action := subscribe,
permission := allow,
principal :=
#{'and' := [#{username := <<"^test?">>},
#{clientid := <<"^test?">>}]},
topics := [<<"%u">>]}] = emqx_config:get([authorization, rules]).
% t_api(_Config) ->
% t_api_unit_test(_Config) ->
% %% TODO: Decode from JSON or HOCON, instead of hand-crafting decode result
% Rule1 = #{<<"principal">> =>
% #{<<"and">> => [#{<<"username">> => <<"^test?">>},
% #{<<"clientid">> => <<"^test?">>}
@ -108,53 +87,89 @@ t_api_unit_test(_Config) ->
% <<"topics">> => [<<"%u">>],
% <<"permission">> => <<"allow">>
% },
% {ok, _} = request_http_rest_add(["authz/push"], #{rules => [Rule1]}),
% {ok, Result1} = request_http_rest_lookup(["authz"]),
% ?assertMatch([Rule1 | _ ], get_http_data(Result1)),
% ok = emqx_authz_api:push_authz(#{}, Rule1),
% [#{action := subscribe,
% permission := allow,
% principal :=
% #{'and' := [#{username := <<"^test?">>},
% #{clientid := <<"^test?">>}]},
% topics := [<<"%u">>]}] = emqx_config:get([authorization, rules]).
% Rule2 = #{<<"principal">> => #{<<"ipaddress">> => <<"127.0.0.1">>},
% <<"action">> => <<"publish">>,
% <<"topics">> => [#{<<"eq">> => <<"#">>},
% #{<<"eq">> => <<"+">>}
% ],
% <<"permission">> => <<"deny">>
% },
% {ok, _} = request_http_rest_add(["authz/append"], #{rules => [Rule2]}),
% {ok, Result2} = request_http_rest_lookup(["authz"]),
% ?assertEqual(Rule2#{<<"principal">> => #{<<"ipaddress">> => "127.0.0.1"}},
% lists:last(get_http_data(Result2))),
t_post(_) ->
Rules1 = request(get, uri(), []),
ct:print("============~p~n",[Rules1]),
ok.
% {ok, _} = request_http_rest_update(["authz"], #{rules => []}),
% {ok, Result3} = request_http_rest_lookup(["authz"]),
% ?assertEqual([], get_http_data(Result3)),
% ok.
t_api(_Config) ->
Rule1 = #{<<"principal">> =>
#{<<"and">> => [#{<<"username">> => <<"^test?">>},
#{<<"clientid">> => <<"^test?">>}
]},
<<"action">> => <<"subscribe">>,
<<"topics">> => [<<"%u">>],
<<"permission">> => <<"allow">>
},
{ok, _} = request_http_rest_add(["authz/push"], #{rules => [Rule1]}),
{ok, Result1} = request_http_rest_lookup(["authz"]),
?assertMatch([Rule1 | _ ], get_http_data(Result1)),
% %%--------------------------------------------------------------------
% %% HTTP Request
% %%--------------------------------------------------------------------
Rule2 = #{<<"principal">> => #{<<"ipaddress">> => <<"127.0.0.1">>},
<<"action">> => <<"publish">>,
<<"topics">> => [#{<<"eq">> => <<"#">>},
#{<<"eq">> => <<"+">>}
],
<<"permission">> => <<"deny">>
},
{ok, _} = request_http_rest_add(["authz/append"], #{rules => [Rule2]}),
{ok, Result2} = request_http_rest_lookup(["authz"]),
?assertEqual(Rule2#{<<"principal">> => #{<<"ipaddress">> => "127.0.0.1"}},
lists:last(get_http_data(Result2))),
% request_http_rest_list(Path) ->
% request_api(get, uri(Path), default_auth_header()).
{ok, _} = request_http_rest_update(["authz"], #{rules => []}),
{ok, Result3} = request_http_rest_lookup(["authz"]),
?assertEqual([], get_http_data(Result3)),
ok.
% request_http_rest_lookup(Path) ->
% request_api(get, uri([Path]), default_auth_header()).
%%--------------------------------------------------------------------
%% HTTP Request
%%--------------------------------------------------------------------
% request_http_rest_add(Path, Params) ->
% request_api(post, uri(Path), [], default_auth_header(), Params).
request(Method, Url, Body) ->
Request = case Body of
[] -> {Url, [{"username", "admin"}, {"password", "public"}]};
_ -> {Url, [{"username", "admin"}, {"password", "public"}], "application/json", Body}
end,
case httpc:request(Method, Request, [], [{body_format, binary}]) of
{error, socket_closed_remotely} ->
{error, socket_closed_remotely};
{ok, {{"HTTP/1.1", Code, _}, _Headers, Return} } ->
{ok, Code, Return};
{ok, {Reason, _, _}} ->
{error, Reason}
end.
% request_http_rest_update(Path, Params) ->
% request_api(put, uri([Path]), [], default_auth_header(), Params).
request_http_rest_list(Path) ->
request_api(get, uri(Path), default_auth_header()).
% request_http_rest_delete(Login) ->
% request_api(delete, uri([Login]), default_auth_header()).
request_http_rest_lookup(Path) ->
request_api(get, uri([Path]), default_auth_header()).
% uri() -> uri([]).
% uri(Parts) when is_list(Parts) ->
% NParts = [b2l(E) || E <- Parts],
% ?HOST ++ filename:join([?BASE_PATH, ?API_VERSION | NParts]).
request_http_rest_add(Path, Params) ->
request_api(post, uri(Path), [], default_auth_header(), Params).
% %% @private
% b2l(B) when is_binary(B) ->
% binary_to_list(B);
% b2l(L) when is_list(L) ->
% L.
request_http_rest_update(Path, Params) ->
request_api(put, uri([Path]), [], default_auth_header(), Params).
request_http_rest_delete(Login) ->
request_api(delete, uri([Login]), default_auth_header()).
uri() -> uri([]).
uri(Parts) when is_list(Parts) ->
NParts = [b2l(E) || E <- Parts],
?HOST ++ filename:join([?BASE_PATH, ?API_VERSION | NParts]).
%% @private
b2l(B) when is_binary(B) ->
binary_to_list(B);
b2l(L) when is_list(L) ->
L.

View File

@ -31,6 +31,7 @@ groups() ->
init_per_suite(Config) ->
meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]),
meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end),
meck:expect(emqx_resource, remove, fun(_) -> ok end ),
ok = emqx_ct_helpers:start_apps([emqx_authz]),
ok = emqx_config:update([zones, default, authorization, cache, enable], false),

View File

@ -31,6 +31,7 @@ groups() ->
init_per_suite(Config) ->
meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]),
meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end ),
meck:expect(emqx_resource, remove, fun(_) -> ok end ),
ok = emqx_ct_helpers:start_apps([emqx_authz]),

View File

@ -31,6 +31,7 @@ groups() ->
init_per_suite(Config) ->
meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]),
meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end ),
meck:expect(emqx_resource, remove, fun(_) -> ok end ),
ok = emqx_ct_helpers:start_apps([emqx_authz]),

View File

@ -31,6 +31,7 @@ groups() ->
init_per_suite(Config) ->
meck:new(emqx_resource, [non_strict, passthrough, no_history, no_link]),
meck:expect(emqx_resource, create, fun(_, _, _) -> {ok, meck_data} end ),
meck:expect(emqx_resource, remove, fun(_) -> ok end ),
ok = emqx_ct_helpers:start_apps([emqx_authz]),