Merge pull request #12421 from HJianBo/fix-import-users
fix(user_import): ensure the last record overwrites previous one
This commit is contained in:
commit
c0674913e2
|
@ -96,8 +96,16 @@ request_body_schema() ->
|
||||||
schema => #{
|
schema => #{
|
||||||
type => object,
|
type => object,
|
||||||
example => [
|
example => [
|
||||||
#{<<"user_id">> => <<"user1">>, <<"password">> => <<"password1">>},
|
#{
|
||||||
#{<<"user_id">> => <<"user2">>, <<"password">> => <<"password2">>}
|
<<"user_id">> => <<"user1">>,
|
||||||
|
<<"password">> => <<"password1">>,
|
||||||
|
<<"is_superuser">> => true
|
||||||
|
},
|
||||||
|
#{
|
||||||
|
<<"user_id">> => <<"user2">>,
|
||||||
|
<<"password">> => <<"password2">>,
|
||||||
|
<<"is_superuser">> => false
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
user_id,password,is_superuser
|
||||||
|
myuser3,password3,true
|
||||||
|
myuser3,password4,false
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"user_id":"myuser1",
|
||||||
|
"password":"password1",
|
||||||
|
"is_superuser": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"user_id":"myuser1",
|
||||||
|
"password":"password2",
|
||||||
|
"is_superuser": false
|
||||||
|
}
|
||||||
|
]
|
|
@ -457,7 +457,7 @@ parse_import_users(Filename, FileData, Convertor) ->
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
ReaderFn = reader_fn(Filename, FileData),
|
ReaderFn = reader_fn(Filename, FileData),
|
||||||
Users = lists:reverse(Eval(ReaderFn)),
|
Users = Eval(ReaderFn),
|
||||||
NewUsersCount =
|
NewUsersCount =
|
||||||
lists:foldl(
|
lists:foldl(
|
||||||
fun(
|
fun(
|
||||||
|
|
|
@ -340,6 +340,55 @@ t_import_users_prepared_list(_) ->
|
||||||
)
|
)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
t_import_users_duplicated_records(_) ->
|
||||||
|
Config0 = config(),
|
||||||
|
Config = Config0#{password_hash_algorithm => #{name => plain, salt_position => disable}},
|
||||||
|
{ok, State} = emqx_authn_mnesia:create(?AUTHN_ID, Config),
|
||||||
|
|
||||||
|
?assertEqual(
|
||||||
|
ok,
|
||||||
|
emqx_authn_mnesia:import_users(
|
||||||
|
sample_filename_and_data(plain, <<"user-credentials-plain-dup.json">>),
|
||||||
|
State
|
||||||
|
)
|
||||||
|
),
|
||||||
|
?assertEqual(
|
||||||
|
ok,
|
||||||
|
emqx_authn_mnesia:import_users(
|
||||||
|
sample_filename_and_data(plain, <<"user-credentials-plain-dup.csv">>),
|
||||||
|
State
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Users1 = [
|
||||||
|
#{
|
||||||
|
<<"user_id">> => <<"myuser5">>,
|
||||||
|
<<"password">> => <<"password5">>,
|
||||||
|
<<"is_superuser">> => true
|
||||||
|
},
|
||||||
|
#{
|
||||||
|
<<"user_id">> => <<"myuser5">>,
|
||||||
|
<<"password">> => <<"password6">>,
|
||||||
|
<<"is_superuser">> => false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
?assertEqual(
|
||||||
|
ok,
|
||||||
|
emqx_authn_mnesia:import_users(
|
||||||
|
{plain, prepared_user_list, Users1},
|
||||||
|
State
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
%% assert: the last record overwrites the previous one
|
||||||
|
?assertMatch(
|
||||||
|
[
|
||||||
|
{user_info, {_, <<"myuser1">>}, <<"password2">>, _, false},
|
||||||
|
{user_info, {_, <<"myuser3">>}, <<"password4">>, _, false},
|
||||||
|
{user_info, {_, <<"myuser5">>}, <<"password6">>, _, false}
|
||||||
|
],
|
||||||
|
ets:tab2list(emqx_authn_mnesia)
|
||||||
|
).
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Helpers
|
%% Helpers
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
|
|
|
@ -206,11 +206,10 @@ fields(node_invitation_succeed) ->
|
||||||
[
|
[
|
||||||
{finished_at,
|
{finished_at,
|
||||||
?HOCON(
|
?HOCON(
|
||||||
emqx_utils_calendar:epoch_millisecond(),
|
binary(),
|
||||||
#{
|
#{
|
||||||
desc =>
|
desc => <<"The time of the async invitation result is received">>,
|
||||||
<<"The time of the async invitation result is received, millisecond precision epoch">>,
|
example => <<"2024-01-30T15:24:39.355+08:00">>
|
||||||
example => <<"1705044829915">>
|
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
|
@ -223,11 +222,10 @@ fields(node_invitation_in_progress) ->
|
||||||
)},
|
)},
|
||||||
{started_at,
|
{started_at,
|
||||||
?HOCON(
|
?HOCON(
|
||||||
emqx_utils_calendar:epoch_millisecond(),
|
binary(),
|
||||||
#{
|
#{
|
||||||
desc =>
|
desc => <<"The time of the async invitation is started">>,
|
||||||
<<"The start timestamp of the invitation, millisecond precision epoch">>,
|
example => <<"2024-01-30T15:24:39.355+08:00">>
|
||||||
example => <<"1705044829915">>
|
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
].
|
].
|
||||||
|
|
Loading…
Reference in New Issue