Merge remote-tracking branch 'ce/main-v4.3' into merge-main-v4.3-into-v4.4
This commit is contained in:
commit
e5fab4df25
|
@ -32,27 +32,32 @@
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([match_password/3]).
|
-export([ match_password/3
|
||||||
|
, hash_type/0
|
||||||
|
]).
|
||||||
|
|
||||||
init(#{clientid_list := ClientidList, username_list := UsernameList}) ->
|
init(#{clientid_list := ClientidList, username_list := UsernameList}) ->
|
||||||
ok = ekka_mnesia:create_table(?TABLE, [
|
ok = ekka_mnesia:create_table(?TABLE, [
|
||||||
{disc_copies, [node()]},
|
{disc_copies, [node()]},
|
||||||
{attributes, record_info(fields, emqx_user)},
|
{attributes, record_info(fields, emqx_user)},
|
||||||
{storage_properties, [{ets, [{read_concurrency, true}]}]}]),
|
{storage_properties, [{ets, [{read_concurrency, true}]}]}]),
|
||||||
_ = [ add_default_user({{clientid, iolist_to_binary(Clientid)}, iolist_to_binary(Password)})
|
lists:foreach(fun({Clientid, Password}) ->
|
||||||
|| {Clientid, Password} <- ClientidList],
|
emqx_auth_mnesia_cli:add_default_user(clientid, iolist_to_binary(Clientid), iolist_to_binary(Password))
|
||||||
_ = [ add_default_user({{username, iolist_to_binary(Username)}, iolist_to_binary(Password)})
|
end, ClientidList),
|
||||||
|| {Username, Password} <- UsernameList],
|
|
||||||
ok = ekka_mnesia:copy_table(?TABLE, disc_copies).
|
|
||||||
|
|
||||||
%% @private
|
lists:foreach(fun({Username, Password}) ->
|
||||||
add_default_user({Login, Password}) when is_tuple(Login) ->
|
emqx_auth_mnesia_cli:add_default_user(username, iolist_to_binary(Username), iolist_to_binary(Password))
|
||||||
emqx_auth_mnesia_cli:force_add_user(Login, Password).
|
end, UsernameList),
|
||||||
|
|
||||||
|
ok = ekka_mnesia:copy_table(?TABLE, disc_copies).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
-spec(register_metrics() -> ok).
|
||||||
register_metrics() ->
|
register_metrics() ->
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
||||||
|
|
||||||
|
hash_type() ->
|
||||||
|
application:get_env(emqx_auth_mnesia, password_hash, sha256).
|
||||||
|
|
||||||
check(ClientInfo = #{ clientid := Clientid
|
check(ClientInfo = #{ clientid := Clientid
|
||||||
, password := NPassword
|
, password := NPassword
|
||||||
}, AuthResult, #{hash_type := HashType}) ->
|
}, AuthResult, #{hash_type := HashType}) ->
|
||||||
|
|
|
@ -57,9 +57,7 @@ load_auth_hook() ->
|
||||||
UsernameList = application:get_env(?APP, username_list, []),
|
UsernameList = application:get_env(?APP, username_list, []),
|
||||||
ok = emqx_auth_mnesia:init(#{clientid_list => ClientidList, username_list => UsernameList}),
|
ok = emqx_auth_mnesia:init(#{clientid_list => ClientidList, username_list => UsernameList}),
|
||||||
ok = emqx_auth_mnesia:register_metrics(),
|
ok = emqx_auth_mnesia:register_metrics(),
|
||||||
Params = #{
|
Params = #{hash_type => emqx_auth_mnesia:hash_type()},
|
||||||
hash_type => application:get_env(emqx_auth_mnesia, password_hash, sha256)
|
|
||||||
},
|
|
||||||
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]).
|
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]).
|
||||||
|
|
||||||
load_acl_hook() ->
|
load_acl_hook() ->
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
%% Auth APIs
|
%% Auth APIs
|
||||||
-export([ add_user/2
|
-export([ add_user/2
|
||||||
, force_add_user/2
|
, force_add_user/2
|
||||||
|
, add_default_user/3
|
||||||
, update_user/2
|
, update_user/2
|
||||||
, remove_user/1
|
, remove_user/1
|
||||||
, lookup_user/1
|
, lookup_user/1
|
||||||
|
@ -57,6 +58,39 @@ insert_user(User = #emqx_user{login = Login}) ->
|
||||||
[_|_] -> mnesia:abort(existed)
|
[_|_] -> mnesia:abort(existed)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec(add_default_user(clientid | username, tuple(), binary()) -> ok | {error, any()}).
|
||||||
|
add_default_user(Type, Key, Password) ->
|
||||||
|
Login = {Type, Key},
|
||||||
|
case add_user(Login, Password) of
|
||||||
|
ok -> ok;
|
||||||
|
{error, existed} ->
|
||||||
|
NewPwd = encrypted_data(Password),
|
||||||
|
[#emqx_user{password = OldPwd}] = emqx_auth_mnesia_cli:lookup_user(Login),
|
||||||
|
HashType = emqx_auth_mnesia:hash_type(),
|
||||||
|
case emqx_auth_mnesia:match_password(NewPwd, HashType, [OldPwd]) of
|
||||||
|
true -> ok;
|
||||||
|
false ->
|
||||||
|
%% We can't force add default,
|
||||||
|
%% otherwise passwords that have been updated via HTTP API will be reset after reboot.
|
||||||
|
TypeCtl =
|
||||||
|
case Type of
|
||||||
|
clientid -> clientid;
|
||||||
|
username -> user
|
||||||
|
end,
|
||||||
|
?LOG(warning,
|
||||||
|
"[Auth Mnesia] auth.client.x.~p=~s's password in the emqx_auth_mnesia.conf\n"
|
||||||
|
"does not match the password in the database(mnesia).\n"
|
||||||
|
"1. If you have already changed the password via the HTTP API, this warning has no effect.\n"
|
||||||
|
"You can remove the warning from emqx_auth_mnesia.conf to resolve the warning.\n"
|
||||||
|
"2. If you just want to update the password by manually changing the configuration file,\n"
|
||||||
|
"you need to delete the old user and password using `emqx_ctl ~p delete ~s` first\n"
|
||||||
|
"the new password in emqx_auth_mnesia.conf can take effect after reboot.",
|
||||||
|
[Type, Key, TypeCtl, Key]),
|
||||||
|
ok
|
||||||
|
end;
|
||||||
|
Error -> Error
|
||||||
|
end.
|
||||||
|
|
||||||
force_add_user(Login, Password) ->
|
force_add_user(Login, Password) ->
|
||||||
User = #emqx_user{
|
User = #emqx_user{
|
||||||
login = Login,
|
login = Login,
|
||||||
|
@ -74,7 +108,7 @@ insert_or_update_user(NewPwd, User = #emqx_user{login = Login}) ->
|
||||||
case mnesia:read(?TABLE, Login) of
|
case mnesia:read(?TABLE, Login) of
|
||||||
[] -> mnesia:write(User);
|
[] -> mnesia:write(User);
|
||||||
[#emqx_user{password = Pwd}] ->
|
[#emqx_user{password = Pwd}] ->
|
||||||
case emqx_auth_mnesia:match_password(NewPwd, hash_type(), [Pwd]) of
|
case emqx_auth_mnesia:match_password(NewPwd, emqx_auth_mnesia:hash_type(), [Pwd]) of
|
||||||
true -> ok;
|
true -> ok;
|
||||||
false ->
|
false ->
|
||||||
ok = mnesia:write(User),
|
ok = mnesia:write(User),
|
||||||
|
@ -136,7 +170,7 @@ ret({atomic, Res}) -> Res;
|
||||||
ret({aborted, Error}) -> {error, Error}.
|
ret({aborted, Error}) -> {error, Error}.
|
||||||
|
|
||||||
encrypted_data(Password) ->
|
encrypted_data(Password) ->
|
||||||
HashType = hash_type(),
|
HashType = emqx_auth_mnesia:hash_type(),
|
||||||
SaltBin = salt(),
|
SaltBin = salt(),
|
||||||
<<SaltBin/binary, (hash(Password, SaltBin, HashType))/binary>>.
|
<<SaltBin/binary, (hash(Password, SaltBin, HashType))/binary>>.
|
||||||
|
|
||||||
|
@ -219,5 +253,3 @@ auth_username_cli(_) ->
|
||||||
{"user add <Username> <Password>", "Add username auth rule"},
|
{"user add <Username> <Password>", "Add username auth rule"},
|
||||||
{"user update <Username> <NewPassword>", "Update username auth rule"},
|
{"user update <Username> <NewPassword>", "Update username auth rule"},
|
||||||
{"user delete <Username>", "Delete username auth rule"}]).
|
{"user delete <Username>", "Delete username auth rule"}]).
|
||||||
hash_type() ->
|
|
||||||
application:get_env(emqx_auth_mnesia, password_hash, sha256).
|
|
||||||
|
|
|
@ -103,6 +103,17 @@ t_boot(_Config) ->
|
||||||
|
|
||||||
%% change default pwd
|
%% change default pwd
|
||||||
NewPwd = <<"emqx654321">>,
|
NewPwd = <<"emqx654321">>,
|
||||||
|
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
|
||||||
|
fun(_) -> set_default(ClientId, UserName, NewPwd, sha256) end),
|
||||||
|
?assertEqual(Failed,
|
||||||
|
emqx_auth_mnesia:check(#{clientid => ClientId, password => NewPwd},
|
||||||
|
#{}, #{hash_type => sha256})),
|
||||||
|
?assertEqual(Failed,
|
||||||
|
emqx_auth_mnesia:check(#{clientid => <<"NotExited">>, username => UserName, password => NewPwd},
|
||||||
|
#{}, #{hash_type => sha256})),
|
||||||
|
clean_all_users(),
|
||||||
|
emqx_ct_helpers:stop_apps([emqx_auth_mnesia]),
|
||||||
|
|
||||||
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
|
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
|
||||||
fun(_) -> set_default(ClientId, UserName, NewPwd, sha256) end),
|
fun(_) -> set_default(ClientId, UserName, NewPwd, sha256) end),
|
||||||
?assertEqual(Ok,
|
?assertEqual(Ok,
|
||||||
|
@ -115,6 +126,17 @@ t_boot(_Config) ->
|
||||||
|
|
||||||
%% change hash_type
|
%% change hash_type
|
||||||
NewPwd2 = <<"emqx6543210">>,
|
NewPwd2 = <<"emqx6543210">>,
|
||||||
|
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
|
||||||
|
fun(_) -> set_default(ClientId, UserName, NewPwd2, plain) end),
|
||||||
|
?assertEqual(Failed,
|
||||||
|
emqx_auth_mnesia:check(#{clientid => ClientId, password => NewPwd2},
|
||||||
|
#{}, #{hash_type => plain})),
|
||||||
|
?assertEqual(Failed,
|
||||||
|
emqx_auth_mnesia:check(#{clientid => <<"NotExited">>, username => UserName, password => NewPwd2},
|
||||||
|
#{}, #{hash_type => plain})),
|
||||||
|
clean_all_users(),
|
||||||
|
emqx_ct_helpers:stop_apps([emqx_auth_mnesia]),
|
||||||
|
|
||||||
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
|
ok = emqx_ct_helpers:start_apps([emqx_auth_mnesia],
|
||||||
fun(_) -> set_default(ClientId, UserName, NewPwd2, plain) end),
|
fun(_) -> set_default(ClientId, UserName, NewPwd2, plain) end),
|
||||||
?assertEqual(Ok,
|
?assertEqual(Ok,
|
||||||
|
|
|
@ -98,8 +98,7 @@ add_meta(Params, List) ->
|
||||||
page => Page,
|
page => Page,
|
||||||
limit => Limit,
|
limit => Limit,
|
||||||
hasnext => Start + Limit - 1 < Count,
|
hasnext => Start + Limit - 1 < Count,
|
||||||
count => Count
|
count => Count},
|
||||||
},
|
|
||||||
data => Data,
|
data => Data,
|
||||||
code => 0
|
code => 0
|
||||||
}.
|
}.
|
||||||
|
|
Loading…
Reference in New Issue