feat(dashboard): add bootstrap files to initialize user accounts

This commit is contained in:
firest 2022-08-09 15:17:39 +08:00
parent e9d7cde0b4
commit 0f8ebbdf0f
4 changed files with 69 additions and 7 deletions

View File

@ -197,4 +197,14 @@ its own from which a browser should permit loading resources."""
zh: "多语言支持"
}
}
bootstrap_user {
desc {
en: "Initialize users file."
zh: "初始化用户文件"
}
label {
en: "Initialize users file"
zh: "初始化用户文件"
}
}
}

View File

@ -50,7 +50,8 @@
-export([
add_default_user/0,
default_username/0
default_username/0,
add_bootstrap_user/0
]).
-type emqx_admin() :: #?ADMIN{}.
@ -74,6 +75,28 @@ 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 ->
add_bootstrap_user(File);
_ ->
ok
end
end.
%%--------------------------------------------------------------------
%% API
%%--------------------------------------------------------------------
@ -272,11 +295,6 @@ destroy_token_by_username(Username, Token) ->
%%--------------------------------------------------------------------
%% 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() ->
binenv(default_username).
@ -290,3 +308,35 @@ add_default_user(Username, Password) ->
[] -> add_user(Username, Password, <<"administrator">>);
_ -> {ok, default_user_exists}
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
end,
load_bootstrap_user(Dev, MP);
eof ->
ok;
Error ->
Error
end.

View File

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

View File

@ -54,7 +54,8 @@ fields("dashboard") ->
}
)},
{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") ->
[