chore: add more test for api_key
This commit is contained in:
parent
f6a47e5cf6
commit
5d4a1933a2
|
@ -1,221 +0,0 @@
|
||||||
emqx_dashboard_schema {
|
|
||||||
listeners {
|
|
||||||
desc {
|
|
||||||
en: """HTTP(s) listeners are identified by their protocol type and are
|
|
||||||
used to serve dashboard UI and restful HTTP API.
|
|
||||||
Listeners must have a unique combination of port number and IP address.
|
|
||||||
For example, an HTTP listener can listen on all configured IP addresses
|
|
||||||
on a given port for a machine by specifying the IP address 0.0.0.0.
|
|
||||||
Alternatively, the HTTP listener can specify a unique IP address for each listener,
|
|
||||||
but use the same port."""
|
|
||||||
zh: """仪表盘监听器设置。"""
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Listeners"
|
|
||||||
zh: "监听器"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sample_interval {
|
|
||||||
desc {
|
|
||||||
en: """How often to update metrics displayed in the dashboard.
|
|
||||||
Note: `sample_interval` should be a divisor of 60."""
|
|
||||||
zh: """更新仪表板中显示的指标的时间间隔。必须小于60,且被60的整除。"""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
token_expired_time {
|
|
||||||
desc {
|
|
||||||
en: "JWT token expiration time."
|
|
||||||
zh: "JWT token 过期时间"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Token expired time"
|
|
||||||
zh: "JWT 过期时间"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
num_acceptors {
|
|
||||||
desc {
|
|
||||||
en: "Socket acceptor pool size for TCP protocols."
|
|
||||||
zh: "TCP协议的Socket acceptor池大小"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Number of acceptors"
|
|
||||||
zh: "Acceptor 数量"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
max_connections {
|
|
||||||
desc {
|
|
||||||
en: "Maximum number of simultaneous connections."
|
|
||||||
zh: "同时处理的最大连接数"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Maximum connections"
|
|
||||||
zh: "最大连接数"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
backlog {
|
|
||||||
desc {
|
|
||||||
en: "Defines the maximum length that the queue of pending connections can grow to."
|
|
||||||
zh: "排队等待连接的队列的最大长度"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Backlog"
|
|
||||||
zh: "排队长度"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
send_timeout {
|
|
||||||
desc {
|
|
||||||
en: "Send timeout for the socket."
|
|
||||||
zh: "Socket发送超时时间"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Send timeout"
|
|
||||||
zh: "发送超时时间"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inet6 {
|
|
||||||
desc {
|
|
||||||
en: "Enable IPv6 support, default is false, which means IPv4 only."
|
|
||||||
zh: "启用IPv6, 如果机器不支持IPv6,请关闭此选项,否则会导致仪表盘无法使用。"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "IPv6"
|
|
||||||
zh: "IPv6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ipv6_v6only {
|
|
||||||
desc {
|
|
||||||
en: "Disable IPv4-to-IPv6 mapping for the listener."
|
|
||||||
zh: "当开启 inet6 功能的同时禁用 IPv4-to-IPv6 映射。该配置仅在 inet6 功能开启时有效。"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "IPv6 only"
|
|
||||||
zh: "IPv6 only"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
desc_dashboard {
|
|
||||||
desc {
|
|
||||||
en: "Configuration for EMQX dashboard."
|
|
||||||
zh: "EMQX仪表板配置"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Dashboard"
|
|
||||||
zh: "仪表板"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
desc_listeners {
|
|
||||||
desc {
|
|
||||||
en: "Configuration for the dashboard listener."
|
|
||||||
zh: "仪表板监听器配置"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Listeners"
|
|
||||||
zh: "监听器"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
desc_http {
|
|
||||||
desc {
|
|
||||||
en: "Configuration for the dashboard listener (plaintext)."
|
|
||||||
zh: "仪表板监听器(HTTP)配置"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "HTTP"
|
|
||||||
zh: "HTTP"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
desc_https {
|
|
||||||
desc {
|
|
||||||
en: "Configuration for the dashboard listener (TLS)."
|
|
||||||
zh: "仪表板监听器(HTTPS)配置"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "HTTPS"
|
|
||||||
zh: "HTTPS"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listener_enable {
|
|
||||||
desc {
|
|
||||||
en: "Ignore or enable this listener"
|
|
||||||
zh: "忽略或启用该监听器配置"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Enable"
|
|
||||||
zh: "启用"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bind {
|
|
||||||
desc {
|
|
||||||
en: "Port without IP(18083) or port with specified IP(127.0.0.1:18083)."
|
|
||||||
zh: "监听的地址与端口,在dashboard更新此配置时,会重启dashboard服务。"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Bind"
|
|
||||||
zh: "绑定端口"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default_username {
|
|
||||||
desc {
|
|
||||||
en: "The default username of the automatically created dashboard user."
|
|
||||||
zh: "默认的仪表板用户名"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Default username"
|
|
||||||
zh: "默认用户名"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default_password {
|
|
||||||
desc {
|
|
||||||
en: """The initial default password for dashboard 'admin' user.
|
|
||||||
For safety, it should be changed as soon as possible."""
|
|
||||||
zh: """默认的仪表板用户密码
|
|
||||||
为了安全,应该尽快修改密码。"""
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "Default password"
|
|
||||||
zh: "默认密码"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cors {
|
|
||||||
desc {
|
|
||||||
en: """Support Cross-Origin Resource Sharing (CORS).
|
|
||||||
Allows a server to indicate any origins (domain, scheme, or port) other than
|
|
||||||
its own from which a browser should permit loading resources."""
|
|
||||||
zh: """支持跨域资源共享(CORS)
|
|
||||||
允许服务器指示任何来源(域名、协议或端口),除了本服务器之外的任何浏览器应允许加载资源。"""
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "CORS"
|
|
||||||
zh: "跨域资源共享"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i18n_lang {
|
|
||||||
desc {
|
|
||||||
en: "Internationalization language support."
|
|
||||||
zh: "swagger多语言支持"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: "I18n language"
|
|
||||||
zh: "多语言支持"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bootstrap_users_file {
|
|
||||||
desc {
|
|
||||||
en: "Initialize users file."
|
|
||||||
zh: "初始化用户文件"
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
en: """Is used to add an administrative user to Dashboard when emqx is first launched,
|
|
||||||
the format is:
|
|
||||||
```
|
|
||||||
username1:password1
|
|
||||||
username2:password2
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
zh: """用于在首次启动 emqx 时,为 Dashboard 添加管理用户,其格式为:
|
|
||||||
```
|
|
||||||
username1:password1
|
|
||||||
username2:password2
|
|
||||||
```
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -48,7 +48,7 @@
|
||||||
api_secret_hash = <<>> :: binary() | '_',
|
api_secret_hash = <<>> :: binary() | '_',
|
||||||
enable = true :: boolean() | '_',
|
enable = true :: boolean() | '_',
|
||||||
desc = <<>> :: binary() | '_',
|
desc = <<>> :: binary() | '_',
|
||||||
expired_at = 0 :: integer() | undefined | '_',
|
expired_at = 0 :: integer() | undefined | infinity | '_',
|
||||||
created_at = 0 :: integer() | '_'
|
created_at = 0 :: integer() | '_'
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ init_bootstrap_file() ->
|
||||||
init_bootstrap_file(File).
|
init_bootstrap_file(File).
|
||||||
|
|
||||||
create(Name, Enable, ExpiredAt, Desc) ->
|
create(Name, Enable, ExpiredAt, Desc) ->
|
||||||
case mnesia:table_info(?APP, size) < 1024 of
|
case mnesia:table_info(?APP, size) < 100 of
|
||||||
true -> create_app(Name, Enable, ExpiredAt, Desc);
|
true -> create_app(Name, Enable, ExpiredAt, Desc);
|
||||||
false -> {error, "Maximum ApiKey"}
|
false -> {error, "Maximum ApiKey"}
|
||||||
end.
|
end.
|
||||||
|
@ -237,16 +237,17 @@ init_bootstrap_file(File) ->
|
||||||
{ok, Dev} ->
|
{ok, Dev} ->
|
||||||
{ok, MP} = re:compile(<<"(\.+):(\.+$)">>, [ungreedy]),
|
{ok, MP} = re:compile(<<"(\.+):(\.+$)">>, [ungreedy]),
|
||||||
init_bootstrap_file(File, Dev, MP);
|
init_bootstrap_file(File, Dev, MP);
|
||||||
{error, Reason} = Error ->
|
{error, Reason0} ->
|
||||||
|
Reason = emqx_misc:explain_posix(Reason0),
|
||||||
?SLOG(
|
?SLOG(
|
||||||
error,
|
error,
|
||||||
#{
|
#{
|
||||||
msg => "failed_to_open_the_bootstrap_file",
|
msg => "failed_to_open_the_bootstrap_file",
|
||||||
file => File,
|
file => File,
|
||||||
reason => emqx_misc:explain_posix(Reason)
|
reason => Reason
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
Error
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
init_bootstrap_file(File, Dev, MP) ->
|
init_bootstrap_file(File, Dev, MP) ->
|
||||||
|
|
|
@ -25,15 +25,62 @@ suite() -> [{timetrap, {minutes, 1}}].
|
||||||
groups() ->
|
groups() ->
|
||||||
[
|
[
|
||||||
{parallel, [parallel], [t_create, t_update, t_delete, t_authorize, t_create_unexpired_app]},
|
{parallel, [parallel], [t_create, t_update, t_delete, t_authorize, t_create_unexpired_app]},
|
||||||
{sequence, [], [t_create_failed]}
|
{sequence, [], [t_bootstrap_file, t_create_failed]}
|
||||||
].
|
].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_mgmt_api_test_util:init_suite(),
|
emqx_mgmt_api_test_util:init_suite([emqx_conf]),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_suite(_) ->
|
end_per_suite(_) ->
|
||||||
emqx_mgmt_api_test_util:end_suite().
|
emqx_mgmt_api_test_util:end_suite([emqx_conf]).
|
||||||
|
|
||||||
|
t_bootstrap_file(_) ->
|
||||||
|
TestPath = <<"/api/v5/status">>,
|
||||||
|
Bin = <<"test-1:secret-1\ntest-2:secret-2">>,
|
||||||
|
File = "./bootstrap_api_keys.txt",
|
||||||
|
ok = file:write_file(File, Bin),
|
||||||
|
emqx:update_config([api_key, bootstrap_file], File),
|
||||||
|
ok = emqx_mgmt_auth:init_bootstrap_file(),
|
||||||
|
?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
|
||||||
|
?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
|
||||||
|
?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-1">>)),
|
||||||
|
|
||||||
|
%% relaunch to check if the table is changed.
|
||||||
|
Bin1 = <<"test-1:new-secret-1\ntest-2:new-secret-2">>,
|
||||||
|
ok = file:write_file(File, Bin1),
|
||||||
|
ok = emqx_mgmt_auth:init_bootstrap_file(),
|
||||||
|
?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-1">>)),
|
||||||
|
?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-2">>)),
|
||||||
|
?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"new-secret-1">>)),
|
||||||
|
?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"new-secret-2">>)),
|
||||||
|
|
||||||
|
%% Compatibility
|
||||||
|
Bin2 = <<"test-3:new-secret-3\ntest-4:new-secret-4">>,
|
||||||
|
ok = file:write_file(File, Bin2),
|
||||||
|
emqx:update_config([api_key, bootstrap_file], <<>>),
|
||||||
|
emqx:update_config([dashboard, bootstrap_users_file], File),
|
||||||
|
ok = emqx_mgmt_auth:init_bootstrap_file(),
|
||||||
|
?assertMatch(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"new-secret-1">>)),
|
||||||
|
?assertMatch(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"new-secret-2">>)),
|
||||||
|
?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-3">>, <<"new-secret-3">>)),
|
||||||
|
?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-4">>, <<"new-secret-4">>)),
|
||||||
|
|
||||||
|
%% not found
|
||||||
|
NotFoundFile = "./bootstrap_apps_not_exist.txt",
|
||||||
|
emqx:update_config([api_key, bootstrap_file], NotFoundFile),
|
||||||
|
?assertMatch({error, "No such file or directory"}, emqx_mgmt_auth:init_bootstrap_file()),
|
||||||
|
|
||||||
|
%% bad format
|
||||||
|
BadBin = <<"test-1:secret-11\ntest-2 secret-12">>,
|
||||||
|
ok = file:write_file(File, BadBin),
|
||||||
|
emqx:update_config([api_key, bootstrap_file], File),
|
||||||
|
?assertMatch({error, #{reason := "invalid_format"}}, emqx_mgmt_auth:init_bootstrap_file()),
|
||||||
|
?assertEqual(ok, emqx_mgmt_auth:authorize(TestPath, <<"test-1">>, <<"secret-11">>)),
|
||||||
|
?assertMatch({error, _}, emqx_mgmt_auth:authorize(TestPath, <<"test-2">>, <<"secret-12">>)),
|
||||||
|
emqx:update_config([api_key, bootstrap_file], <<>>),
|
||||||
|
emqx:update_config([dashboard, bootstrap_users_file], <<>>),
|
||||||
|
ok.
|
||||||
|
|
||||||
t_create(_Config) ->
|
t_create(_Config) ->
|
||||||
Name = <<"EMQX-API-KEY-1">>,
|
Name = <<"EMQX-API-KEY-1">>,
|
||||||
|
@ -69,7 +116,7 @@ t_create_failed(_Config) ->
|
||||||
?assertEqual(BadRequest, create_app(LongName)),
|
?assertEqual(BadRequest, create_app(LongName)),
|
||||||
|
|
||||||
{ok, List} = list_app(),
|
{ok, List} = list_app(),
|
||||||
CreateNum = 1024 - erlang:length(List),
|
CreateNum = 100 - erlang:length(List),
|
||||||
Names = lists:map(
|
Names = lists:map(
|
||||||
fun(Seq) ->
|
fun(Seq) ->
|
||||||
<<"EMQX-API-FAILED-KEY-", (integer_to_binary(Seq))/binary>>
|
<<"EMQX-API-FAILED-KEY-", (integer_to_binary(Seq))/binary>>
|
||||||
|
|
Loading…
Reference in New Issue