feat(authz api): support '/authorization/settings' api and update swagger schema
Signed-off-by: zhanghongtong <rory-z@outlook.com>
This commit is contained in:
parent
cfe4e37d50
commit
ef1b617624
|
@ -19,17 +19,17 @@
|
||||||
-export([definitions/0]).
|
-export([definitions/0]).
|
||||||
|
|
||||||
definitions() ->
|
definitions() ->
|
||||||
RetruenedRules = #{
|
RetruenedSources = #{
|
||||||
allOf => [ #{type => object,
|
allOf => [ #{type => object,
|
||||||
properties => #{
|
properties => #{
|
||||||
annotations => #{
|
annotations => #{
|
||||||
type => object,
|
type => object,
|
||||||
required => [id],
|
required => [status],
|
||||||
properties => #{
|
properties => #{
|
||||||
id => #{
|
status => #{
|
||||||
type => string
|
type => string,
|
||||||
},
|
example => <<"healthy">>
|
||||||
principal => minirest:ref(<<"principal">>)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,119 +37,76 @@ definitions() ->
|
||||||
, minirest:ref(<<"sources">>)
|
, minirest:ref(<<"sources">>)
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
Rules = #{
|
Sources = #{
|
||||||
oneOf => [ minirest:ref(<<"simple_source">>)
|
oneOf => [ minirest:ref(<<"connector_redis">>)
|
||||||
% , minirest:ref(<<"connector_redis">>)
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
% ConnectorRedis = #{
|
ConnectorRedis= #{
|
||||||
% type => object,
|
|
||||||
% required => [principal, type, enable, config, cmd]
|
|
||||||
% properties => #{
|
|
||||||
% principal => minirest:ref(<<"principal">>),
|
|
||||||
% type => #{
|
|
||||||
% type => string,
|
|
||||||
% enum => [<<"redis">>],
|
|
||||||
% example => <<"redis">>
|
|
||||||
% },
|
|
||||||
% enable => #{
|
|
||||||
% type => boolean,
|
|
||||||
% example => true
|
|
||||||
% }
|
|
||||||
% config => #{
|
|
||||||
% type =>
|
|
||||||
% }
|
|
||||||
% }
|
|
||||||
% }
|
|
||||||
SimpleRule = #{
|
|
||||||
type => object,
|
type => object,
|
||||||
required => [principal, permission, action, topics],
|
required => [type, enable, config, cmd],
|
||||||
properties => #{
|
properties => #{
|
||||||
action => #{
|
type => #{
|
||||||
type => string,
|
type => string,
|
||||||
enum => [<<"publish">>, <<"subscribe">>, <<"all">>],
|
enum => [<<"redis">>],
|
||||||
example => <<"publish">>
|
example => <<"redis">>
|
||||||
},
|
},
|
||||||
permission => #{
|
enable => #{
|
||||||
|
type => boolean,
|
||||||
|
example => true
|
||||||
|
},
|
||||||
|
config => #{
|
||||||
|
oneOf => [ #{type => object,
|
||||||
|
required => [server, redis_type, pool_size, auto_reconnect],
|
||||||
|
properties => #{
|
||||||
|
server => #{type => string, example => <<"127.0.0.1:3306">>},
|
||||||
|
redis_type => #{type => string,
|
||||||
|
enum => [<<"single">>],
|
||||||
|
example => <<"single">>},
|
||||||
|
pool_size => #{type => integer},
|
||||||
|
auto_reconnect => #{type => boolean, example => true},
|
||||||
|
password => #{type => string},
|
||||||
|
database => #{type => string, example => mqtt}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, #{type => object,
|
||||||
|
required => [servers, redis_type, sentinel, pool_size, auto_reconnect],
|
||||||
|
properties => #{
|
||||||
|
servers => #{type => array,
|
||||||
|
items => #{type => string,example => <<"127.0.0.1:3306">>}},
|
||||||
|
redis_type => #{type => string,
|
||||||
|
enum => [<<"sentinel">>],
|
||||||
|
example => <<"sentinel">>},
|
||||||
|
sentinel => #{type => string},
|
||||||
|
pool_size => #{type => integer},
|
||||||
|
auto_reconnect => #{type => boolean, example => true},
|
||||||
|
password => #{type => string},
|
||||||
|
database => #{type => string, example => mqtt}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, #{type => object,
|
||||||
|
required => [servers, redis_type, pool_size, auto_reconnect],
|
||||||
|
properties => #{
|
||||||
|
servers => #{type => array,
|
||||||
|
items => #{type => string, example => <<"127.0.0.1:3306">>}},
|
||||||
|
redis_type => #{type => string,
|
||||||
|
enum => [<<"cluster">>],
|
||||||
|
example => <<"cluster">>},
|
||||||
|
pool_size => #{type => integer},
|
||||||
|
auto_reconnect => #{type => boolean, example => true},
|
||||||
|
password => #{type => string},
|
||||||
|
database => #{type => string, example => mqtt}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
type => object
|
||||||
|
},
|
||||||
|
cmd => #{
|
||||||
type => string,
|
type => string,
|
||||||
enum => [<<"allow">>, <<"deny">>],
|
example => <<"HGETALL mqtt_authz">>
|
||||||
example => <<"allow">>
|
|
||||||
},
|
|
||||||
topics => #{
|
|
||||||
type => array,
|
|
||||||
items => #{
|
|
||||||
oneOf => [ #{type => string, example => <<"#">>}
|
|
||||||
, #{type => object,
|
|
||||||
required => [eq],
|
|
||||||
properties => #{
|
|
||||||
eq => #{type => string}
|
|
||||||
},
|
|
||||||
example => #{eq => <<"#">>}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
principal => minirest:ref(<<"principal">>)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Principal = #{
|
|
||||||
oneOf => [ minirest:ref(<<"principal_username">>)
|
|
||||||
, minirest:ref(<<"principal_clientid">>)
|
|
||||||
, minirest:ref(<<"principal_ipaddress">>)
|
|
||||||
, #{type => string, enum=>[<<"all">>], example => <<"all">>}
|
|
||||||
, #{type => object,
|
|
||||||
required => ['and'],
|
|
||||||
properties => #{'and' => #{type => array,
|
|
||||||
items => #{oneOf => [ minirest:ref(<<"principal_username">>)
|
|
||||||
, minirest:ref(<<"principal_clientid">>)
|
|
||||||
, minirest:ref(<<"principal_ipaddress">>)
|
|
||||||
]}}},
|
|
||||||
example => #{'and' => [#{username => <<"emqx">>}, #{clientid => <<"emqx">>}]}
|
|
||||||
}
|
|
||||||
, #{type => object,
|
|
||||||
required => ['or'],
|
|
||||||
properties => #{'and' => #{type => array,
|
|
||||||
items => #{oneOf => [ minirest:ref(<<"principal_username">>)
|
|
||||||
, minirest:ref(<<"principal_clientid">>)
|
|
||||||
, minirest:ref(<<"principal_ipaddress">>)
|
|
||||||
]}}},
|
|
||||||
example => #{'or' => [#{username => <<"emqx">>}, #{clientid => <<"emqx">>}]}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
PrincipalUsername = #{type => object,
|
|
||||||
required => [username],
|
|
||||||
properties => #{username => #{type => string}},
|
|
||||||
example => #{username => <<"emqx">>}
|
|
||||||
},
|
|
||||||
PrincipalClientid = #{type => object,
|
|
||||||
required => [clientid],
|
|
||||||
properties => #{clientid => #{type => string}},
|
|
||||||
example => #{clientid => <<"emqx">>}
|
|
||||||
},
|
|
||||||
PrincipalIpaddress = #{type => object,
|
|
||||||
required => [ipaddress],
|
|
||||||
properties => #{ipaddress => #{type => string}},
|
|
||||||
example => #{ipaddress => <<"127.0.0.1">>}
|
|
||||||
},
|
|
||||||
ErrorDef = #{
|
|
||||||
type => object,
|
|
||||||
properties => #{
|
|
||||||
code => #{
|
|
||||||
type => string,
|
|
||||||
example => <<"BAD_REQUEST">>
|
|
||||||
},
|
|
||||||
message => #{
|
|
||||||
type => string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[ #{<<"returned_sources">> => RetruenedRules}
|
[ #{<<"returned_sources">> => RetruenedSources}
|
||||||
, #{<<"sources">> => Rules}
|
, #{<<"sources">> => Sources}
|
||||||
, #{<<"simple_source">> => SimpleRule}
|
, #{<<"connector_redis">> => ConnectorRedis}
|
||||||
, #{<<"principal">> => Principal}
|
|
||||||
, #{<<"principal_username">> => PrincipalUsername}
|
|
||||||
, #{<<"principal_clientid">> => PrincipalClientid}
|
|
||||||
, #{<<"principal_ipaddress">> => PrincipalIpaddress}
|
|
||||||
, #{<<"error">> => ErrorDef}
|
|
||||||
].
|
].
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_authz_api_settings).
|
||||||
|
|
||||||
|
-behavior(minirest_api).
|
||||||
|
|
||||||
|
-export([ api_spec/0
|
||||||
|
, settings/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
api_spec() ->
|
||||||
|
{[settings_api()], []}.
|
||||||
|
|
||||||
|
authorization_settings() ->
|
||||||
|
maps:remove(<<"sources">>, emqx:get_raw_config([authorization], #{})).
|
||||||
|
|
||||||
|
conf_schema() ->
|
||||||
|
emqx_mgmt_api_configs:gen_schema(authorization_settings()).
|
||||||
|
|
||||||
|
settings_api() ->
|
||||||
|
Metadata = #{
|
||||||
|
get => #{
|
||||||
|
description => "Get authorization settings",
|
||||||
|
responses => #{<<"200">> => emqx_mgmt_util:schema(conf_schema())}
|
||||||
|
},
|
||||||
|
put => #{
|
||||||
|
description => "Update authorization settings",
|
||||||
|
requestBody => emqx_mgmt_util:schema(conf_schema()),
|
||||||
|
responses => #{
|
||||||
|
<<"200">> => emqx_mgmt_util:schema(conf_schema()),
|
||||||
|
<<"400">> => emqx_mgmt_util:bad_request()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{"/authorization/settings", Metadata, settings}.
|
||||||
|
|
||||||
|
settings(get, _Params) ->
|
||||||
|
{200, authorization_settings()};
|
||||||
|
|
||||||
|
settings(put, #{body := #{<<"no_match">> := NoMatch,
|
||||||
|
<<"deny_action">> := DenyAction,
|
||||||
|
<<"cache">> := Cache}}) ->
|
||||||
|
{ok, _} = emqx:update_config([authorization, no_match], NoMatch),
|
||||||
|
{ok, _} = emqx:update_config([authorization, deny_action], DenyAction),
|
||||||
|
{ok, _} = emqx:update_config([authorization, cache], Cache),
|
||||||
|
ok = emqx_authz_cache:drain_cache(),
|
||||||
|
{200, authorization_settings()}.
|
|
@ -14,31 +14,29 @@
|
||||||
%% limitations under the License.
|
%% limitations under the License.
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
-module(emqx_authz_api).
|
-module(emqx_authz_api_sources).
|
||||||
|
|
||||||
-behavior(minirest_api).
|
-behavior(minirest_api).
|
||||||
|
|
||||||
-include("emqx_authz.hrl").
|
-include("emqx_authz.hrl").
|
||||||
|
|
||||||
-define(EXAMPLE_RETURNED_RULE1,
|
-define(EXAMPLE_REDIS,
|
||||||
#{principal => <<"all">>,
|
#{type=> redis,
|
||||||
permission => <<"allow">>,
|
config => #{server => <<"127.0.0.1:3306">>,
|
||||||
action => <<"all">>,
|
redis_type => single,
|
||||||
topics => [<<"#">>],
|
pool_size => 1,
|
||||||
annotations => #{id => 1}
|
auto_reconnect => true
|
||||||
}).
|
},
|
||||||
|
cmd => <<"HGETALL mqtt_authz">>}).
|
||||||
|
-define(EXAMPLE_RETURNED_REDIS,
|
||||||
|
maps:put(annotations, #{status => healthy}, ?EXAMPLE_REDIS)
|
||||||
|
).
|
||||||
|
|
||||||
-define(EXAMPLE_RETURNED_RULES,
|
-define(EXAMPLE_RETURNED_RULES,
|
||||||
#{sources => [?EXAMPLE_RETURNED_RULE1
|
#{sources => [?EXAMPLE_RETURNED_REDIS
|
||||||
]
|
]
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-define(EXAMPLE_RULE1, #{principal => <<"all">>,
|
|
||||||
permission => <<"allow">>,
|
|
||||||
action => <<"all">>,
|
|
||||||
topics => [<<"#">>]}).
|
|
||||||
|
|
||||||
-export([ api_spec/0
|
-export([ api_spec/0
|
||||||
, sources/2
|
, sources/2
|
||||||
, source/2
|
, source/2
|
||||||
|
@ -107,9 +105,9 @@ sources_api() ->
|
||||||
'application/json' => #{
|
'application/json' => #{
|
||||||
schema => minirest:ref(<<"sources">>),
|
schema => minirest:ref(<<"sources">>),
|
||||||
examples => #{
|
examples => #{
|
||||||
simple_source => #{
|
redis => #{
|
||||||
summary => <<"Sources">>,
|
summary => <<"Redis">>,
|
||||||
value => jsx:encode(?EXAMPLE_RULE1)
|
value => jsx:encode(?EXAMPLE_REDIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,23 +115,7 @@ sources_api() ->
|
||||||
},
|
},
|
||||||
responses => #{
|
responses => #{
|
||||||
<<"204">> => #{description => <<"Created">>},
|
<<"204">> => #{description => <<"Created">>},
|
||||||
<<"400">> => #{
|
<<"400">> => emqx_mgmt_util:bad_request()
|
||||||
description => <<"Bad Request">>,
|
|
||||||
content => #{
|
|
||||||
'application/json' => #{
|
|
||||||
schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Bad Request">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"BAD_REQUEST">>,
|
|
||||||
message => <<"Bad Request">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
put => #{
|
put => #{
|
||||||
|
@ -146,9 +128,9 @@ sources_api() ->
|
||||||
items => minirest:ref(<<"returned_sources">>)
|
items => minirest:ref(<<"returned_sources">>)
|
||||||
},
|
},
|
||||||
examples => #{
|
examples => #{
|
||||||
sources => #{
|
redis => #{
|
||||||
summary => <<"Sources">>,
|
summary => <<"Redis">>,
|
||||||
value => jsx:encode([?EXAMPLE_RULE1])
|
value => jsx:encode([?EXAMPLE_REDIS])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,23 +138,7 @@ sources_api() ->
|
||||||
},
|
},
|
||||||
responses => #{
|
responses => #{
|
||||||
<<"204">> => #{description => <<"Created">>},
|
<<"204">> => #{description => <<"Created">>},
|
||||||
<<"400">> => #{
|
<<"400">> => emqx_mgmt_util:bad_request()
|
||||||
description => <<"Bad Request">>,
|
|
||||||
content => #{
|
|
||||||
'application/json' => #{
|
|
||||||
schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Bad Request">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"BAD_REQUEST">>,
|
|
||||||
message => <<"Bad Request">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -201,29 +167,13 @@ source_api() ->
|
||||||
examples => #{
|
examples => #{
|
||||||
sources => #{
|
sources => #{
|
||||||
summary => <<"Sources">>,
|
summary => <<"Sources">>,
|
||||||
value => jsx:encode(?EXAMPLE_RETURNED_RULE1)
|
value => jsx:encode(?EXAMPLE_RETURNED_REDIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<<"404">> => #{
|
<<"404">> => emqx_mgmt_util:bad_request(<<"Not Found">>)
|
||||||
description => <<"Bad Request">>,
|
|
||||||
content => #{
|
|
||||||
'application/json' => #{
|
|
||||||
schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Not Found">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"NOT_FOUND">>,
|
|
||||||
message => <<"source xxx not found">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
put => #{
|
put => #{
|
||||||
|
@ -243,9 +193,9 @@ source_api() ->
|
||||||
'application/json' => #{
|
'application/json' => #{
|
||||||
schema => minirest:ref(<<"sources">>),
|
schema => minirest:ref(<<"sources">>),
|
||||||
examples => #{
|
examples => #{
|
||||||
simple_source => #{
|
redis => #{
|
||||||
summary => <<"Sources">>,
|
summary => <<"Redis">>,
|
||||||
value => jsx:encode(?EXAMPLE_RULE1)
|
value => jsx:encode(?EXAMPLE_REDIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,47 +203,15 @@ source_api() ->
|
||||||
},
|
},
|
||||||
responses => #{
|
responses => #{
|
||||||
<<"204">> => #{description => <<"No Content">>},
|
<<"204">> => #{description => <<"No Content">>},
|
||||||
<<"404">> => #{
|
<<"404">> => emqx_mgmt_util:bad_request(<<"Not Found">>),
|
||||||
description => <<"Bad Request">>,
|
<<"400">> => emqx_mgmt_util:bad_request()
|
||||||
content => #{
|
|
||||||
'application/json' => #{
|
|
||||||
schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Not Found">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"NOT_FOUND">>,
|
|
||||||
message => <<"source xxx not found">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
<<"400">> => #{
|
|
||||||
description => <<"Bad Request">>,
|
|
||||||
content => #{
|
|
||||||
'application/json' => #{
|
|
||||||
schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Bad Request">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"BAD_REQUEST">>,
|
|
||||||
message => <<"Bad Request">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
delete => #{
|
delete => #{
|
||||||
description => "Delete source",
|
description => "Delete source",
|
||||||
parameters => [
|
parameters => [
|
||||||
#{
|
#{
|
||||||
name => id,
|
name => type,
|
||||||
in => path,
|
in => path,
|
||||||
schema => #{
|
schema => #{
|
||||||
type => string
|
type => string
|
||||||
|
@ -303,23 +221,7 @@ source_api() ->
|
||||||
],
|
],
|
||||||
responses => #{
|
responses => #{
|
||||||
<<"204">> => #{description => <<"No Content">>},
|
<<"204">> => #{description => <<"No Content">>},
|
||||||
<<"400">> => #{
|
<<"400">> => emqx_mgmt_util:bad_request()
|
||||||
description => <<"Bad Request">>,
|
|
||||||
content => #{
|
|
||||||
'application/json' => #{
|
|
||||||
schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Bad Request">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"BAD_REQUEST">>,
|
|
||||||
message => <<"Bad Request">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -378,38 +280,8 @@ move_source_api() ->
|
||||||
<<"204">> => #{
|
<<"204">> => #{
|
||||||
description => <<"No Content">>
|
description => <<"No Content">>
|
||||||
},
|
},
|
||||||
<<"404">> => #{
|
<<"404">> => emqx_mgmt_util:bad_request(<<"Not Found">>),
|
||||||
description => <<"Bad Request">>,
|
<<"400">> => emqx_mgmt_util:bad_request()
|
||||||
content => #{ 'application/json' => #{ schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Not Found">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"NOT_FOUND">>,
|
|
||||||
message => <<"source xxx not found">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
<<"400">> => #{
|
|
||||||
description => <<"Bad Request">>,
|
|
||||||
content => #{
|
|
||||||
'application/json' => #{
|
|
||||||
schema => minirest:ref(<<"error">>),
|
|
||||||
examples => #{
|
|
||||||
example1 => #{
|
|
||||||
summary => <<"Bad Request">>,
|
|
||||||
value => #{
|
|
||||||
code => <<"BAD_REQUEST">>,
|
|
||||||
message => <<"Bad Request">>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -519,6 +391,3 @@ move_source(post, #{bindings := #{type := Type}, body := #{<<"position">> := Pos
|
||||||
{400, #{code => <<"BAD_REQUEST">>,
|
{400, #{code => <<"BAD_REQUEST">>,
|
||||||
messgae => atom_to_binary(Reason)}}
|
messgae => atom_to_binary(Reason)}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_authz_api_settings_SUITE).
|
||||||
|
|
||||||
|
-compile(nowarn_export_all).
|
||||||
|
-compile(export_all).
|
||||||
|
|
||||||
|
-include("emqx_authz.hrl").
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
|
-define(CONF_DEFAULT, <<"authorization: {sources: []}">>).
|
||||||
|
|
||||||
|
-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
|
||||||
|
, auth_header/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(HOST, "http://127.0.0.1:18083/").
|
||||||
|
-define(API_VERSION, "v5").
|
||||||
|
-define(BASE_PATH, "api").
|
||||||
|
|
||||||
|
all() ->
|
||||||
|
emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
|
groups() ->
|
||||||
|
[].
|
||||||
|
|
||||||
|
init_per_suite(Config) ->
|
||||||
|
ok = emqx_ct_helpers:start_apps([emqx_authz, emqx_dashboard], fun set_special_configs/1),
|
||||||
|
{ok, _} = emqx:update_config([authorization, cache, enable], false),
|
||||||
|
{ok, _} = emqx:update_config([authorization, no_match], deny),
|
||||||
|
|
||||||
|
Config.
|
||||||
|
|
||||||
|
end_per_suite(_Config) ->
|
||||||
|
emqx_ct_helpers:stop_apps([emqx_resource, emqx_authz, emqx_dashboard]),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
set_special_configs(emqx_dashboard) ->
|
||||||
|
Config = #{
|
||||||
|
default_username => <<"admin">>,
|
||||||
|
default_password => <<"public">>,
|
||||||
|
listeners => [#{
|
||||||
|
protocol => http,
|
||||||
|
port => 18083
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
emqx_config:put([emqx_dashboard], Config),
|
||||||
|
ok;
|
||||||
|
set_special_configs(_App) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
%% Testcases
|
||||||
|
%%------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
t_api(_) ->
|
||||||
|
Settings1 = #{<<"no_match">> => <<"deny">>,
|
||||||
|
<<"deny_action">> => <<"disconnect">>,
|
||||||
|
<<"cache">> => #{
|
||||||
|
<<"enable">> => false,
|
||||||
|
<<"max_size">> => 32,
|
||||||
|
<<"ttl">> => 60000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ok, 200, Result1} = request(put, uri(["authorization", "settings"]), Settings1),
|
||||||
|
{ok, 200, Result1} = request(get, uri(["authorization", "settings"]), []),
|
||||||
|
?assertEqual(Settings1, jsx:decode(Result1)),
|
||||||
|
|
||||||
|
Settings2 = #{<<"no_match">> => <<"allow">>,
|
||||||
|
<<"deny_action">> => <<"ignore">>,
|
||||||
|
<<"cache">> => #{
|
||||||
|
<<"enable">> => true,
|
||||||
|
<<"max_size">> => 32,
|
||||||
|
<<"ttl">> => 60000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{ok, 200, Result2} = request(put, uri(["authorization", "settings"]), Settings2),
|
||||||
|
{ok, 200, Result2} = request(get, uri(["authorization", "settings"]), []),
|
||||||
|
?assertEqual(Settings2, jsx:decode(Result2)),
|
||||||
|
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% HTTP Request
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
request(Method, Url, Body) ->
|
||||||
|
Request = case Body of
|
||||||
|
[] -> {Url, [auth_header_()]};
|
||||||
|
_ -> {Url, [auth_header_()], "application/json", jsx:encode(Body)}
|
||||||
|
end,
|
||||||
|
ct:pal("Method: ~p, Request: ~p", [Method, Request]),
|
||||||
|
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.
|
||||||
|
|
||||||
|
uri() -> uri([]).
|
||||||
|
uri(Parts) when is_list(Parts) ->
|
||||||
|
NParts = [E || E <- Parts],
|
||||||
|
?HOST ++ filename:join([?BASE_PATH, ?API_VERSION | NParts]).
|
||||||
|
|
||||||
|
get_sources(Result) ->
|
||||||
|
maps:get(<<"sources">>, jsx:decode(Result), []).
|
||||||
|
|
||||||
|
auth_header_() ->
|
||||||
|
Username = <<"admin">>,
|
||||||
|
Password = <<"public">>,
|
||||||
|
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||||
|
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
|
@ -13,7 +13,7 @@
|
||||||
%% limitations under the License.
|
%% limitations under the License.
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
-module(emqx_authz_api_SUITE).
|
-module(emqx_authz_api_sources_SUITE).
|
||||||
|
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
-compile(export_all).
|
-compile(export_all).
|
Loading…
Reference in New Issue