fix(RBAC): allow read-only users to logout

This commit is contained in:
firest 2023-09-22 11:06:24 +08:00
parent d6a97987e2
commit 681e57dee6
3 changed files with 34 additions and 7 deletions

View File

@ -28,7 +28,7 @@
-export([error_codes/1, error_codes/2]).
-export([file_schema/1]).
-export([base_path/0]).
-export([relative_uri/1]).
-export([relative_uri/1, get_relative_uri/1]).
-export([compose_filters/2]).
-export([
@ -212,6 +212,12 @@ base_path() ->
relative_uri(Uri) ->
base_path() ++ Uri.
-spec get_relative_uri(uri_string:uri_string()) -> {ok, uri_string:uri_string()} | error.
get_relative_uri(<<?BASE_PATH, Path/binary>>) ->
{ok, Path};
get_relative_uri(_Path) ->
error.
file_schema(FileName) ->
#{
content => #{

View File

@ -12,9 +12,15 @@
%%=====================================================================
%% API
check_rbac(Req, Extra) ->
Method = cowboy_req:method(Req),
Role = role(Extra),
check_rbac_with_method(Role, Method).
Method = cowboy_req:method(Req),
AbsPath = cowboy_req:path(Req),
case emqx_dashboard_swagger:get_relative_uri(AbsPath) of
{ok, Path} ->
check_rbac(Role, Method, Path);
_ ->
false
end.
%% For compatibility
role(#?ADMIN{role = undefined}) ->
@ -35,11 +41,14 @@ valid_role(Role) ->
{error, <<"Role does not exist">>}
end.
%% ===================================================================
check_rbac_with_method(?ROLE_SUPERUSER, _) ->
check_rbac(?ROLE_SUPERUSER, _, _) ->
true;
check_rbac_with_method(?ROLE_VIEWER, <<"GET">>) ->
check_rbac(?ROLE_VIEWER, <<"GET">>, _) ->
true;
check_rbac_with_method(_, _) ->
%% this API is a special case
check_rbac(?ROLE_VIEWER, <<"POST">>, <<"/logout">>) ->
true;
check_rbac(_, _, _) ->
false.
role_list() ->

View File

@ -136,7 +136,8 @@ t_clean_token(_) ->
NewDesc = <<"new desc">>,
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, Desc),
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
FakeReq = #{method => <<"GET">>},
FakePath = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri("/fake")),
FakeReq = #{method => <<"GET">>, path => FakePath},
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
%% change description
{ok, _} = emqx_dashboard_admin:update_user(Username, ?ROLE_SUPERUSER, NewDesc),
@ -148,6 +149,17 @@ t_clean_token(_) ->
{error, not_found} = emqx_dashboard_admin:verify_token(FakeReq, Token),
ok.
t_login_out(_) ->
Username = <<"admin_token">>,
Password = <<"public_www1">>,
Desc = <<"desc">>,
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, Desc),
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
FakePath = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri("/logout")),
FakeReq = #{method => <<"POST">>, path => FakePath},
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
ok.
add_default_superuser() ->
{ok, _NewUser} = emqx_dashboard_admin:add_user(
?DEFAULT_SUPERUSER,