fix(dashbaord): fix test cases to support RBAC
This commit is contained in:
parent
5c31c5ce76
commit
45ccc66474
|
@ -15,10 +15,20 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-define(ADMIN, emqx_admin).
|
-define(ADMIN, emqx_admin).
|
||||||
|
|
||||||
|
%% TODO:
|
||||||
|
%% The predefined roles of the preliminary RBAC implementation,
|
||||||
|
%% these may be removed when developing the full RBAC feature.
|
||||||
|
%% In full RBAC feature, the role may be customised created and deleted,
|
||||||
|
%% a predefined configuration would replace these macros.
|
||||||
-define(ROLE_VIEWER, <<"viewer">>).
|
-define(ROLE_VIEWER, <<"viewer">>).
|
||||||
-define(ROLE_DEFAULT, ?ROLE_VIEWER).
|
|
||||||
-define(ROLE_SUPERUSER, <<"superuser">>).
|
-define(ROLE_SUPERUSER, <<"superuser">>).
|
||||||
|
|
||||||
|
-if(?EMQX_RELEASE_EDITION == ee).
|
||||||
|
-define(ROLE_DEFAULT, ?ROLE_VIEWER).
|
||||||
|
-else.
|
||||||
|
-define(ROLE_DEFAULT, ?ROLE_SUPERUSER).
|
||||||
|
-endif.
|
||||||
|
|
||||||
-record(?ADMIN, {
|
-record(?ADMIN, {
|
||||||
username :: binary(),
|
username :: binary(),
|
||||||
pwdhash :: binary(),
|
pwdhash :: binary(),
|
||||||
|
|
|
@ -213,7 +213,8 @@ authorize(Req) ->
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
{401, 'BAD_TOKEN', <<"Get a token by POST /login">>};
|
{401, 'BAD_TOKEN', <<"Get a token by POST /login">>};
|
||||||
{error, unauthorized_role} ->
|
{error, unauthorized_role} ->
|
||||||
{401, 'UNAUTHORIZED_ROLE', <<"Unauthorized Role">>}
|
{403, 'UNAUTHORIZED_ROLE',
|
||||||
|
<<"You don't have permission to access this resource">>}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
return_unauthorized(
|
return_unauthorized(
|
||||||
|
|
|
@ -196,7 +196,12 @@ force_add_user(Username, Password, Role, Desc) ->
|
||||||
add_user_(Username, Password, Role, Desc) ->
|
add_user_(Username, Password, Role, Desc) ->
|
||||||
case mnesia:wread({?ADMIN, Username}) of
|
case mnesia:wread({?ADMIN, Username}) of
|
||||||
[] ->
|
[] ->
|
||||||
Admin = #?ADMIN{username = Username, pwdhash = hash(Password), description = Desc},
|
Admin = #?ADMIN{
|
||||||
|
username = Username,
|
||||||
|
pwdhash = hash(Password),
|
||||||
|
role = Role,
|
||||||
|
description = Desc
|
||||||
|
},
|
||||||
mnesia:write(Admin),
|
mnesia:write(Admin),
|
||||||
#{username => Username, role => Role, description => Desc};
|
#{username => Username, role => Role, description => Desc};
|
||||||
[_] ->
|
[_] ->
|
||||||
|
@ -305,12 +310,14 @@ all_users() ->
|
||||||
fun(
|
fun(
|
||||||
#?ADMIN{
|
#?ADMIN{
|
||||||
username = Username,
|
username = Username,
|
||||||
description = Desc
|
description = Desc,
|
||||||
|
role = Role
|
||||||
}
|
}
|
||||||
) ->
|
) ->
|
||||||
#{
|
#{
|
||||||
username => Username,
|
username => Username,
|
||||||
description => Desc
|
description => Desc,
|
||||||
|
role => ensure_role(Role)
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
ets:tab2list(?ADMIN)
|
ets:tab2list(?ADMIN)
|
||||||
|
@ -374,12 +381,21 @@ add_default_user(Username, Password) ->
|
||||||
_ -> {ok, default_user_exists}
|
_ -> {ok, default_user_exists}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% ensure the `role` is correct when it directly read from the table
|
||||||
|
%% this value in old data is `undefined`
|
||||||
|
ensure_role(undefined) ->
|
||||||
|
?ROLE_SUPERUSER;
|
||||||
|
ensure_role(Role) when is_binary(Role) ->
|
||||||
|
Role.
|
||||||
|
|
||||||
-if(?EMQX_RELEASE_EDITION == ee).
|
-if(?EMQX_RELEASE_EDITION == ee).
|
||||||
legal_role(Role) ->
|
legal_role(Role) ->
|
||||||
emqx_dashboard_rbac:legal_role(Role).
|
emqx_dashboard_rbac:legal_role(Role).
|
||||||
|
|
||||||
-else.
|
-else.
|
||||||
|
|
||||||
|
-dialyzer({no_match, [add_user/4, update_user/3]}).
|
||||||
|
|
||||||
legal_role(_) ->
|
legal_role(_) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ field(old_pwd) ->
|
||||||
field(new_pwd) ->
|
field(new_pwd) ->
|
||||||
{new_pwd, mk(binary(), #{desc => ?DESC(new_pwd)})};
|
{new_pwd, mk(binary(), #{desc => ?DESC(new_pwd)})};
|
||||||
field(role) ->
|
field(role) ->
|
||||||
{role, mk(binary(), #{desc => ?DESC(role)})}.
|
{role, mk(binary(), #{desc => ?DESC(role), example => ?ROLE_DEFAULT})}.
|
||||||
|
|
||||||
%% -------------------------------------------------------------------------------------------------
|
%% -------------------------------------------------------------------------------------------------
|
||||||
%% API
|
%% API
|
||||||
|
@ -369,7 +369,9 @@ field_filter(role) ->
|
||||||
field_filter(_) ->
|
field_filter(_) ->
|
||||||
true.
|
true.
|
||||||
|
|
||||||
|
filter_result(Result) when is_list(Result) ->
|
||||||
|
lists:map(fun filter_result/1, Result);
|
||||||
filter_result(Result) ->
|
filter_result(Result) ->
|
||||||
maps:without([Role], Result).
|
maps:without([role], Result).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
|
@ -104,7 +104,7 @@ mnesia(boot) ->
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% jwt apply
|
%% jwt apply
|
||||||
do_sign(#?ADMIN{username = Username, extra = Extra}, Password) ->
|
do_sign(#?ADMIN{username = Username} = User, Password) ->
|
||||||
ExpTime = jwt_expiration_time(),
|
ExpTime = jwt_expiration_time(),
|
||||||
Salt = salt(),
|
Salt = salt(),
|
||||||
JWK = jwk(Username, Password, Salt),
|
JWK = jwk(Username, Password, Salt),
|
||||||
|
@ -117,7 +117,8 @@ do_sign(#?ADMIN{username = Username, extra = Extra}, Password) ->
|
||||||
},
|
},
|
||||||
Signed = jose_jwt:sign(JWK, JWS, JWT),
|
Signed = jose_jwt:sign(JWK, JWS, JWT),
|
||||||
{_, Token} = jose_jws:compact(Signed),
|
{_, Token} = jose_jws:compact(Signed),
|
||||||
JWTRec = format(Token, Username, ExpTime, Extra),
|
Role = role(User),
|
||||||
|
JWTRec = format(Token, Username, Role, ExpTime),
|
||||||
_ = mria:transaction(?DASHBOARD_SHARD, fun mnesia:write/1, [JWTRec]),
|
_ = mria:transaction(?DASHBOARD_SHARD, fun mnesia:write/1, [JWTRec]),
|
||||||
{ok, Token}.
|
{ok, Token}.
|
||||||
|
|
||||||
|
@ -191,12 +192,12 @@ jwt_expiration_time() ->
|
||||||
token_ttl() ->
|
token_ttl() ->
|
||||||
emqx_conf:get([dashboard, token_expired_time], ?EXPTIME).
|
emqx_conf:get([dashboard, token_expired_time], ?EXPTIME).
|
||||||
|
|
||||||
format(Token, Username, ExpTime, Extra) ->
|
format(Token, Username, Role, ExpTime) ->
|
||||||
#?ADMIN_JWT{
|
#?ADMIN_JWT{
|
||||||
token = Token,
|
token = Token,
|
||||||
username = Username,
|
username = Username,
|
||||||
exptime = ExpTime,
|
exptime = ExpTime,
|
||||||
extra = #{role => role(Extra)}
|
extra = #{role => Role}
|
||||||
}.
|
}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -254,11 +255,12 @@ role(Data) ->
|
||||||
-else.
|
-else.
|
||||||
|
|
||||||
-dialyzer({nowarn_function, [check_rbac/2]}).
|
-dialyzer({nowarn_function, [check_rbac/2]}).
|
||||||
|
-dialyzer({no_match, [do_verify/2]}).
|
||||||
|
|
||||||
check_rbac(_Req, _Extra) ->
|
check_rbac(_Req, _Extra) ->
|
||||||
true.
|
true.
|
||||||
|
|
||||||
role(_) ->
|
role(_) ->
|
||||||
undefined.
|
?ROLE_DEFAULT.
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
|
@ -67,7 +67,9 @@ end_per_suite(_Config) ->
|
||||||
|
|
||||||
t_overview(_) ->
|
t_overview(_) ->
|
||||||
mnesia:clear_table(?ADMIN),
|
mnesia:clear_table(?ADMIN),
|
||||||
emqx_dashboard_admin:add_user(<<"admin">>, <<"public_www1">>, <<"simple_description">>),
|
emqx_dashboard_admin:add_user(
|
||||||
|
<<"admin">>, <<"public_www1">>, ?ROLE_SUPERUSER, <<"simple_description">>
|
||||||
|
),
|
||||||
Headers = auth_header_(<<"admin">>, <<"public_www1">>),
|
Headers = auth_header_(<<"admin">>, <<"public_www1">>),
|
||||||
[
|
[
|
||||||
{ok, _} = request_dashboard(get, api_path([Overview]), Headers)
|
{ok, _} = request_dashboard(get, api_path([Overview]), Headers)
|
||||||
|
@ -77,8 +79,12 @@ t_overview(_) ->
|
||||||
t_admins_add_delete(_) ->
|
t_admins_add_delete(_) ->
|
||||||
mnesia:clear_table(?ADMIN),
|
mnesia:clear_table(?ADMIN),
|
||||||
Desc = <<"simple description">>,
|
Desc = <<"simple description">>,
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(<<"username">>, <<"password_0">>, Desc),
|
{ok, _} = emqx_dashboard_admin:add_user(
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(<<"username1">>, <<"password1">>, Desc),
|
<<"username">>, <<"password_0">>, ?ROLE_SUPERUSER, Desc
|
||||||
|
),
|
||||||
|
{ok, _} = emqx_dashboard_admin:add_user(
|
||||||
|
<<"username1">>, <<"password1">>, ?ROLE_SUPERUSER, Desc
|
||||||
|
),
|
||||||
Admins = emqx_dashboard_admin:all_users(),
|
Admins = emqx_dashboard_admin:all_users(),
|
||||||
?assertEqual(2, length(Admins)),
|
?assertEqual(2, length(Admins)),
|
||||||
{ok, _} = emqx_dashboard_admin:remove_user(<<"username1">>),
|
{ok, _} = emqx_dashboard_admin:remove_user(<<"username1">>),
|
||||||
|
@ -95,7 +101,7 @@ t_admins_add_delete(_) ->
|
||||||
t_admin_delete_self_failed(_) ->
|
t_admin_delete_self_failed(_) ->
|
||||||
mnesia:clear_table(?ADMIN),
|
mnesia:clear_table(?ADMIN),
|
||||||
Desc = <<"simple description">>,
|
Desc = <<"simple description">>,
|
||||||
_ = emqx_dashboard_admin:add_user(<<"username1">>, <<"password_1">>, Desc),
|
_ = emqx_dashboard_admin:add_user(<<"username1">>, <<"password_1">>, ?ROLE_SUPERUSER, Desc),
|
||||||
Admins = emqx_dashboard_admin:all_users(),
|
Admins = emqx_dashboard_admin:all_users(),
|
||||||
?assertEqual(1, length(Admins)),
|
?assertEqual(1, length(Admins)),
|
||||||
Header = auth_header_(<<"username1">>, <<"password_1">>),
|
Header = auth_header_(<<"username1">>, <<"password_1">>),
|
||||||
|
@ -109,7 +115,7 @@ t_rest_api(_Config) ->
|
||||||
mnesia:clear_table(?ADMIN),
|
mnesia:clear_table(?ADMIN),
|
||||||
Desc = <<"administrator">>,
|
Desc = <<"administrator">>,
|
||||||
Password = <<"public_www1">>,
|
Password = <<"public_www1">>,
|
||||||
emqx_dashboard_admin:add_user(<<"admin">>, Password, Desc),
|
emqx_dashboard_admin:add_user(<<"admin">>, Password, ?ROLE_SUPERUSER, Desc),
|
||||||
{ok, 200, Res0} = http_get(["users"]),
|
{ok, 200, Res0} = http_get(["users"]),
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
[
|
[
|
||||||
|
@ -120,12 +126,22 @@ t_rest_api(_Config) ->
|
||||||
],
|
],
|
||||||
get_http_data(Res0)
|
get_http_data(Res0)
|
||||||
),
|
),
|
||||||
{ok, 200, _} = http_put(["users", "admin"], #{<<"description">> => <<"a_new_description">>}),
|
{ok, 200, _} = http_put(
|
||||||
{ok, 200, _} = http_post(["users"], #{
|
["users", "admin"],
|
||||||
<<"username">> => <<"usera">>,
|
filter_req(#{
|
||||||
<<"password">> => <<"passwd_01234">>,
|
<<"role">> => ?ROLE_SUPERUSER,
|
||||||
<<"description">> => Desc
|
<<"description">> => <<"a_new_description">>
|
||||||
}),
|
})
|
||||||
|
),
|
||||||
|
{ok, 200, _} = http_post(
|
||||||
|
["users"],
|
||||||
|
filter_req(#{
|
||||||
|
<<"username">> => <<"usera">>,
|
||||||
|
<<"password">> => <<"passwd_01234">>,
|
||||||
|
<<"role">> => ?ROLE_SUPERUSER,
|
||||||
|
<<"description">> => Desc
|
||||||
|
})
|
||||||
|
),
|
||||||
{ok, 204, _} = http_delete(["users", "usera"]),
|
{ok, 204, _} = http_delete(["users", "usera"]),
|
||||||
{ok, 404, _} = http_delete(["users", "usera"]),
|
{ok, 404, _} = http_delete(["users", "usera"]),
|
||||||
{ok, 204, _} = http_post(
|
{ok, 204, _} = http_post(
|
||||||
|
@ -136,7 +152,7 @@ t_rest_api(_Config) ->
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
mnesia:clear_table(?ADMIN),
|
mnesia:clear_table(?ADMIN),
|
||||||
emqx_dashboard_admin:add_user(<<"admin">>, Password, <<"administrator">>),
|
emqx_dashboard_admin:add_user(<<"admin">>, Password, ?ROLE_SUPERUSER, <<"administrator">>),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_swagger_json(_Config) ->
|
t_swagger_json(_Config) ->
|
||||||
|
@ -180,7 +196,7 @@ t_cli(_Config) ->
|
||||||
t_lookup_by_username_jwt(_Config) ->
|
t_lookup_by_username_jwt(_Config) ->
|
||||||
User = bin(["user-", integer_to_list(random_num())]),
|
User = bin(["user-", integer_to_list(random_num())]),
|
||||||
Pwd = bin("t_password" ++ integer_to_list(random_num())),
|
Pwd = bin("t_password" ++ integer_to_list(random_num())),
|
||||||
emqx_dashboard_token:sign(User, Pwd),
|
emqx_dashboard_token:sign(#?ADMIN{username = User}, Pwd),
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
[#?ADMIN_JWT{username = User}],
|
[#?ADMIN_JWT{username = User}],
|
||||||
emqx_dashboard_token:lookup_by_username(User)
|
emqx_dashboard_token:lookup_by_username(User)
|
||||||
|
@ -194,7 +210,7 @@ t_lookup_by_username_jwt(_Config) ->
|
||||||
t_clean_expired_jwt(_Config) ->
|
t_clean_expired_jwt(_Config) ->
|
||||||
User = bin(["user-", integer_to_list(random_num())]),
|
User = bin(["user-", integer_to_list(random_num())]),
|
||||||
Pwd = bin("t_password" ++ integer_to_list(random_num())),
|
Pwd = bin("t_password" ++ integer_to_list(random_num())),
|
||||||
emqx_dashboard_token:sign(User, Pwd),
|
emqx_dashboard_token:sign(#?ADMIN{username = User}, Pwd),
|
||||||
[#?ADMIN_JWT{username = User, exptime = ExpTime}] =
|
[#?ADMIN_JWT{username = User, exptime = ExpTime}] =
|
||||||
emqx_dashboard_token:lookup_by_username(User),
|
emqx_dashboard_token:lookup_by_username(User),
|
||||||
ok = emqx_dashboard_token:clean_expired_jwt(_Now1 = ExpTime),
|
ok = emqx_dashboard_token:clean_expired_jwt(_Now1 = ExpTime),
|
||||||
|
@ -261,3 +277,14 @@ api_path(Parts) ->
|
||||||
json(Data) ->
|
json(Data) ->
|
||||||
{ok, Jsx} = emqx_utils_json:safe_decode(Data, [return_maps]),
|
{ok, Jsx} = emqx_utils_json:safe_decode(Data, [return_maps]),
|
||||||
Jsx.
|
Jsx.
|
||||||
|
|
||||||
|
-if(?EMQX_RELEASE_EDITION == ee).
|
||||||
|
filter_req(Req) ->
|
||||||
|
Req.
|
||||||
|
|
||||||
|
-else.
|
||||||
|
|
||||||
|
filter_req(Req) ->
|
||||||
|
maps:without([role, <<"role">>], Req).
|
||||||
|
|
||||||
|
-endif.
|
||||||
|
|
|
@ -42,8 +42,8 @@ t_check_user(_) ->
|
||||||
BadPassword = <<"public_bad">>,
|
BadPassword = <<"public_bad">>,
|
||||||
EmptyUsername = <<>>,
|
EmptyUsername = <<>>,
|
||||||
EmptyPassword = <<>>,
|
EmptyPassword = <<>>,
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, <<"desc">>),
|
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, <<"desc">>),
|
||||||
ok = emqx_dashboard_admin:check(Username, Password),
|
{ok, _} = emqx_dashboard_admin:check(Username, Password),
|
||||||
{error, <<"password_error">>} = emqx_dashboard_admin:check(Username, BadPassword),
|
{error, <<"password_error">>} = emqx_dashboard_admin:check(Username, BadPassword),
|
||||||
{error, <<"username_not_found">>} = emqx_dashboard_admin:check(BadUsername, Password),
|
{error, <<"username_not_found">>} = emqx_dashboard_admin:check(BadUsername, Password),
|
||||||
{error, <<"username_not_found">>} = emqx_dashboard_admin:check(BadUsername, BadPassword),
|
{error, <<"username_not_found">>} = emqx_dashboard_admin:check(BadUsername, BadPassword),
|
||||||
|
@ -61,19 +61,23 @@ t_add_user(_) ->
|
||||||
BadAddUser = <<"***add_user_bad">>,
|
BadAddUser = <<"***add_user_bad">>,
|
||||||
|
|
||||||
%% add success. not return password
|
%% add success. not return password
|
||||||
{ok, NewUser} = emqx_dashboard_admin:add_user(AddUser, AddPassword, AddDescription),
|
{ok, NewUser} = emqx_dashboard_admin:add_user(
|
||||||
|
AddUser, AddPassword, ?ROLE_SUPERUSER, AddDescription
|
||||||
|
),
|
||||||
AddUser = maps:get(username, NewUser),
|
AddUser = maps:get(username, NewUser),
|
||||||
AddDescription = maps:get(description, NewUser),
|
AddDescription = maps:get(description, NewUser),
|
||||||
false = maps:is_key(password, NewUser),
|
false = maps:is_key(password, NewUser),
|
||||||
|
|
||||||
%% add again
|
%% add again
|
||||||
{error, <<"username_already_exist">>} =
|
{error, <<"username_already_exist">>} =
|
||||||
emqx_dashboard_admin:add_user(AddUser, AddPassword, AddDescription),
|
emqx_dashboard_admin:add_user(AddUser, AddPassword, ?ROLE_SUPERUSER, AddDescription),
|
||||||
|
|
||||||
%% add bad username
|
%% add bad username
|
||||||
BadNameError =
|
BadNameError =
|
||||||
<<"Bad Username. Only upper and lower case letters, numbers and underscores are supported">>,
|
<<"Bad Username. Only upper and lower case letters, numbers and underscores are supported">>,
|
||||||
{error, BadNameError} = emqx_dashboard_admin:add_user(BadAddUser, AddPassword, AddDescription),
|
{error, BadNameError} = emqx_dashboard_admin:add_user(
|
||||||
|
BadAddUser, AddPassword, ?ROLE_SUPERUSER, AddDescription
|
||||||
|
),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_lookup_user(_) ->
|
t_lookup_user(_) ->
|
||||||
|
@ -84,7 +88,9 @@ t_lookup_user(_) ->
|
||||||
BadLookupUser = <<"***lookup_user_bad">>,
|
BadLookupUser = <<"***lookup_user_bad">>,
|
||||||
|
|
||||||
{ok, _} =
|
{ok, _} =
|
||||||
emqx_dashboard_admin:add_user(LookupUser, LookupPassword, LookupDescription),
|
emqx_dashboard_admin:add_user(
|
||||||
|
LookupUser, LookupPassword, ?ROLE_SUPERUSER, LookupDescription
|
||||||
|
),
|
||||||
%% lookup success. not return password
|
%% lookup success. not return password
|
||||||
[#emqx_admin{username = LookupUser, description = LookupDescription}] =
|
[#emqx_admin{username = LookupUser, description = LookupDescription}] =
|
||||||
emqx_dashboard_admin:lookup_user(LookupUser),
|
emqx_dashboard_admin:lookup_user(LookupUser),
|
||||||
|
@ -95,7 +101,7 @@ t_lookup_user(_) ->
|
||||||
t_all_users(_) ->
|
t_all_users(_) ->
|
||||||
Username = <<"admin_all">>,
|
Username = <<"admin_all">>,
|
||||||
Password = <<"public_2">>,
|
Password = <<"public_2">>,
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, <<"desc">>),
|
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, <<"desc">>),
|
||||||
All = emqx_dashboard_admin:all_users(),
|
All = emqx_dashboard_admin:all_users(),
|
||||||
?assert(erlang:length(All) >= 1),
|
?assert(erlang:length(All) >= 1),
|
||||||
ok.
|
ok.
|
||||||
|
@ -108,7 +114,9 @@ t_delete_user(_) ->
|
||||||
DeleteBadUser = <<"delete_user_bad">>,
|
DeleteBadUser = <<"delete_user_bad">>,
|
||||||
|
|
||||||
{ok, _NewUser} =
|
{ok, _NewUser} =
|
||||||
emqx_dashboard_admin:add_user(DeleteUser, DeletePassword, DeleteDescription),
|
emqx_dashboard_admin:add_user(
|
||||||
|
DeleteUser, DeletePassword, ?ROLE_SUPERUSER, DeleteDescription
|
||||||
|
),
|
||||||
{ok, ok} = emqx_dashboard_admin:remove_user(DeleteUser),
|
{ok, ok} = emqx_dashboard_admin:remove_user(DeleteUser),
|
||||||
%% remove again
|
%% remove again
|
||||||
{error, <<"username_not_found">>} = emqx_dashboard_admin:remove_user(DeleteUser),
|
{error, <<"username_not_found">>} = emqx_dashboard_admin:remove_user(DeleteUser),
|
||||||
|
@ -124,13 +132,17 @@ t_update_user(_) ->
|
||||||
|
|
||||||
BadUpdateUser = <<"update_user_bad">>,
|
BadUpdateUser = <<"update_user_bad">>,
|
||||||
|
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(UpdateUser, UpdatePassword, UpdateDescription),
|
{ok, _} = emqx_dashboard_admin:add_user(
|
||||||
|
UpdateUser, UpdatePassword, ?ROLE_SUPERUSER, UpdateDescription
|
||||||
|
),
|
||||||
{ok, NewUserInfo} =
|
{ok, NewUserInfo} =
|
||||||
emqx_dashboard_admin:update_user(UpdateUser, NewDesc),
|
emqx_dashboard_admin:update_user(UpdateUser, ?ROLE_SUPERUSER, NewDesc),
|
||||||
UpdateUser = maps:get(username, NewUserInfo),
|
UpdateUser = maps:get(username, NewUserInfo),
|
||||||
NewDesc = maps:get(description, NewUserInfo),
|
NewDesc = maps:get(description, NewUserInfo),
|
||||||
|
|
||||||
{error, <<"username_not_found">>} = emqx_dashboard_admin:update_user(BadUpdateUser, NewDesc),
|
{error, <<"username_not_found">>} = emqx_dashboard_admin:update_user(
|
||||||
|
BadUpdateUser, ?ROLE_SUPERUSER, NewDesc
|
||||||
|
),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_change_password(_) ->
|
t_change_password(_) ->
|
||||||
|
@ -143,7 +155,7 @@ t_change_password(_) ->
|
||||||
|
|
||||||
BadChangeUser = <<"change_user_bad">>,
|
BadChangeUser = <<"change_user_bad">>,
|
||||||
|
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(User, OldPassword, Description),
|
{ok, _} = emqx_dashboard_admin:add_user(User, OldPassword, ?ROLE_SUPERUSER, Description),
|
||||||
|
|
||||||
{ok, ok} = emqx_dashboard_admin:change_password(User, OldPassword, NewPassword),
|
{ok, ok} = emqx_dashboard_admin:change_password(User, OldPassword, NewPassword),
|
||||||
%% change pwd again
|
%% change pwd again
|
||||||
|
@ -161,17 +173,18 @@ t_clean_token(_) ->
|
||||||
Username = <<"admin_token">>,
|
Username = <<"admin_token">>,
|
||||||
Password = <<"public_www1">>,
|
Password = <<"public_www1">>,
|
||||||
NewPassword = <<"public_www2">>,
|
NewPassword = <<"public_www2">>,
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, <<"desc">>),
|
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, <<"desc">>),
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||||
ok = emqx_dashboard_admin:verify_token(Token),
|
FakeReq = #{method => <<"get">>},
|
||||||
|
ok = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
||||||
%% change password
|
%% change password
|
||||||
{ok, _} = emqx_dashboard_admin:change_password(Username, Password, NewPassword),
|
{ok, _} = emqx_dashboard_admin:change_password(Username, Password, NewPassword),
|
||||||
timer:sleep(5),
|
timer:sleep(5),
|
||||||
{error, not_found} = emqx_dashboard_admin:verify_token(Token),
|
{error, not_found} = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
||||||
%% remove user
|
%% remove user
|
||||||
{ok, Token2} = emqx_dashboard_admin:sign_token(Username, NewPassword),
|
{ok, Token2} = emqx_dashboard_admin:sign_token(Username, NewPassword),
|
||||||
ok = emqx_dashboard_admin:verify_token(Token2),
|
ok = emqx_dashboard_admin:verify_token(FakeReq, Token2),
|
||||||
{ok, _} = emqx_dashboard_admin:remove_user(Username),
|
{ok, _} = emqx_dashboard_admin:remove_user(Username),
|
||||||
timer:sleep(5),
|
timer:sleep(5),
|
||||||
{error, not_found} = emqx_dashboard_admin:verify_token(Token2),
|
{error, not_found} = emqx_dashboard_admin:verify_token(FakeReq, Token2),
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -16,10 +16,12 @@ check_rbac(Req, Extra) ->
|
||||||
Role = role(Extra),
|
Role = role(Extra),
|
||||||
check_rbac_with_method(Role, Method).
|
check_rbac_with_method(Role, Method).
|
||||||
|
|
||||||
|
%% For compatibility
|
||||||
role(#?ADMIN{role = undefined}) ->
|
role(#?ADMIN{role = undefined}) ->
|
||||||
?ROLE_SUPERUSER;
|
?ROLE_SUPERUSER;
|
||||||
role(#?ADMIN{role = Role}) ->
|
role(#?ADMIN{role = Role}) ->
|
||||||
Role;
|
Role;
|
||||||
|
%% For compatibility
|
||||||
role([]) ->
|
role([]) ->
|
||||||
?ROLE_SUPERUSER;
|
?ROLE_SUPERUSER;
|
||||||
role(#{role := Role}) ->
|
role(#{role := Role}) ->
|
||||||
|
@ -35,7 +37,7 @@ legal_role(Role) ->
|
||||||
%% ===================================================================
|
%% ===================================================================
|
||||||
check_rbac_with_method(?ROLE_SUPERUSER, _) ->
|
check_rbac_with_method(?ROLE_SUPERUSER, _) ->
|
||||||
true;
|
true;
|
||||||
check_rbac_with_method(?ROLE_VIEWER, <<"get">>) ->
|
check_rbac_with_method(?ROLE_VIEWER, <<"GET">>) ->
|
||||||
true;
|
true;
|
||||||
check_rbac_with_method(_, _) ->
|
check_rbac_with_method(_, _) ->
|
||||||
false.
|
false.
|
||||||
|
|
|
@ -114,7 +114,8 @@
|
||||||
emqx_node_rebalance,
|
emqx_node_rebalance,
|
||||||
emqx_ft,
|
emqx_ft,
|
||||||
emqx_ldap,
|
emqx_ldap,
|
||||||
emqx_gcp_device
|
emqx_gcp_device,
|
||||||
|
emqx_dashboard_rbac
|
||||||
],
|
],
|
||||||
%% must always be of type `load'
|
%% must always be of type `load'
|
||||||
ce_business_apps =>
|
ce_business_apps =>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
|
-define(ROLE_SUPERUSER, <<"superuser">>).
|
||||||
-define(BOOTSTRAP_BACKUP, "emqx-export-test-bootstrap-ce.tar.gz").
|
-define(BOOTSTRAP_BACKUP, "emqx-export-test-bootstrap-ce.tar.gz").
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
|
@ -297,7 +298,7 @@ t_import_on_cluster(Config) ->
|
||||||
t_verify_imported_mnesia_tab_on_cluster(Config) ->
|
t_verify_imported_mnesia_tab_on_cluster(Config) ->
|
||||||
UsersToExport = users(<<"user_to_export_">>),
|
UsersToExport = users(<<"user_to_export_">>),
|
||||||
UsersBeforeImport = users(<<"user_before_import_">>),
|
UsersBeforeImport = users(<<"user_before_import_">>),
|
||||||
[{ok, _} = emqx_dashboard_admin:add_user(U, U, U) || U <- UsersToExport],
|
[{ok, _} = emqx_dashboard_admin:add_user(U, U, ?ROLE_SUPERUSER, U) || U <- UsersToExport],
|
||||||
{ok, #{filename := FileName}} = emqx_mgmt_data_backup:export(),
|
{ok, #{filename := FileName}} = emqx_mgmt_data_backup:export(),
|
||||||
{ok, Cwd} = file:get_cwd(),
|
{ok, Cwd} = file:get_cwd(),
|
||||||
AbsFilePath = filename:join(Cwd, FileName),
|
AbsFilePath = filename:join(Cwd, FileName),
|
||||||
|
@ -305,7 +306,7 @@ t_verify_imported_mnesia_tab_on_cluster(Config) ->
|
||||||
[CoreNode1, CoreNode2, ReplicantNode] = ?config(cluster, Config),
|
[CoreNode1, CoreNode2, ReplicantNode] = ?config(cluster, Config),
|
||||||
|
|
||||||
[
|
[
|
||||||
{ok, _} = rpc:call(CoreNode1, emqx_dashboard_admin, add_user, [U, U, U])
|
{ok, _} = rpc:call(CoreNode1, emqx_dashboard_admin, add_user, [U, U, ?ROLE_SUPERUSER, U])
|
||||||
|| U <- UsersBeforeImport
|
|| U <- UsersBeforeImport
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue