fix(emqx_management): Allow to specify credential type during import
This commit is contained in:
parent
830cdffe16
commit
2c029c0607
|
@ -127,7 +127,7 @@ import(_Bindings, Params) ->
|
||||||
|
|
||||||
do_import(Filename) ->
|
do_import(Filename) ->
|
||||||
FullFilename = filename:join([emqx:get_env(data_dir), Filename]),
|
FullFilename = filename:join([emqx:get_env(data_dir), Filename]),
|
||||||
emqx_mgmt_data_backup:import(FullFilename).
|
emqx_mgmt_data_backup:import(FullFilename, "{}").
|
||||||
|
|
||||||
download(#{filename := Filename}, _Params) ->
|
download(#{filename := Filename}, _Params) ->
|
||||||
FullFilename = filename:join([emqx:get_env(data_dir), Filename]),
|
FullFilename = filename:join([emqx:get_env(data_dir), Filename]),
|
||||||
|
|
|
@ -562,7 +562,9 @@ data(["export"]) ->
|
||||||
end;
|
end;
|
||||||
|
|
||||||
data(["import", Filename]) ->
|
data(["import", Filename]) ->
|
||||||
case emqx_mgmt_data_backup:import(Filename) of
|
data(["import", Filename, "--env", "{}"]);
|
||||||
|
data(["import", Filename, "--env", Env]) ->
|
||||||
|
case emqx_mgmt_data_backup:import(Filename, Env) of
|
||||||
ok ->
|
ok ->
|
||||||
emqx_ctl:print("The emqx data has been imported successfully.~n");
|
emqx_ctl:print("The emqx data has been imported successfully.~n");
|
||||||
{error, import_failed} ->
|
{error, import_failed} ->
|
||||||
|
@ -574,7 +576,8 @@ data(["import", Filename]) ->
|
||||||
end;
|
end;
|
||||||
|
|
||||||
data(_) ->
|
data(_) ->
|
||||||
emqx_ctl:usage([{"data import <File>", "Import data from the specified file"},
|
emqx_ctl:usage([{"data import <File> [--env '<json>']",
|
||||||
|
"Import data from the specified file, possibly with overrides"},
|
||||||
{"data export", "Export data"}]).
|
{"data export", "Export data"}]).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([ export/0
|
-export([ export/0
|
||||||
, import/1
|
, import/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -464,7 +464,7 @@ do_import_auth_mnesia_4_2(Auths) ->
|
||||||
CreatedAt = erlang:system_time(millisecond),
|
CreatedAt = erlang:system_time(millisecond),
|
||||||
lists:foreach(fun(#{<<"login">> := Login,
|
lists:foreach(fun(#{<<"login">> := Login,
|
||||||
<<"password">> := Password}) ->
|
<<"password">> := Password}) ->
|
||||||
mnesia:dirty_write({emqx_user, {username, Login}, Password, CreatedAt})
|
mnesia:dirty_write({emqx_user, {get_old_type(), Login}, Password, CreatedAt})
|
||||||
end, Auths)
|
end, Auths)
|
||||||
end.
|
end.
|
||||||
-endif.
|
-endif.
|
||||||
|
@ -476,7 +476,7 @@ do_import_auth_mnesia_by_old_data(Auths) ->
|
||||||
CreatedAt = erlang:system_time(millisecond),
|
CreatedAt = erlang:system_time(millisecond),
|
||||||
lists:foreach(fun(#{<<"login">> := Login,
|
lists:foreach(fun(#{<<"login">> := Login,
|
||||||
<<"password">> := Password}) ->
|
<<"password">> := Password}) ->
|
||||||
mnesia:dirty_write({emqx_user, {username, Login}, base64:decode(Password), CreatedAt})
|
mnesia:dirty_write({emqx_user, {get_old_type(), Login}, base64:decode(Password), CreatedAt})
|
||||||
end, Auths)
|
end, Auths)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -506,7 +506,7 @@ do_import_acl_mnesia_by_old_data(Acls) ->
|
||||||
true -> allow;
|
true -> allow;
|
||||||
false -> deny
|
false -> deny
|
||||||
end,
|
end,
|
||||||
mnesia:dirty_write({emqx_acl, {{username, Login}, Topic}, any_to_atom(Action), Allow1, CreatedAt})
|
mnesia:dirty_write({emqx_acl, {{get_old_type(), Login}, Topic}, any_to_atom(Action), Allow1, CreatedAt})
|
||||||
end, Acls)
|
end, Acls)
|
||||||
end.
|
end.
|
||||||
do_import_acl_mnesia(Acls) ->
|
do_import_acl_mnesia(Acls) ->
|
||||||
|
@ -614,11 +614,14 @@ do_export_extra_data() ->
|
||||||
do_export_extra_data() -> [].
|
do_export_extra_data() -> [].
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
import(Filename) ->
|
import(Filename, OverridesJson) ->
|
||||||
case file:read_file(Filename) of
|
case file:read_file(Filename) of
|
||||||
{ok, Json} ->
|
{ok, Json} ->
|
||||||
Data = emqx_json:decode(Json, [return_maps]),
|
Imported = emqx_json:decode(Json, [return_maps]),
|
||||||
|
Overrides = emqx_json:decode(OverridesJson, [return_maps]),
|
||||||
|
Data = maps:merge(Imported, Overrides),
|
||||||
Version = to_version(maps:get(<<"version">>, Data)),
|
Version = to_version(maps:get(<<"version">>, Data)),
|
||||||
|
read_global_auth_type(Data, Version),
|
||||||
case lists:member(Version, ?VERSIONS) of
|
case lists:member(Version, ?VERSIONS) of
|
||||||
true ->
|
true ->
|
||||||
try
|
try
|
||||||
|
@ -664,3 +667,27 @@ covert_empty_headers(Headers) ->
|
||||||
Other -> Other
|
Other -> Other
|
||||||
end.
|
end.
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
read_global_auth_type(Data, Version) when Version =:= "4.0" orelse
|
||||||
|
Version =:= "4.1" orelse
|
||||||
|
Version =:= "4.2" ->
|
||||||
|
case Data of
|
||||||
|
#{<<"auth.mnesia.as">> := <<"username">>} -> application:set_env(emqx_auth_mnesia, as, username);
|
||||||
|
#{<<"auth.mnesia.as">> := <<"clientid">>} -> application:set_env(emqx_auth_mnesia, as, clientid);
|
||||||
|
_ ->
|
||||||
|
logger:error("While importing data from EMQX versions prior to 4.3 "
|
||||||
|
"it is necessary to specify the value of \"auth.mnesia.as\" parameter "
|
||||||
|
"as it was configured in etc/plugins/emqx_auth_mnesia.conf.\n"
|
||||||
|
"Use the following command to import data:\n"
|
||||||
|
" $ emqx_ctl data import <filename> --env '{\"auth.mnesia.as\":\"username\"}'\n"
|
||||||
|
"or\n"
|
||||||
|
" $ emqx_ctl data import <filename> --env '{\"auth.mnesia.as\":\"clientid\"}'",
|
||||||
|
[]),
|
||||||
|
error(import_failed)
|
||||||
|
end;
|
||||||
|
read_global_auth_type(_Data, _Version) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
get_old_type() ->
|
||||||
|
{ok, Type} = application:get_env(emqx_auth_mnesia, as),
|
||||||
|
Type.
|
||||||
|
|
|
@ -26,20 +26,32 @@
|
||||||
-include_lib("emqx_auth_mnesia/include/emqx_auth_mnesia.hrl").
|
-include_lib("emqx_auth_mnesia/include/emqx_auth_mnesia.hrl").
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
|
[{group, Id} || {Id, _, _} <- groups()].
|
||||||
|
|
||||||
|
groups() ->
|
||||||
|
[{username, [], cases()}, {clientid, [], cases()}].
|
||||||
|
|
||||||
|
cases() ->
|
||||||
[t_import_4_2, t_import_4_1].
|
[t_import_4_2, t_import_4_1].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_ct_helpers:start_apps([emqx_management, emqx_dashboard, emqx_auth_mnesia]),
|
emqx_ct_helpers:start_apps([emqx_management, emqx_dashboard, emqx_auth_mnesia]),
|
||||||
ekka_mnesia:start(),
|
ekka_mnesia:start(),
|
||||||
emqx_mgmt_auth:mnesia(boot),
|
emqx_mgmt_auth:mnesia(boot),
|
||||||
mnesia:clear_table(emqx_acl),
|
|
||||||
mnesia:clear_table(emqx_user),
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
emqx_ct_helpers:stop_apps([emqx_modules, emqx_management, emqx_dashboard, emqx_management, emqx_auth_mnesia]),
|
emqx_ct_helpers:stop_apps([emqx_modules, emqx_management, emqx_dashboard, emqx_management, emqx_auth_mnesia]),
|
||||||
ekka_mnesia:ensure_stopped().
|
ekka_mnesia:ensure_stopped().
|
||||||
|
|
||||||
|
init_per_group(username, Config) ->
|
||||||
|
[{cred_type, username} | Config];
|
||||||
|
init_per_group(clientid, Config) ->
|
||||||
|
[{cred_type, clientid} | Config].
|
||||||
|
|
||||||
|
end_per_group(_, Config) ->
|
||||||
|
Config.
|
||||||
|
|
||||||
init_per_testcase(_, Config) ->
|
init_per_testcase(_, Config) ->
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
|
@ -55,26 +67,30 @@ t_import_4_1(Config) ->
|
||||||
test_import(Config, "v4.1.json").
|
test_import(Config, "v4.1.json").
|
||||||
|
|
||||||
test_import(Config, File) ->
|
test_import(Config, File) ->
|
||||||
|
Type = proplists:get_value(cred_type, Config),
|
||||||
|
mnesia:clear_table(emqx_acl),
|
||||||
|
mnesia:clear_table(emqx_user),
|
||||||
Filename = filename:join(proplists:get_value(data_dir, Config), File),
|
Filename = filename:join(proplists:get_value(data_dir, Config), File),
|
||||||
?assertMatch(ok, emqx_mgmt_data_backup:import(Filename)),
|
Overrides = emqx_json:encode(#{<<"auth.mnesia.as">> => atom_to_binary(Type)}),
|
||||||
|
?assertMatch(ok, emqx_mgmt_data_backup:import(Filename, Overrides)),
|
||||||
Records = lists:sort(ets:tab2list(emqx_acl)),
|
Records = lists:sort(ets:tab2list(emqx_acl)),
|
||||||
%% Check importing of records related to emqx_auth_mnesia
|
%% Check importing of records related to emqx_auth_mnesia
|
||||||
?assertMatch([#emqx_acl{
|
?assertMatch([#emqx_acl{
|
||||||
filter = {{username,<<"emqx_c">>}, <<"Topic/A">>},
|
filter = {{Type,<<"emqx_c">>}, <<"Topic/A">>},
|
||||||
action = pub,
|
action = pub,
|
||||||
access = allow
|
access = allow
|
||||||
},
|
},
|
||||||
#emqx_acl{
|
#emqx_acl{
|
||||||
filter = {{username,<<"emqx_c">>}, <<"Topic/A">>},
|
filter = {{Type,<<"emqx_c">>}, <<"Topic/A">>},
|
||||||
action = sub,
|
action = sub,
|
||||||
access = allow
|
access = allow
|
||||||
}],
|
}],
|
||||||
lists:sort(Records)),
|
lists:sort(Records)),
|
||||||
?assertMatch([#emqx_user{
|
?assertMatch([#emqx_user{
|
||||||
login = {username, <<"emqx_c">>}
|
login = {Type, <<"emqx_c">>}
|
||||||
}], ets:tab2list(emqx_user)),
|
}], ets:tab2list(emqx_user)),
|
||||||
Req = #{clientid => "blah",
|
Req = #{clientid => <<"blah">>}
|
||||||
username => <<"emqx_c">>,
|
#{Type => <<"emqx_c">>,
|
||||||
password => "emqx_p"
|
password => "emqx_p"
|
||||||
},
|
},
|
||||||
?assertMatch({stop, #{auth_result := success}},
|
?assertMatch({stop, #{auth_result := success}},
|
||||||
|
|
Loading…
Reference in New Issue