fix: allow viewers to change their own passwords
This commit is contained in:
parent
4c0bec1866
commit
2388d36b09
|
@ -248,8 +248,8 @@ clean_expired_jwt(Now) ->
|
||||||
|
|
||||||
-if(?EMQX_RELEASE_EDITION == ee).
|
-if(?EMQX_RELEASE_EDITION == ee).
|
||||||
check_rbac(Req, JWT) ->
|
check_rbac(Req, JWT) ->
|
||||||
#?ADMIN_JWT{exptime = _ExpTime, extra = Extra, username = _Username} = JWT,
|
#?ADMIN_JWT{exptime = _ExpTime, extra = Extra, username = Username} = JWT,
|
||||||
case emqx_dashboard_rbac:check_rbac(Req, Extra) of
|
case emqx_dashboard_rbac:check_rbac(Req, Username, Extra) of
|
||||||
true ->
|
true ->
|
||||||
save_new_jwt(JWT);
|
save_new_jwt(JWT);
|
||||||
_ ->
|
_ ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_dashboard_rbac, [
|
{application, emqx_dashboard_rbac, [
|
||||||
{description, "EMQX Dashboard RBAC"},
|
{description, "EMQX Dashboard RBAC"},
|
||||||
{vsn, "0.1.0"},
|
{vsn, "0.1.1"},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [
|
{applications, [
|
||||||
kernel,
|
kernel,
|
||||||
|
|
|
@ -6,18 +6,18 @@
|
||||||
|
|
||||||
-include_lib("emqx_dashboard/include/emqx_dashboard.hrl").
|
-include_lib("emqx_dashboard/include/emqx_dashboard.hrl").
|
||||||
|
|
||||||
-export([check_rbac/2, role/1, valid_role/1]).
|
-export([check_rbac/3, role/1, valid_role/1]).
|
||||||
|
|
||||||
-dialyzer({nowarn_function, role/1}).
|
-dialyzer({nowarn_function, role/1}).
|
||||||
%%=====================================================================
|
%%=====================================================================
|
||||||
%% API
|
%% API
|
||||||
check_rbac(Req, Extra) ->
|
check_rbac(Req, Username, Extra) ->
|
||||||
Role = role(Extra),
|
Role = role(Extra),
|
||||||
Method = cowboy_req:method(Req),
|
Method = cowboy_req:method(Req),
|
||||||
AbsPath = cowboy_req:path(Req),
|
AbsPath = cowboy_req:path(Req),
|
||||||
case emqx_dashboard_swagger:get_relative_uri(AbsPath) of
|
case emqx_dashboard_swagger:get_relative_uri(AbsPath) of
|
||||||
{ok, Path} ->
|
{ok, Path} ->
|
||||||
check_rbac(Role, Method, Path);
|
check_rbac(Role, Method, Path, Username);
|
||||||
_ ->
|
_ ->
|
||||||
false
|
false
|
||||||
end.
|
end.
|
||||||
|
@ -41,14 +41,21 @@ valid_role(Role) ->
|
||||||
{error, <<"Role does not exist">>}
|
{error, <<"Role does not exist">>}
|
||||||
end.
|
end.
|
||||||
%% ===================================================================
|
%% ===================================================================
|
||||||
check_rbac(?ROLE_SUPERUSER, _, _) ->
|
check_rbac(?ROLE_SUPERUSER, _, _, _) ->
|
||||||
true;
|
true;
|
||||||
check_rbac(?ROLE_VIEWER, <<"GET">>, _) ->
|
check_rbac(?ROLE_VIEWER, <<"GET">>, _, _) ->
|
||||||
true;
|
true;
|
||||||
%% this API is a special case
|
%% everyone should allow to logout
|
||||||
check_rbac(?ROLE_VIEWER, <<"POST">>, <<"/logout">>) ->
|
check_rbac(?ROLE_VIEWER, <<"POST">>, <<"/logout">>, _) ->
|
||||||
true;
|
true;
|
||||||
check_rbac(_, _, _) ->
|
%% viewer should allow to change self password,
|
||||||
|
%% superuser should allow to change any user
|
||||||
|
check_rbac(?ROLE_VIEWER, <<"POST">>, <<"/users/", SubPath/binary>>, Username) ->
|
||||||
|
case binary:split(SubPath, <<"/">>, [global]) of
|
||||||
|
[Username, <<"change_pwd">>] -> true;
|
||||||
|
_ -> false
|
||||||
|
end;
|
||||||
|
check_rbac(_, _, _, _) ->
|
||||||
false.
|
false.
|
||||||
|
|
||||||
role_list() ->
|
role_list() ->
|
||||||
|
|
|
@ -160,6 +160,34 @@ t_login_out(_) ->
|
||||||
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
t_change_pwd(_) ->
|
||||||
|
Viewer1 = <<"viewer1">>,
|
||||||
|
Viewer2 = <<"viewer2">>,
|
||||||
|
SuperUser = <<"super_user">>,
|
||||||
|
Password = <<"public_www1">>,
|
||||||
|
Desc = <<"desc">>,
|
||||||
|
{ok, _} = emqx_dashboard_admin:add_user(Viewer1, Password, ?ROLE_VIEWER, Desc),
|
||||||
|
{ok, _} = emqx_dashboard_admin:add_user(Viewer2, Password, ?ROLE_VIEWER, Desc),
|
||||||
|
{ok, _} = emqx_dashboard_admin:add_user(SuperUser, Password, ?ROLE_SUPERUSER, Desc),
|
||||||
|
{ok, ?ROLE_VIEWER, Viewer1Token} = emqx_dashboard_admin:sign_token(Viewer1, Password),
|
||||||
|
{ok, ?ROLE_SUPERUSER, SuperToken} = emqx_dashboard_admin:sign_token(SuperUser, Password),
|
||||||
|
%% viewer can change own password
|
||||||
|
?assertEqual({ok, Viewer1}, change_pwd(Viewer1Token, Viewer1)),
|
||||||
|
%% viewer can't change other's password
|
||||||
|
?assertEqual({error, unauthorized_role}, change_pwd(Viewer1Token, Viewer2)),
|
||||||
|
?assertEqual({error, unauthorized_role}, change_pwd(Viewer1Token, SuperUser)),
|
||||||
|
%% superuser can change other's password
|
||||||
|
?assertEqual({ok, SuperUser}, change_pwd(SuperToken, Viewer1)),
|
||||||
|
?assertEqual({ok, SuperUser}, change_pwd(SuperToken, Viewer2)),
|
||||||
|
?assertEqual({ok, SuperUser}, change_pwd(SuperToken, SuperUser)),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
change_pwd(Token, Username) ->
|
||||||
|
Path = "/users/" ++ binary_to_list(Username) ++ "/change_pwd",
|
||||||
|
Path1 = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri(Path)),
|
||||||
|
Req = #{method => <<"POST">>, path => Path1},
|
||||||
|
emqx_dashboard_admin:verify_token(Req, Token).
|
||||||
|
|
||||||
add_default_superuser() ->
|
add_default_superuser() ->
|
||||||
{ok, _NewUser} = emqx_dashboard_admin:add_user(
|
{ok, _NewUser} = emqx_dashboard_admin:add_user(
|
||||||
?DEFAULT_SUPERUSER,
|
?DEFAULT_SUPERUSER,
|
||||||
|
|
Loading…
Reference in New Issue