chore(rbac): fix CI errors & update change

This commit is contained in:
firest 2023-10-25 12:02:40 +08:00
parent ec41479633
commit 4ba34f8f3e
5 changed files with 114 additions and 8 deletions

View File

@ -59,12 +59,8 @@ valid_role(Type, Role) ->
%% =================================================================== %% ===================================================================
check_rbac(?ROLE_SUPERUSER, _, _, _) -> check_rbac(?ROLE_SUPERUSER, _, _, _) ->
true; true;
%%check_rbac(?ROLE_API_SUPERUSER, _, _, _) ->
%% true;
check_rbac(?ROLE_VIEWER, <<"GET">>, _, _) -> check_rbac(?ROLE_VIEWER, <<"GET">>, _, _) ->
true; true;
%%check_rbac(?ROLE_API_VIEWER, <<"GET">>, _, _) ->
%% true;
check_rbac(?ROLE_API_PUBLISHER, <<"POST">>, <<"/publish">>, _) -> check_rbac(?ROLE_API_PUBLISHER, <<"POST">>, <<"/publish">>, _) ->
true; true;
check_rbac(?ROLE_API_PUBLISHER, <<"POST">>, <<"/publish/bulk">>, _) -> check_rbac(?ROLE_API_PUBLISHER, <<"POST">>, <<"/publish/bulk">>, _) ->

View File

@ -38,7 +38,7 @@
-export([authorize/4]). -export([authorize/4]).
-export([post_config_update/5]). -export([post_config_update/5]).
-export([backup_tables/0]). -export([backup_tables/0, validate_mnesia_backup/1]).
%% Internal exports (RPC) %% Internal exports (RPC)
-export([ -export([
@ -82,6 +82,22 @@ mnesia(boot) ->
backup_tables() -> [?APP]. backup_tables() -> [?APP].
validate_mnesia_backup({schema, _Tab, CreateList} = Schema) ->
case emqx_mgmt_data_backup:default_validate_mnesia_backup(Schema) of
ok ->
ok;
_ ->
case proplists:get_value(attributes, CreateList) of
%% Since v5.4.0 the `desc` has changed to `extra`
[name, api_key, api_secret_hash, enable, desc, expired_at, created_at] ->
ok;
Fields ->
{error, {unknow_fields, Fields}}
end
end;
validate_mnesia_backup(_Other) ->
ok.
post_config_update([api_key], _Req, NewConf, _OldConf, _AppEnvs) -> post_config_update([api_key], _Req, NewConf, _OldConf, _AppEnvs) ->
#{bootstrap_file := File} = NewConf, #{bootstrap_file := File} = NewConf,
case init_bootstrap_file(File) of case init_bootstrap_file(File) of

View File

@ -39,7 +39,7 @@ groups() ->
[ [
{parallel, [parallel], [t_create, t_update, t_delete, t_authorize, t_create_unexpired_app]}, {parallel, [parallel], [t_create, t_update, t_delete, t_authorize, t_create_unexpired_app]},
{parallel, [parallel], ?EE_CASES}, {parallel, [parallel], ?EE_CASES},
{sequence, [], [t_bootstrap_file, t_create_failed]} {sequence, [], [t_bootstrap_file, t_bootstrap_file_with_role, t_create_failed]}
]. ].
init_per_suite(Config) -> init_per_suite(Config) ->
@ -86,6 +86,92 @@ t_bootstrap_file(_) ->
update_file(<<>>), update_file(<<>>),
ok. ok.
-if(?EMQX_RELEASE_EDITION == ee).
t_bootstrap_file_with_role(_) ->
Search = fun(Name) ->
lists:search(
fun(#{api_key := AppName}) ->
AppName =:= Name
end,
emqx_mgmt_auth:list()
)
end,
Bin = <<"role-1:role-1:viewer\nrole-2:role-2:administrator\nrole-3:role-3">>,
File = "./bootstrap_api_keys.txt",
ok = file:write_file(File, Bin),
update_file(File),
?assertMatch(
{value, #{api_key := <<"role-1">>, role := <<"viewer">>}},
Search(<<"role-1">>)
),
?assertMatch(
{value, #{api_key := <<"role-2">>, role := <<"administrator">>}},
Search(<<"role-2">>)
),
?assertMatch(
{value, #{api_key := <<"role-3">>, role := <<"administrator">>}},
Search(<<"role-3">>)
),
%% bad role
BadBin = <<"role-4:secret-11:bad\n">>,
ok = file:write_file(File, BadBin),
update_file(File),
?assertEqual(
false,
Search(<<"role-4">>)
),
ok.
-else.
t_bootstrap_file_with_role(_) ->
Search = fun(Name) ->
lists:search(
fun(#{api_key := AppName}) ->
AppName =:= Name
end,
emqx_mgmt_auth:list()
)
end,
Bin = <<"role-1:role-1:administrator\nrole-2:role-2">>,
File = "./bootstrap_api_keys.txt",
ok = file:write_file(File, Bin),
update_file(File),
?assertMatch(
{value, #{api_key := <<"role-1">>, role := <<"administrator">>}},
Search(<<"role-1">>)
),
?assertMatch(
{value, #{api_key := <<"role-2">>, role := <<"administrator">>}},
Search(<<"role-2">>)
),
%% only administrator
OtherRoleBin = <<"role-3:role-3:viewer\n">>,
ok = file:write_file(File, OtherRoleBin),
update_file(File),
?assertEqual(
false,
Search(<<"role-3">>)
),
%% bad role
BadBin = <<"role-4:secret-11:bad\n">>,
ok = file:write_file(File, BadBin),
update_file(File),
?assertEqual(
false,
Search(<<"role-4">>)
),
ok.
-endif.
auth_authorize(Path, Key, Secret) -> auth_authorize(Path, Key, Secret) ->
FakePath = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri("/fake")), FakePath = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri("/fake")),
FakeReq = #{method => <<"GET">>, path => FakePath}, FakeReq = #{method => <<"GET">>, path => FakePath},

View File

@ -0,0 +1,5 @@
Improve the format for the REST API key bootstrap file to support initialize key with a role.
The new form is:`api_key:api_secret:role`.
`role` is optional and its default value is `administrator`.

View File

@ -9,8 +9,11 @@ api_key.label:
bootstrap_file.desc: bootstrap_file.desc:
"""The bootstrap file provides API keys for EMQX. """The bootstrap file provides API keys for EMQX.
EMQX will load these keys on startup to authorize API requests. EMQX will load these keys on startup to authorize API requests.
It contains key-value pairs in the format:`api_key:api_secret`. It contains colon-separated values in the format: `api_key:api_secret:role`.
Each line specifies an API key and its associated secret.""" Each line specifies an API key and its associated secret, and the role of this key.
The 'role' part should be the pre-defined access scope group name,
for example, `administrator` or `viewer`.
The 'role' is introduced in 5.4, to be backward compatible, if it is missing, the key is implicitly granted `administrator` role."""
bootstrap_file.label: bootstrap_file.label:
"""Initialize api_key file.""" """Initialize api_key file."""