diff --git a/changes/v4.4.12-en.md b/changes/v4.4.12-en.md index d7c50c34a..751600dfe 100644 --- a/changes/v4.4.12-en.md +++ b/changes/v4.4.12-en.md @@ -7,3 +7,5 @@ - Fixed load bootstrap file when no bootstrap user in `mqtt_app` [#9474](https://github.com/emqx/emqx/pull/9474). - Trigger `message.dropped` hook when QoS2 message is resend by client with a same packet id, or 'awaiting_rel' queue is full [#9486](https://github.com/emqx/emqx/pull/9486). + +- When dashboard creates a new user, the password length must match 3-32 and the format is `^[A-Za-z0-9]+[A-Za-z0-9-_]*$` [#9475](https://github.com/emqx/emqx-enterprise/pull/9475). diff --git a/changes/v4.4.12-zh.md b/changes/v4.4.12-zh.md index 4dd86e913..226b499e0 100644 --- a/changes/v4.4.12-zh.md +++ b/changes/v4.4.12-zh.md @@ -2,9 +2,10 @@ - HTTP 客户端库 `ehttpc` 从 `0.2.1` 升级到 `0.4.2` [#9456](https://github.com/emqx/emqx/pull/9456)。 - ### 修复 - 修复 mqtt_app 表内没有 boostrap user 里未导入用户的问题 [#9474](https://github.com/emqx/emqx/pull/9474). - 当 QoS2 消息被重发(使用相同 Packet ID),或当 'awaiting_rel' 队列已满时,触发消息丢弃钩子(`message.dropped`)及计数器 [#9486](https://github.com/emqx/emqx-enterprise/pull/9486)。 + +- 当控制台创建新用户时,密码长度必须在 3-32 之间,且格式为 `^[A-Za-z0-9]+[A-Za-z0-9-_]*$` [#9475](https://github.com/emqx/emqx-enterprise/pull/9475)。 diff --git a/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl b/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl index a76ed9cff..49cf84b5b 100644 --- a/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl +++ b/lib-ce/emqx_dashboard/src/emqx_dashboard_admin.erl @@ -79,16 +79,17 @@ start_link() -> -spec(add_user(binary(), binary(), binary()) -> ok | {error, any()}). add_user(Username, Password, Tags) when is_binary(Username), is_binary(Password) -> - case emqx_misc:is_sane_id(Username) of - ok -> + case {emqx_misc:is_sane_id(Username), emqx_misc:is_sane_id(Password, 2, 32)} of + {ok, ok} -> Admin = #mqtt_admin{username = Username, password = hash(Password), tags = Tags}, return(mnesia:transaction(fun add_user_/1, [Admin])); - {error, Reason} -> {error, Reason} + {{error, Reason}, _} -> {error, Reason}; + {_, {error, Reason}} -> {error, Reason} end. force_add_user(Username, Password, Tags) -> - case emqx_misc:is_sane_id(Username) of - ok -> + case {emqx_misc:is_sane_id(Username), emqx_misc:is_sane_id(Password, 2, 32)} of + {ok, ok} -> AddFun = fun() -> mnesia:write(#mqtt_admin{username = Username, password = Password, tags = Tags}) end, @@ -96,7 +97,8 @@ force_add_user(Username, Password, Tags) -> {atomic, ok} -> ok; {aborted, Reason} -> {error, Reason} end; - {error, Reason} -> {error, Reason} + {{error, Reason}, _} -> {error, Reason}; + {_, {error, Reason}} -> {error, Reason} end. %% @private diff --git a/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl b/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl index d97aeb0aa..95b8c2c74 100644 --- a/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl +++ b/lib-ce/emqx_dashboard/test/emqx_dashboard_SUITE.erl @@ -82,6 +82,20 @@ t_overview(_) -> t_admins_add_delete({init, Config}) -> Config; t_admins_add_delete({'end', _Config}) -> ok; t_admins_add_delete(_) -> + ?assertEqual({error,<<"0 < Length =< 256">>}, + emqx_dashboard_admin:add_user(<<"">>, <<"password">>, <<"tag1">>)), + + ?assertEqual({error,<<"2 < Length =< 32">>}, + emqx_dashboard_admin:add_user(<<"badusername">>, <<"">>, <<"tag1">>)), + ?assertEqual({error,<<"2 < Length =< 32">>}, + emqx_dashboard_admin:add_user(<<"badusername">>, <<"p">>, <<"tag1">>)), + P33 = iolist_to_binary(lists:duplicate(33, <<"p">>)), + ?assertEqual({error,<<"2 < Length =< 32">>}, + emqx_dashboard_admin:add_user(<<"badusername">>, P33, <<"tag1">>)), + P32 = iolist_to_binary(lists:duplicate(32, <<"p">>)), + ?assertEqual(ok, emqx_dashboard_admin:add_user(<<"goodusername">>, P32, <<"tag1">>)), + ok = emqx_dashboard_admin:remove_user(<<"goodusername">>), + ok = emqx_dashboard_admin:add_user(<<"username">>, <<"password">>, <<"tag">>), ok = emqx_dashboard_admin:add_user(<<"username1">>, <<"password1">>, <<"tag1">>), ok = emqx_dashboard_admin:add_user(<<"1username1">>, <<"password1">>, <<"tag1">>), diff --git a/src/emqx.appup.src b/src/emqx.appup.src index afdf74062..b41e751d6 100644 --- a/src/emqx.appup.src +++ b/src/emqx.appup.src @@ -4,6 +4,7 @@ [{"4.4.11", [{add_module,emqx_cover}, {load_module,emqx_relup,brutal_purge,soft_purge,[]}, + {load_module,emqx_misc,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]}, @@ -380,6 +381,7 @@ [{"4.4.11", [{load_module,emqx_relup,brutal_purge,soft_purge,[]}, {load_module,emqx_app,brutal_purge,soft_purge,[]}, + {load_module,emqx_misc,brutal_purge,soft_purge,[]}, {load_module,emqx_cm,brutal_purge,soft_purge,[]}, {load_module,emqx_channel,brutal_purge,soft_purge,[]}, {load_module,emqx_session,brutal_purge,soft_purge,[]}, diff --git a/src/emqx_misc.erl b/src/emqx_misc.erl index f276c3ec2..1fd1152ce 100644 --- a/src/emqx_misc.erl +++ b/src/emqx_misc.erl @@ -59,6 +59,7 @@ ]). -export([ is_sane_id/1 + , is_sane_id/3 ]). -export([ @@ -73,14 +74,21 @@ -spec is_sane_id(list() | binary()) -> ok | {error, Reason::binary()}. is_sane_id(Str) -> + is_sane_id(Str, 0, 256). + +is_sane_id(Str, Min, Max) -> StrLen = len(Str), - case StrLen > 0 andalso StrLen =< 256 of + case StrLen > Min andalso StrLen =< Max of true -> case re:run(Str, ?VALID_STR_RE) of nomatch -> {error, <<"required: " ?VALID_STR_RE>>}; _ -> ok end; - false -> {error, <<"0 < Length =< 256">>} + false -> + Msg = <<(integer_to_binary(Min))/binary, + <<" < Length =< ">>/binary, + (integer_to_binary(Max))/binary>>, + {error, Msg} end. len(Bin) when is_binary(Bin) -> byte_size(Bin);