chore(authn api): replace user import api with upload api
This commit is contained in:
parent
96f58d0ec8
commit
2d53c21d45
|
@ -166,11 +166,11 @@ when
|
|||
when
|
||||
State :: state().
|
||||
|
||||
-callback import_users(Filename, State) ->
|
||||
-callback import_users({Filename, FileData}, State) ->
|
||||
ok
|
||||
| {error, term()}
|
||||
when
|
||||
Filename :: binary(), State :: state().
|
||||
Filename :: binary(), FileData :: binary(), State :: state().
|
||||
|
||||
-callback add_user(UserInfo, State) ->
|
||||
{ok, User}
|
||||
|
@ -385,7 +385,7 @@ list_authenticators(ChainName) ->
|
|||
move_authenticator(ChainName, AuthenticatorID, Position) ->
|
||||
call({move_authenticator, ChainName, AuthenticatorID, Position}).
|
||||
|
||||
-spec import_users(chain_name(), authenticator_id(), binary() | {binary(), binary()}) ->
|
||||
-spec import_users(chain_name(), authenticator_id(), {binary(), binary()}) ->
|
||||
ok | {error, term()}.
|
||||
import_users(ChainName, AuthenticatorID, Filename) ->
|
||||
call({import_users, ChainName, AuthenticatorID, Filename}).
|
||||
|
|
|
@ -105,20 +105,6 @@ emqx_authn_api {
|
|||
}
|
||||
}
|
||||
|
||||
authentication_id_import_users_post {
|
||||
desc {
|
||||
en: """Import users into authenticator in global authentication chain."""
|
||||
zh: """为全局认证链上的指定认证器导入用户数据。"""
|
||||
}
|
||||
}
|
||||
|
||||
listeners_listener_id_authentication_id_import_users_post {
|
||||
desc {
|
||||
en: """Import users into authenticator in listener authentication chain."""
|
||||
zh: """为监听器认证链上的指定认证器导入用户数据。"""
|
||||
}
|
||||
}
|
||||
|
||||
authentication_id_users_post {
|
||||
desc {
|
||||
en: """Create users for authenticator in global authentication chain."""
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
emqx_authn_user_import_api {
|
||||
|
||||
authentication_id_import_users_post {
|
||||
desc {
|
||||
en: """Import users into authenticator in global authentication chain."""
|
||||
zh: """为全局认证链上的指定认证器导入用户数据。"""
|
||||
}
|
||||
}
|
||||
|
||||
listeners_listener_id_authentication_id_import_users_post {
|
||||
desc {
|
||||
en: """Import users into authenticator in listener authentication chain."""
|
||||
zh: """为监听器认证链上的指定认证器导入用户数据。"""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
emqx_authn_user_upload_api {
|
||||
|
||||
authentication_id_upload_users_post {
|
||||
desc {
|
||||
en: """Upload file with users into authenticator in global authentication chain."""
|
||||
zh: """将带有用户的文件上传到全局身份验证链中的身份验证器。"""
|
||||
}
|
||||
}
|
||||
|
||||
listeners_listener_id_authentication_id_upload_users_post {
|
||||
desc {
|
||||
en: """Upload file with users into authenticator in listener-specific authentication chain."""
|
||||
zh: """将带有用户的文件上传到特定于侦听器的身份验证链中的身份验证器。"""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -62,8 +62,6 @@
|
|||
listener_authenticator_status/2,
|
||||
authenticator_move/2,
|
||||
listener_authenticator_move/2,
|
||||
authenticator_import_users/2,
|
||||
listener_authenticator_import_users/2,
|
||||
authenticator_users/2,
|
||||
authenticator_user/2,
|
||||
listener_authenticator_users/2,
|
||||
|
@ -75,7 +73,6 @@
|
|||
-export([
|
||||
authenticator_examples/0,
|
||||
request_move_examples/0,
|
||||
request_import_users_examples/0,
|
||||
request_user_create_examples/0,
|
||||
request_user_update_examples/0,
|
||||
response_user_examples/0,
|
||||
|
@ -108,7 +105,6 @@ paths() ->
|
|||
"/authentication/:id",
|
||||
"/authentication/:id/status",
|
||||
"/authentication/:id/move",
|
||||
"/authentication/:id/import_users",
|
||||
"/authentication/:id/users",
|
||||
"/authentication/:id/users/:user_id",
|
||||
|
||||
|
@ -116,7 +112,6 @@ paths() ->
|
|||
"/listeners/:listener_id/authentication/:id",
|
||||
"/listeners/:listener_id/authentication/:id/status",
|
||||
"/listeners/:listener_id/authentication/:id/move",
|
||||
"/listeners/:listener_id/authentication/:id/import_users",
|
||||
"/listeners/:listener_id/authentication/:id/users",
|
||||
"/listeners/:listener_id/authentication/:id/users/:user_id"
|
||||
].
|
||||
|
@ -126,7 +121,6 @@ roots() ->
|
|||
request_user_create,
|
||||
request_user_update,
|
||||
request_move,
|
||||
request_import_users,
|
||||
response_user,
|
||||
response_users
|
||||
].
|
||||
|
@ -143,9 +137,6 @@ fields(request_user_update) ->
|
|||
];
|
||||
fields(request_move) ->
|
||||
[{position, mk(binary(), #{required => true})}];
|
||||
fields(request_import_users) ->
|
||||
%% TODO: add file update
|
||||
[{filename, mk(binary(), #{required => true})}];
|
||||
fields(response_user) ->
|
||||
[
|
||||
{user_id, mk(binary(), #{required => true})},
|
||||
|
@ -379,42 +370,6 @@ schema("/listeners/:listener_id/authentication/:id/move") ->
|
|||
}
|
||||
}
|
||||
};
|
||||
schema("/authentication/:id/import_users") ->
|
||||
#{
|
||||
'operationId' => authenticator_import_users,
|
||||
post => #{
|
||||
tags => ?API_TAGS_GLOBAL,
|
||||
description => ?DESC(authentication_id_import_users_post),
|
||||
parameters => [param_auth_id()],
|
||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||
ref(request_import_users),
|
||||
request_import_users_examples()
|
||||
),
|
||||
responses => #{
|
||||
204 => <<"Users imported">>,
|
||||
400 => error_codes([?BAD_REQUEST], <<"Bad Request">>),
|
||||
404 => error_codes([?NOT_FOUND], <<"Not Found">>)
|
||||
}
|
||||
}
|
||||
};
|
||||
schema("/listeners/:listener_id/authentication/:id/import_users") ->
|
||||
#{
|
||||
'operationId' => listener_authenticator_import_users,
|
||||
post => #{
|
||||
tags => ?API_TAGS_SINGLE,
|
||||
description => ?DESC(listeners_listener_id_authentication_id_import_users_post),
|
||||
parameters => [param_listener_id(), param_auth_id()],
|
||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||
ref(request_import_users),
|
||||
request_import_users_examples()
|
||||
),
|
||||
responses => #{
|
||||
204 => <<"Users imported">>,
|
||||
400 => error_codes([?BAD_REQUEST], <<"Bad Request">>),
|
||||
404 => error_codes([?NOT_FOUND], <<"Not Found">>)
|
||||
}
|
||||
}
|
||||
};
|
||||
schema("/authentication/:id/users") ->
|
||||
#{
|
||||
'operationId' => authenticator_users,
|
||||
|
@ -751,39 +706,6 @@ listener_authenticator_move(
|
|||
listener_authenticator_move(post, #{bindings := #{listener_id := _, id := _}, body := _}) ->
|
||||
serialize_error({missing_parameter, position}).
|
||||
|
||||
authenticator_import_users(
|
||||
post,
|
||||
#{
|
||||
bindings := #{id := AuthenticatorID},
|
||||
body := #{<<"filename">> := Filename}
|
||||
}
|
||||
) ->
|
||||
case emqx_authentication:import_users(?GLOBAL, AuthenticatorID, Filename) of
|
||||
ok -> {204};
|
||||
{error, Reason} -> serialize_error(Reason)
|
||||
end;
|
||||
authenticator_import_users(post, #{bindings := #{id := _}, body := _}) ->
|
||||
serialize_error({missing_parameter, filename}).
|
||||
|
||||
listener_authenticator_import_users(
|
||||
post,
|
||||
#{
|
||||
bindings := #{listener_id := ListenerID, id := AuthenticatorID},
|
||||
body := #{<<"filename">> := Filename}
|
||||
}
|
||||
) ->
|
||||
with_chain(
|
||||
ListenerID,
|
||||
fun(ChainName) ->
|
||||
case emqx_authentication:import_users(ChainName, AuthenticatorID, Filename) of
|
||||
ok -> {204};
|
||||
{error, Reason} -> serialize_error(Reason)
|
||||
end
|
||||
end
|
||||
);
|
||||
listener_authenticator_import_users(post, #{bindings := #{listener_id := _, id := _}, body := _}) ->
|
||||
serialize_error({missing_parameter, filename}).
|
||||
|
||||
authenticator_users(post, #{bindings := #{id := AuthenticatorID}, body := UserInfo}) ->
|
||||
add_user(?GLOBAL, AuthenticatorID, UserInfo);
|
||||
authenticator_users(get, #{bindings := #{id := AuthenticatorID}, query_string := QueryString}) ->
|
||||
|
@ -1583,22 +1505,6 @@ request_move_examples() ->
|
|||
}
|
||||
}.
|
||||
|
||||
request_import_users_examples() ->
|
||||
#{
|
||||
import_csv => #{
|
||||
summary => <<"Import users from CSV file">>,
|
||||
value => #{
|
||||
filename => <<"/path/to/user/data.csv">>
|
||||
}
|
||||
},
|
||||
import_json => #{
|
||||
summary => <<"Import users from JSON file">>,
|
||||
value => #{
|
||||
filename => <<"/path/to/user/data.json">>
|
||||
}
|
||||
}
|
||||
}.
|
||||
|
||||
response_user_examples() ->
|
||||
#{
|
||||
regular_user => #{
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
%% limitations under the License.
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-module(emqx_authn_user_upload_api).
|
||||
-module(emqx_authn_user_import_api).
|
||||
|
||||
-behaviour(minirest_api).
|
||||
|
||||
|
@ -46,8 +46,8 @@
|
|||
]).
|
||||
|
||||
-export([
|
||||
authenticator_upload_users/2,
|
||||
listener_authenticator_upload_users/2
|
||||
authenticator_import_users/2,
|
||||
listener_authenticator_import_users/2
|
||||
]).
|
||||
|
||||
api_spec() ->
|
||||
|
@ -55,16 +55,16 @@ api_spec() ->
|
|||
|
||||
paths() ->
|
||||
[
|
||||
"/authentication/:id/upload_users",
|
||||
"/listeners/:listener_id/authentication/:id/upload_users"
|
||||
"/authentication/:id/import_users",
|
||||
"/listeners/:listener_id/authentication/:id/import_users"
|
||||
].
|
||||
|
||||
schema("/authentication/:id/upload_users") ->
|
||||
schema("/authentication/:id/import_users") ->
|
||||
#{
|
||||
'operationId' => authenticator_upload_users,
|
||||
'operationId' => authenticator_import_users,
|
||||
post => #{
|
||||
tags => ?API_TAGS_GLOBAL,
|
||||
description => ?DESC(authentication_id_upload_users_post),
|
||||
description => ?DESC(authentication_id_import_users_post),
|
||||
parameters => [emqx_authn_api:param_auth_id()],
|
||||
'requestBody' => #{
|
||||
content => #{
|
||||
|
@ -82,12 +82,12 @@ schema("/authentication/:id/upload_users") ->
|
|||
}
|
||||
}
|
||||
};
|
||||
schema("/listeners/:listener_id/authentication/:id/upload_users") ->
|
||||
schema("/listeners/:listener_id/authentication/:id/import_users") ->
|
||||
#{
|
||||
'operationId' => listener_authenticator_upload_users,
|
||||
'operationId' => listener_authenticator_import_users,
|
||||
post => #{
|
||||
tags => ?API_TAGS_SINGLE,
|
||||
description => ?DESC(listeners_listener_id_authentication_id_upload_users_post),
|
||||
description => ?DESC(listeners_listener_id_authentication_id_import_users_post),
|
||||
parameters => [emqx_authn_api:param_listener_id(), emqx_authn_api:param_auth_id()],
|
||||
'requestBody' => #{
|
||||
content => #{
|
||||
|
@ -106,7 +106,7 @@ schema("/listeners/:listener_id/authentication/:id/upload_users") ->
|
|||
}
|
||||
}.
|
||||
|
||||
authenticator_upload_users(
|
||||
authenticator_import_users(
|
||||
post,
|
||||
#{
|
||||
bindings := #{id := AuthenticatorID},
|
||||
|
@ -118,10 +118,10 @@ authenticator_upload_users(
|
|||
ok -> {204};
|
||||
{error, Reason} -> emqx_authn_api:serialize_error(Reason)
|
||||
end;
|
||||
authenticator_upload_users(post, #{bindings := #{id := _}, body := _}) ->
|
||||
authenticator_import_users(post, #{bindings := #{id := _}, body := _}) ->
|
||||
emqx_authn_api:serialize_error({missing_parameter, filename}).
|
||||
|
||||
listener_authenticator_upload_users(
|
||||
listener_authenticator_import_users(
|
||||
post,
|
||||
#{
|
||||
bindings := #{listener_id := ListenerID, id := AuthenticatorID},
|
||||
|
@ -140,5 +140,5 @@ listener_authenticator_upload_users(
|
|||
end
|
||||
end
|
||||
);
|
||||
listener_authenticator_upload_users(post, #{bindings := #{listener_id := _, id := _}, body := _}) ->
|
||||
listener_authenticator_import_users(post, #{bindings := #{listener_id := _, id := _}, body := _}) ->
|
||||
emqx_authn_api:serialize_error({missing_parameter, filename}).
|
|
@ -188,32 +188,12 @@ import_users({Filename0, FileData}, State) ->
|
|||
<<".json">> ->
|
||||
import_users_from_json(FileData, State);
|
||||
<<".csv">> ->
|
||||
{ok, CSV} = csv_data_reader(FileData),
|
||||
CSV = csv_data(FileData),
|
||||
import_users_from_csv(CSV, State);
|
||||
<<>> ->
|
||||
{error, unknown_file_format};
|
||||
Extension ->
|
||||
{error, {unsupported_file_format, Extension}}
|
||||
end;
|
||||
import_users(Filename0, State) ->
|
||||
Filename = to_binary(Filename0),
|
||||
case filename:extension(Filename) of
|
||||
<<".json">> ->
|
||||
case file:read_file(Filename) of
|
||||
{ok, Data} -> import_users_from_json(Data, State);
|
||||
{error, _} = Error -> Error
|
||||
end;
|
||||
<<".csv">> ->
|
||||
case csv_file_reader(Filename) of
|
||||
{ok, CSV} ->
|
||||
import_users_from_csv(CSV, State);
|
||||
{error, _} = Error ->
|
||||
Error
|
||||
end;
|
||||
<<>> ->
|
||||
{error, unknown_file_format};
|
||||
Extension ->
|
||||
{error, {unsupported_file_format, Extension}}
|
||||
end.
|
||||
|
||||
add_user(
|
||||
|
@ -360,9 +340,7 @@ import_users_from_json(Bin, #{user_group := UserGroup}) ->
|
|||
import_users_from_csv(CSV, #{user_group := UserGroup}) ->
|
||||
case get_csv_header(CSV) of
|
||||
{ok, Seq, NewCSV} ->
|
||||
Result = trans(fun import_csv/3, [UserGroup, NewCSV, Seq]),
|
||||
_ = csv_close(CSV),
|
||||
Result;
|
||||
trans(fun import_csv/3, [UserGroup, NewCSV, Seq]);
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
@ -404,9 +382,7 @@ import_csv(UserGroup, CSV, Seq) ->
|
|||
{error, Reason}
|
||||
end;
|
||||
eof ->
|
||||
ok;
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
ok
|
||||
end.
|
||||
|
||||
get_csv_header(CSV) ->
|
||||
|
@ -415,9 +391,7 @@ get_csv_header(CSV) ->
|
|||
Seq = binary:split(Line, [<<",">>, <<" ">>, <<"\n">>], [global, trim_all]),
|
||||
{ok, Seq, NewCSV};
|
||||
eof ->
|
||||
{error, empty_file};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
{error, empty_file}
|
||||
end.
|
||||
|
||||
get_user_info_by_seq(Fields, Seq) ->
|
||||
|
@ -499,33 +473,11 @@ group_match_spec(UserGroup, QString) ->
|
|||
end)
|
||||
end.
|
||||
|
||||
csv_file_reader(Filename) ->
|
||||
case file:open(Filename, [read, binary]) of
|
||||
{ok, File} ->
|
||||
{ok, {csv_file_reader, File}};
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
csv_data_reader(Data) ->
|
||||
csv_data(Data) ->
|
||||
Lines = binary:split(Data, [<<"\r">>, <<"\n">>], [global, trim_all]),
|
||||
{ok, {csv_data_reader, Lines}}.
|
||||
{csv_data, Lines}.
|
||||
|
||||
csv_read_line({csv_file_reader, File} = CSV) ->
|
||||
case file:read_line(File) of
|
||||
{ok, Line} ->
|
||||
{ok, Line, CSV};
|
||||
eof ->
|
||||
eof;
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end;
|
||||
csv_read_line({csv_data_reader, [Line | Lines]}) ->
|
||||
{ok, Line, {csv_data_reader, Lines}};
|
||||
csv_read_line({csv_data_reader, []}) ->
|
||||
csv_read_line({csv_data, [Line | Lines]}) ->
|
||||
{ok, Line, {csv_data, Lines}};
|
||||
csv_read_line({csv_data, []}) ->
|
||||
eof.
|
||||
|
||||
csv_close({csv_file_reader, File}) ->
|
||||
file:close(File);
|
||||
csv_close({csv_data_reader, _}) ->
|
||||
ok.
|
||||
|
|
|
@ -102,9 +102,6 @@ t_authenticator_move(_) ->
|
|||
t_authenticator_import_users(_) ->
|
||||
test_authenticator_import_users([]).
|
||||
|
||||
t_authenticator_upload_users(_) ->
|
||||
test_authenticator_upload_users([]).
|
||||
|
||||
t_listener_authenticators(_) ->
|
||||
test_authenticators(["listeners", ?TCP_DEFAULT]).
|
||||
|
||||
|
@ -123,9 +120,6 @@ t_listener_authenticator_move(_) ->
|
|||
t_listener_authenticator_import_users(_) ->
|
||||
test_authenticator_import_users(["listeners", ?TCP_DEFAULT]).
|
||||
|
||||
t_listener_authenticator_upload_users(_) ->
|
||||
test_authenticator_upload_users(["listeners", ?TCP_DEFAULT]).
|
||||
|
||||
t_aggregate_metrics(_) ->
|
||||
Metrics = #{
|
||||
'emqx@node1.emqx.io' => #{
|
||||
|
@ -649,33 +643,8 @@ test_authenticator_import_users(PathPrefix) ->
|
|||
emqx_authn_test_lib:built_in_database_example()
|
||||
),
|
||||
|
||||
{ok, 400, _} = request(post, ImportUri, #{}),
|
||||
|
||||
{ok, 400, _} = request(post, ImportUri, #{filename => <<"/etc/passwd">>}),
|
||||
|
||||
{ok, 400, _} = request(post, ImportUri, #{filename => <<"/not_exists.csv">>}),
|
||||
|
||||
Dir = code:lib_dir(emqx_authn, test),
|
||||
JSONFileName = filename:join([Dir, <<"data/user-credentials.json">>]),
|
||||
CSVFileName = filename:join([Dir, <<"data/user-credentials.csv">>]),
|
||||
|
||||
{ok, 204, _} = request(post, ImportUri, #{filename => JSONFileName}),
|
||||
|
||||
{ok, 204, _} = request(post, ImportUri, #{filename => CSVFileName}).
|
||||
|
||||
test_authenticator_upload_users(PathPrefix) ->
|
||||
UploadUri = uri(
|
||||
PathPrefix ++
|
||||
[?CONF_NS, "password_based:built_in_database", "upload_users"]
|
||||
),
|
||||
|
||||
{ok, 200, _} = request(
|
||||
post,
|
||||
uri(PathPrefix ++ [?CONF_NS]),
|
||||
emqx_authn_test_lib:built_in_database_example()
|
||||
),
|
||||
|
||||
{ok, 400, _} = multipart_formdata_request(UploadUri, [], [
|
||||
{ok, 400, _} = multipart_formdata_request(ImportUri, [], []),
|
||||
{ok, 400, _} = multipart_formdata_request(ImportUri, [], [
|
||||
{filenam, "user-credentials.json", <<>>}
|
||||
]),
|
||||
|
||||
|
@ -684,12 +653,12 @@ test_authenticator_upload_users(PathPrefix) ->
|
|||
CSVFileName = filename:join([Dir, <<"data/user-credentials.csv">>]),
|
||||
|
||||
{ok, JSONData} = file:read_file(JSONFileName),
|
||||
{ok, 204, _} = multipart_formdata_request(UploadUri, [], [
|
||||
{ok, 204, _} = multipart_formdata_request(ImportUri, [], [
|
||||
{filename, "user-credentials.json", JSONData}
|
||||
]),
|
||||
|
||||
{ok, CSVData} = file:read_file(CSVFileName),
|
||||
{ok, 204, _} = multipart_formdata_request(UploadUri, [], [
|
||||
{ok, 204, _} = multipart_formdata_request(ImportUri, [], [
|
||||
{filename, "user-credentials.csv", CSVData}
|
||||
]).
|
||||
|
||||
|
|
|
@ -228,14 +228,6 @@ t_import_users(_) ->
|
|||
Config = Config0#{password_hash_algorithm => #{name => sha256}},
|
||||
{ok, State} = emqx_authn_mnesia:create(?AUTHN_ID, Config),
|
||||
|
||||
?assertEqual(
|
||||
ok,
|
||||
emqx_authn_mnesia:import_users(
|
||||
sample_filename(<<"user-credentials.json">>),
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
ok,
|
||||
emqx_authn_mnesia:import_users(
|
||||
|
@ -244,14 +236,6 @@ t_import_users(_) ->
|
|||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
ok,
|
||||
emqx_authn_mnesia:import_users(
|
||||
sample_filename(<<"user-credentials.csv">>),
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
ok,
|
||||
emqx_authn_mnesia:import_users(
|
||||
|
@ -260,14 +244,6 @@ t_import_users(_) ->
|
|||
)
|
||||
),
|
||||
|
||||
?assertMatch(
|
||||
{error, {unsupported_file_format, _}},
|
||||
emqx_authn_mnesia:import_users(
|
||||
<<"/file/with/unknown.extension">>,
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertMatch(
|
||||
{error, {unsupported_file_format, _}},
|
||||
emqx_authn_mnesia:import_users(
|
||||
|
@ -276,14 +252,6 @@ t_import_users(_) ->
|
|||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{error, unknown_file_format},
|
||||
emqx_authn_mnesia:import_users(
|
||||
<<"/file/with/no/extension">>,
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{error, unknown_file_format},
|
||||
emqx_authn_mnesia:import_users(
|
||||
|
@ -292,22 +260,6 @@ t_import_users(_) ->
|
|||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{error, enoent},
|
||||
emqx_authn_mnesia:import_users(
|
||||
<<"/file/that/not/exist.json">>,
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{error, bad_format},
|
||||
emqx_authn_mnesia:import_users(
|
||||
sample_filename(<<"user-credentials-malformed-0.json">>),
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{error, bad_format},
|
||||
emqx_authn_mnesia:import_users(
|
||||
|
@ -316,14 +268,6 @@ t_import_users(_) ->
|
|||
)
|
||||
),
|
||||
|
||||
?assertMatch(
|
||||
{error, {_, invalid_json}},
|
||||
emqx_authn_mnesia:import_users(
|
||||
sample_filename(<<"user-credentials-malformed-1.json">>),
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertMatch(
|
||||
{error, {_, invalid_json}},
|
||||
emqx_authn_mnesia:import_users(
|
||||
|
@ -332,14 +276,6 @@ t_import_users(_) ->
|
|||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{error, bad_format},
|
||||
emqx_authn_mnesia:import_users(
|
||||
sample_filename(<<"user-credentials-malformed.csv">>),
|
||||
State
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{error, bad_format},
|
||||
emqx_authn_mnesia:import_users(
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
emqx_gateway_api_authn_user_upload {
|
||||
|
||||
upload_users {
|
||||
desc {
|
||||
en: """Upload file with users into the gateway authentication"""
|
||||
zh: """将带有用户的文件上传到网关身份验证中。"""
|
||||
}
|
||||
}
|
||||
|
||||
upload_listener_users {
|
||||
desc {
|
||||
en: """Upload file with users into listener-specific authentication"""
|
||||
zh: """将带有用户的文件上传到特定于侦听器的身份验证中。"""
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -46,8 +46,7 @@
|
|||
-export([
|
||||
authn/2,
|
||||
users/2,
|
||||
users_insta/2,
|
||||
import_users/2
|
||||
users_insta/2
|
||||
]).
|
||||
|
||||
%% internal export for emqx_gateway_api_listeners module
|
||||
|
@ -64,8 +63,7 @@ paths() ->
|
|||
[
|
||||
"/gateway/:name/authentication",
|
||||
"/gateway/:name/authentication/users",
|
||||
"/gateway/:name/authentication/users/:uid",
|
||||
"/gateway/:name/authentication/import_users"
|
||||
"/gateway/:name/authentication/users/:uid"
|
||||
].
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -160,32 +158,6 @@ users_insta(delete, #{bindings := #{name := Name0, uid := UserId}}) ->
|
|||
emqx_authn_api:delete_user(ChainName, AuthId, UserId)
|
||||
end).
|
||||
|
||||
import_users(post, #{
|
||||
bindings := #{name := Name0},
|
||||
body := Body
|
||||
}) ->
|
||||
with_authn(Name0, fun(
|
||||
_GwName,
|
||||
#{
|
||||
id := AuthId,
|
||||
chain_name := ChainName
|
||||
}
|
||||
) ->
|
||||
case maps:get(<<"filename">>, Body, undefined) of
|
||||
undefined ->
|
||||
emqx_authn_api:serialize_error({missing_parameter, filename});
|
||||
Filename ->
|
||||
case
|
||||
emqx_authentication:import_users(
|
||||
ChainName, AuthId, Filename
|
||||
)
|
||||
of
|
||||
ok -> {204};
|
||||
{error, Reason} -> emqx_authn_api:serialize_error(Reason)
|
||||
end
|
||||
end
|
||||
end).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Utils
|
||||
|
||||
|
@ -326,21 +298,6 @@ schema("/gateway/:name/authentication/users/:uid") ->
|
|||
responses =>
|
||||
?STANDARD_RESP(#{204 => <<"User Deleted">>})
|
||||
}
|
||||
};
|
||||
schema("/gateway/:name/authentication/import_users") ->
|
||||
#{
|
||||
'operationId' => import_users,
|
||||
post =>
|
||||
#{
|
||||
desc => ?DESC(import_users),
|
||||
parameters => params_gateway_name_in_path(),
|
||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||
ref(emqx_authn_api, request_import_users),
|
||||
emqx_authn_api:request_import_users_examples()
|
||||
),
|
||||
responses =>
|
||||
?STANDARD_RESP(#{204 => <<"Imported">>})
|
||||
}
|
||||
}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
%% limitations under the License.
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
-module(emqx_gateway_api_authn_user_upload).
|
||||
-module(emqx_gateway_api_authn_user_import).
|
||||
|
||||
-behaviour(minirest_api).
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
|||
]
|
||||
).
|
||||
|
||||
%% minirest/dashbaord_swagger behaviour callbacks
|
||||
%% minirest/dashboard_swagger behaviour callbacks
|
||||
-export([
|
||||
api_spec/0,
|
||||
paths/0,
|
||||
|
@ -41,8 +41,8 @@
|
|||
|
||||
%% http handlers
|
||||
-export([
|
||||
upload_users/2,
|
||||
upload_listener_users/2
|
||||
import_users/2,
|
||||
import_listener_users/2
|
||||
]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -54,14 +54,14 @@ api_spec() ->
|
|||
|
||||
paths() ->
|
||||
[
|
||||
"/gateway/:name/authentication/upload_users",
|
||||
"/gateway/:name/listeners/:id/authentication/upload_users"
|
||||
"/gateway/:name/authentication/import_users",
|
||||
"/gateway/:name/listeners/:id/authentication/import_users"
|
||||
].
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% http handlers
|
||||
|
||||
upload_users(post, #{
|
||||
import_users(post, #{
|
||||
bindings := #{name := Name0},
|
||||
body := Body
|
||||
}) ->
|
||||
|
@ -88,7 +88,7 @@ upload_users(post, #{
|
|||
end
|
||||
end).
|
||||
|
||||
upload_listener_users(post, #{
|
||||
import_listener_users(post, #{
|
||||
bindings := #{name := Name0, id := Id},
|
||||
body := Body
|
||||
}) ->
|
||||
|
@ -117,12 +117,12 @@ upload_listener_users(post, #{
|
|||
%% Swagger defines
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
schema("/gateway/:name/authentication/upload_users") ->
|
||||
schema("/gateway/:name/authentication/import_users") ->
|
||||
#{
|
||||
'operationId' => upload_users,
|
||||
'operationId' => import_users,
|
||||
post =>
|
||||
#{
|
||||
desc => ?DESC(upload_users),
|
||||
desc => ?DESC(emqx_gateway_api_authn, import_users),
|
||||
parameters => params_gateway_name_in_path(),
|
||||
'requestBody' => #{
|
||||
content => #{
|
||||
|
@ -137,12 +137,12 @@ schema("/gateway/:name/authentication/upload_users") ->
|
|||
?STANDARD_RESP(#{204 => <<"Imported">>})
|
||||
}
|
||||
};
|
||||
schema("/gateway/:name/listeners/:id/authentication/upload_users") ->
|
||||
schema("/gateway/:name/listeners/:id/authentication/import_users") ->
|
||||
#{
|
||||
'operationId' => upload_listener_users,
|
||||
'operationId' => import_listener_users,
|
||||
post =>
|
||||
#{
|
||||
desc => ?DESC(upload_listener_users),
|
||||
desc => ?DESC(emqx_gateway_api_listeners, import_users),
|
||||
parameters => params_gateway_name_in_path() ++
|
||||
params_listener_id_in_path(),
|
||||
'requestBody' => #{
|
|
@ -54,8 +54,7 @@
|
|||
listeners_insta/2,
|
||||
listeners_insta_authn/2,
|
||||
users/2,
|
||||
users_insta/2,
|
||||
import_users/2
|
||||
users_insta/2
|
||||
]).
|
||||
|
||||
%% RPC
|
||||
|
@ -74,8 +73,7 @@ paths() ->
|
|||
"/gateway/:name/listeners/:id",
|
||||
"/gateway/:name/listeners/:id/authentication",
|
||||
"/gateway/:name/listeners/:id/authentication/users",
|
||||
"/gateway/:name/listeners/:id/authentication/users/:uid",
|
||||
"/gateway/:name/listeners/:id/authentication/import_users"
|
||||
"/gateway/:name/listeners/:id/authentication/users/:uid"
|
||||
].
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -239,30 +237,6 @@ users_insta(delete, #{bindings := #{name := Name0, id := Id, uid := UserId}}) ->
|
|||
end
|
||||
).
|
||||
|
||||
import_users(post, #{
|
||||
bindings := #{name := Name0, id := Id},
|
||||
body := Body
|
||||
}) ->
|
||||
with_listener_authn(
|
||||
Name0,
|
||||
Id,
|
||||
fun(_GwName, #{id := AuthId, chain_name := ChainName}) ->
|
||||
case maps:get(<<"filename">>, Body, undefined) of
|
||||
undefined ->
|
||||
emqx_authn_api:serialize_error({missing_parameter, filename});
|
||||
Filename ->
|
||||
case
|
||||
emqx_authentication:import_users(
|
||||
ChainName, AuthId, Filename
|
||||
)
|
||||
of
|
||||
ok -> {204};
|
||||
{error, Reason} -> emqx_authn_api:serialize_error(Reason)
|
||||
end
|
||||
end
|
||||
end
|
||||
).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Utils
|
||||
|
||||
|
@ -549,22 +523,6 @@ schema("/gateway/:name/listeners/:id/authentication/users/:uid") ->
|
|||
responses =>
|
||||
?STANDARD_RESP(#{204 => <<"Deleted">>})
|
||||
}
|
||||
};
|
||||
schema("/gateway/:name/listeners/:id/authentication/import_users") ->
|
||||
#{
|
||||
'operationId' => import_users,
|
||||
post =>
|
||||
#{
|
||||
desc => ?DESC(import_users),
|
||||
parameters => params_gateway_name_in_path() ++
|
||||
params_listener_id_in_path(),
|
||||
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
|
||||
ref(emqx_authn_api, request_import_users),
|
||||
emqx_authn_api:request_import_users_examples()
|
||||
),
|
||||
responses =>
|
||||
?STANDARD_RESP(#{204 => <<"Imported">>})
|
||||
}
|
||||
}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -312,20 +312,20 @@ t_authn_data_mgmt(_) ->
|
|||
"/gateway/stomp/authentication/users"
|
||||
),
|
||||
|
||||
UploadUri = emqx_dashboard_api_test_helpers:uri(
|
||||
["gateway", "stomp", "authentication", "upload_users"]
|
||||
ImportUri = emqx_dashboard_api_test_helpers:uri(
|
||||
["gateway", "stomp", "authentication", "import_users"]
|
||||
),
|
||||
|
||||
Dir = code:lib_dir(emqx_authn, test),
|
||||
JSONFileName = filename:join([Dir, <<"data/user-credentials.json">>]),
|
||||
{ok, JSONData} = file:read_file(JSONFileName),
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(UploadUri, [], [
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(ImportUri, [], [
|
||||
{filename, "user-credentials.json", JSONData}
|
||||
]),
|
||||
|
||||
CSVFileName = filename:join([Dir, <<"data/user-credentials.csv">>]),
|
||||
{ok, CSVData} = file:read_file(CSVFileName),
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(UploadUri, [], [
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(ImportUri, [], [
|
||||
{filename, "user-credentials.csv", CSVData}
|
||||
]),
|
||||
|
||||
|
@ -469,20 +469,20 @@ t_listeners_authn_data_mgmt(_) ->
|
|||
Path ++ "/users"
|
||||
),
|
||||
|
||||
UploadUri = emqx_dashboard_api_test_helpers:uri(
|
||||
["gateway", "stomp", "listeners", "stomp:tcp:def", "authentication", "upload_users"]
|
||||
ImportUri = emqx_dashboard_api_test_helpers:uri(
|
||||
["gateway", "stomp", "listeners", "stomp:tcp:def", "authentication", "import_users"]
|
||||
),
|
||||
|
||||
Dir = code:lib_dir(emqx_authn, test),
|
||||
JSONFileName = filename:join([Dir, <<"data/user-credentials.json">>]),
|
||||
{ok, JSONData} = file:read_file(JSONFileName),
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(UploadUri, [], [
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(ImportUri, [], [
|
||||
{filename, "user-credentials.json", JSONData}
|
||||
]),
|
||||
|
||||
CSVFileName = filename:join([Dir, <<"data/user-credentials.csv">>]),
|
||||
{ok, CSVData} = file:read_file(CSVFileName),
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(UploadUri, [], [
|
||||
{ok, 204, _} = emqx_dashboard_api_test_helpers:multipart_formdata_request(ImportUri, [], [
|
||||
{filename, "user-credentials.csv", CSVData}
|
||||
]),
|
||||
|
||||
|
|
Loading…
Reference in New Issue