Merge pull request #8667 from lafirest/feat/bootstrap_user

feat(dashboard): add bootstrap files to initialize user accounts
This commit is contained in:
lafirest 2022-08-12 10:43:42 +08:00 committed by GitHub
commit c7f6517aee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 89 additions and 9 deletions

View File

@ -197,4 +197,25 @@ its own from which a browser should permit loading resources."""
zh: "多语言支持" zh: "多语言支持"
} }
} }
bootstrap_user {
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
```
"""
}
}
} }

View File

@ -19,6 +19,7 @@
-module(emqx_dashboard_admin). -module(emqx_dashboard_admin).
-include("emqx_dashboard.hrl"). -include("emqx_dashboard.hrl").
-include_lib("emqx/include/logger.hrl").
-include_lib("stdlib/include/ms_transform.hrl"). -include_lib("stdlib/include/ms_transform.hrl").
-boot_mnesia({mnesia, [boot]}). -boot_mnesia({mnesia, [boot]}).
@ -50,7 +51,8 @@
-export([ -export([
add_default_user/0, add_default_user/0,
default_username/0 default_username/0,
add_bootstrap_user/0
]). ]).
-type emqx_admin() :: #?ADMIN{}. -type emqx_admin() :: #?ADMIN{}.
@ -74,6 +76,29 @@ mnesia(boot) ->
]} ]}
]). ]).
%%--------------------------------------------------------------------
%% bootstrap API
%%--------------------------------------------------------------------
-spec add_default_user() -> {ok, map() | empty | default_user_exists} | {error, any()}.
add_default_user() ->
add_default_user(binenv(default_username), binenv(default_password)).
-spec add_bootstrap_user() -> ok | {error, _}.
add_bootstrap_user() ->
case emqx:get_config([dashboard, bootstrap_user], undefined) of
undefined ->
ok;
File ->
case mnesia:table_info(?ADMIN, size) of
0 ->
?SLOG(debug, #{msg => "Add dashboard bootstrap users", file => File}),
add_bootstrap_user(File);
_ ->
ok
end
end.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% API %% API
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -272,11 +297,6 @@ destroy_token_by_username(Username, Token) ->
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Internal functions %% Internal functions
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
-spec add_default_user() -> {ok, map() | empty | default_user_exists} | {error, any()}.
add_default_user() ->
add_default_user(binenv(default_username), binenv(default_password)).
default_username() -> default_username() ->
binenv(default_username). binenv(default_username).
@ -290,3 +310,36 @@ add_default_user(Username, Password) ->
[] -> add_user(Username, Password, <<"administrator">>); [] -> add_user(Username, Password, <<"administrator">>);
_ -> {ok, default_user_exists} _ -> {ok, default_user_exists}
end. end.
add_bootstrap_user(File) ->
case file:open(File, [read]) of
{ok, Dev} ->
{ok, MP} = re:compile(<<"(\.+):(\.+)">>),
try
load_bootstrap_user(Dev, MP)
catch
Type:Reason ->
{error, {Type, Reason}}
after
file:close(Dev)
end;
Error ->
Error
end.
load_bootstrap_user(Dev, MP) ->
case file:read_line(Dev) of
{ok, Line} ->
case re:run(Line, MP, [global, {capture, all_but_first, binary}]) of
{match, Captured} ->
_ = [add_user(Username, Password, <<>>) || [Username, Password] <- Captured],
ok;
_ ->
ok
end,
load_bootstrap_user(Dev, MP);
eof ->
ok;
Error ->
Error
end.

View File

@ -31,8 +31,13 @@ start(_StartType, _StartArgs) ->
case emqx_dashboard:start_listeners() of case emqx_dashboard:start_listeners() of
ok -> ok ->
emqx_dashboard_cli:load(), emqx_dashboard_cli:load(),
case emqx_dashboard_admin:add_bootstrap_user() of
ok ->
{ok, _} = emqx_dashboard_admin:add_default_user(), {ok, _} = emqx_dashboard_admin:add_default_user(),
{ok, Sup}; {ok, Sup};
Error ->
Error
end;
{error, Reason} -> {error, Reason} ->
{error, Reason} {error, Reason}
end. end.

View File

@ -54,7 +54,8 @@ fields("dashboard") ->
} }
)}, )},
{cors, fun cors/1}, {cors, fun cors/1},
{i18n_lang, fun i18n_lang/1} {i18n_lang, fun i18n_lang/1},
{bootstrap_user, ?HOCON(binary(), #{desc => ?DESC(bootstrap_user), required => false})}
]; ];
fields("listeners") -> fields("listeners") ->
[ [