feat(sso): add `role` into the result of login endpoints
This commit is contained in:
parent
681e57dee6
commit
9e55ae240a
|
@ -1260,7 +1260,7 @@ auth_header_() ->
|
||||||
auth_header_(<<"admin">>, <<"public">>).
|
auth_header_(<<"admin">>, <<"public">>).
|
||||||
|
|
||||||
auth_header_(Username, Password) ->
|
auth_header_(Username, Password) ->
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
{ok, _Role, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||||
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
||||||
|
|
||||||
api_path(Parts) ->
|
api_path(Parts) ->
|
||||||
|
|
|
@ -77,7 +77,7 @@ schema("/login") ->
|
||||||
summary => <<"Dashboard authentication">>,
|
summary => <<"Dashboard authentication">>,
|
||||||
'requestBody' => fields([username, password]),
|
'requestBody' => fields([username, password]),
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => fields([token, version, license]),
|
200 => fields([role, token, version, license]),
|
||||||
401 => response_schema(401)
|
401 => response_schema(401)
|
||||||
},
|
},
|
||||||
security => []
|
security => []
|
||||||
|
@ -219,14 +219,16 @@ login(post, #{body := Params}) ->
|
||||||
Username = maps:get(<<"username">>, Params),
|
Username = maps:get(<<"username">>, Params),
|
||||||
Password = maps:get(<<"password">>, Params),
|
Password = maps:get(<<"password">>, Params),
|
||||||
case emqx_dashboard_admin:sign_token(Username, Password) of
|
case emqx_dashboard_admin:sign_token(Username, Password) of
|
||||||
{ok, Token} ->
|
{ok, Role, Token} ->
|
||||||
?SLOG(info, #{msg => "dashboard_login_successful", username => Username}),
|
?SLOG(info, #{msg => "dashboard_login_successful", username => Username}),
|
||||||
Version = iolist_to_binary(proplists:get_value(version, emqx_sys:info())),
|
Version = iolist_to_binary(proplists:get_value(version, emqx_sys:info())),
|
||||||
{200, #{
|
{200,
|
||||||
|
filter_result(#{
|
||||||
|
role => Role,
|
||||||
token => Token,
|
token => Token,
|
||||||
version => Version,
|
version => Version,
|
||||||
license => #{edition => emqx_release:edition()}
|
license => #{edition => emqx_release:edition()}
|
||||||
}};
|
})};
|
||||||
{error, R} ->
|
{error, R} ->
|
||||||
?SLOG(info, #{msg => "dashboard_login_failed", username => Username, reason => R}),
|
?SLOG(info, #{msg => "dashboard_login_failed", username => Username, reason => R}),
|
||||||
{401, ?BAD_USERNAME_OR_PWD, <<"Auth failed">>}
|
{401, ?BAD_USERNAME_OR_PWD, <<"Auth failed">>}
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% jwt function
|
%% jwt function
|
||||||
-spec sign(User :: dashboard_user(), Password :: binary()) ->
|
-spec sign(User :: dashboard_user(), Password :: binary()) ->
|
||||||
{ok, Token :: binary()} | {error, Reason :: term()}.
|
{ok, dashboard_user_role(), Token :: binary()} | {error, Reason :: term()}.
|
||||||
sign(User, Password) ->
|
sign(User, Password) ->
|
||||||
do_sign(User, Password).
|
do_sign(User, Password).
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ do_sign(#?ADMIN{username = Username} = User, Password) ->
|
||||||
Role = emqx_dashboard_admin:role(User),
|
Role = emqx_dashboard_admin:role(User),
|
||||||
JWTRec = format(Token, Username, Role, ExpTime),
|
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, Role, Token}.
|
||||||
|
|
||||||
-spec do_verify(_, Token :: binary()) ->
|
-spec do_verify(_, Token :: binary()) ->
|
||||||
Result ::
|
Result ::
|
||||||
|
|
|
@ -120,6 +120,7 @@ t_rest_api(_Config) ->
|
||||||
?assertEqual(
|
?assertEqual(
|
||||||
[
|
[
|
||||||
filter_req(#{
|
filter_req(#{
|
||||||
|
<<"backend">> => <<"local">>,
|
||||||
<<"username">> => <<"admin">>,
|
<<"username">> => <<"admin">>,
|
||||||
<<"description">> => <<"administrator">>,
|
<<"description">> => <<"administrator">>,
|
||||||
<<"role">> => ?ROLE_SUPERUSER
|
<<"role">> => ?ROLE_SUPERUSER
|
||||||
|
@ -269,7 +270,7 @@ auth_header_() ->
|
||||||
auth_header_(<<"admin">>, <<"public">>).
|
auth_header_(<<"admin">>, <<"public">>).
|
||||||
|
|
||||||
auth_header_(Username, Password) ->
|
auth_header_(Username, Password) ->
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
{ok, _Role, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||||
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
||||||
|
|
||||||
api_path(Parts) ->
|
api_path(Parts) ->
|
||||||
|
@ -286,6 +287,6 @@ filter_req(Req) ->
|
||||||
-else.
|
-else.
|
||||||
|
|
||||||
filter_req(Req) ->
|
filter_req(Req) ->
|
||||||
maps:without([role, <<"role">>], Req).
|
maps:without([role, <<"role">>, backend, <<"backend">>], Req).
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
|
@ -174,15 +174,16 @@ t_clean_token(_) ->
|
||||||
Password = <<"public_www1">>,
|
Password = <<"public_www1">>,
|
||||||
NewPassword = <<"public_www2">>,
|
NewPassword = <<"public_www2">>,
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, <<"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),
|
||||||
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),
|
{ok, Username} = 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(FakeReq, 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, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token2),
|
{ok, Username} = 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),
|
||||||
|
|
|
@ -116,7 +116,7 @@ auth_header(Username) ->
|
||||||
auth_header(Username, <<"public">>).
|
auth_header(Username, <<"public">>).
|
||||||
|
|
||||||
auth_header(Username, Password) ->
|
auth_header(Username, Password) ->
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
{ok, _Role, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||||
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
{"Authorization", "Bearer " ++ binary_to_list(Token)}.
|
||||||
|
|
||||||
multipart_formdata_request(Url, Fields, Files) ->
|
multipart_formdata_request(Url, Fields, Files) ->
|
||||||
|
|
|
@ -55,7 +55,7 @@ t_status(_Config) ->
|
||||||
[binary, {active, false}, {packet, raw}]
|
[binary, {active, false}, {packet, raw}]
|
||||||
),
|
),
|
||||||
ok = gen_tcp:send(Socket, ranch_proxy_header:header(ProxyInfo)),
|
ok = gen_tcp:send(Socket, ranch_proxy_header:header(ProxyInfo)),
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(<<"admin">>, <<"public">>),
|
{ok, _Role, Token} = emqx_dashboard_admin:sign_token(<<"admin">>, <<"public">>),
|
||||||
ok = gen_tcp:send(
|
ok = gen_tcp:send(
|
||||||
Socket,
|
Socket,
|
||||||
"GET /status HTTP/1.1\r\n"
|
"GET /status HTTP/1.1\r\n"
|
||||||
|
|
|
@ -135,7 +135,7 @@ t_clean_token(_) ->
|
||||||
Desc = <<"desc">>,
|
Desc = <<"desc">>,
|
||||||
NewDesc = <<"new desc">>,
|
NewDesc = <<"new desc">>,
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, Desc),
|
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, Desc),
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
{ok, _Role, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||||
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},
|
||||||
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
||||||
|
@ -154,7 +154,7 @@ t_login_out(_) ->
|
||||||
Password = <<"public_www1">>,
|
Password = <<"public_www1">>,
|
||||||
Desc = <<"desc">>,
|
Desc = <<"desc">>,
|
||||||
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, Desc),
|
{ok, _} = emqx_dashboard_admin:add_user(Username, Password, ?ROLE_SUPERUSER, Desc),
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
{ok, _Role, Token} = emqx_dashboard_admin:sign_token(Username, Password),
|
||||||
FakePath = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri("/logout")),
|
FakePath = erlang:list_to_binary(emqx_dashboard_swagger:relative_uri("/logout")),
|
||||||
FakeReq = #{method => <<"POST">>, path => FakePath},
|
FakeReq = #{method => <<"POST">>, path => FakePath},
|
||||||
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
{ok, Username} = emqx_dashboard_admin:verify_token(FakeReq, Token),
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
-module(emqx_dashboard_sso).
|
-module(emqx_dashboard_sso).
|
||||||
|
|
||||||
-include_lib("hocon/include/hoconsc.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
-include_lib("emqx_dashboard/include/emqx_dashboard.hrl").
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
hocon_ref/1,
|
hocon_ref/1,
|
||||||
|
@ -38,7 +39,7 @@
|
||||||
{ok, NewState :: state()} | {error, Reason :: term()}.
|
{ok, NewState :: state()} | {error, Reason :: term()}.
|
||||||
-callback destroy(State :: state()) -> ok.
|
-callback destroy(State :: state()) -> ok.
|
||||||
-callback login(request(), State :: state()) ->
|
-callback login(request(), State :: state()) ->
|
||||||
{ok, Token :: binary()} | {error, Reason :: term()}.
|
{ok, dashboard_user_role(), Token :: binary()} | {error, Reason :: term()}.
|
||||||
|
|
||||||
%%------------------------------------------------------------------------------
|
%%------------------------------------------------------------------------------
|
||||||
%% Callback Interface
|
%% Callback Interface
|
||||||
|
|
|
@ -83,7 +83,7 @@ schema("/sso/login/:backend") ->
|
||||||
parameters => backend_name_in_path(),
|
parameters => backend_name_in_path(),
|
||||||
'requestBody' => login_union(),
|
'requestBody' => login_union(),
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => emqx_dashboard_api:fields([token, version, license]),
|
200 => emqx_dashboard_api:fields([role, token, version, license]),
|
||||||
401 => response_schema(401),
|
401 => response_schema(401),
|
||||||
404 => response_schema(404)
|
404 => response_schema(404)
|
||||||
},
|
},
|
||||||
|
@ -148,10 +148,11 @@ login(post, #{bindings := #{backend := Backend}, body := Sign}) ->
|
||||||
State ->
|
State ->
|
||||||
Provider = emqx_dashboard_sso:provider(Backend),
|
Provider = emqx_dashboard_sso:provider(Backend),
|
||||||
case emqx_dashboard_sso:login(Provider, Sign, State) of
|
case emqx_dashboard_sso:login(Provider, Sign, State) of
|
||||||
{ok, Token} ->
|
{ok, Role, Token} ->
|
||||||
?SLOG(info, #{msg => "dashboard_sso_login_successful", request => Sign}),
|
?SLOG(info, #{msg => "dashboard_sso_login_successful", request => Sign}),
|
||||||
Version = iolist_to_binary(proplists:get_value(version, emqx_sys:info())),
|
Version = iolist_to_binary(proplists:get_value(version, emqx_sys:info())),
|
||||||
{200, #{
|
{200, #{
|
||||||
|
role => Role,
|
||||||
token => Token,
|
token => Token,
|
||||||
version => Version,
|
version => Version,
|
||||||
license => #{edition => emqx_release:edition()}
|
license => #{edition => emqx_release:edition()}
|
||||||
|
|
|
@ -101,7 +101,7 @@ t_first_login(_) ->
|
||||||
},
|
},
|
||||||
%% this API is authorization-free
|
%% this API is authorization-free
|
||||||
{ok, 200, Result} = request_without_authorization(post, Path, Req),
|
{ok, 200, Result} = request_without_authorization(post, Path, Req),
|
||||||
?assertMatch(#{license := _, token := _}, decode_json(Result)),
|
?assertMatch(#{license := _, token := _, role := ?ROLE_VIEWER}, decode_json(Result)),
|
||||||
?assertMatch(
|
?assertMatch(
|
||||||
[#?ADMIN{username = ?SSO_USERNAME(ldap, ?LDAP_USER)}],
|
[#?ADMIN{username = ?SSO_USERNAME(ldap, ?LDAP_USER)}],
|
||||||
emqx_dashboard_admin:lookup_user(ldap, ?LDAP_USER)
|
emqx_dashboard_admin:lookup_user(ldap, ?LDAP_USER)
|
||||||
|
|
|
@ -252,7 +252,7 @@ describe_plugins(Name) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
install_plugin(FilePath) ->
|
install_plugin(FilePath) ->
|
||||||
{ok, Token} = emqx_dashboard_admin:sign_token(<<"admin">>, <<"public">>),
|
{ok, _Role, Token} = emqx_dashboard_admin:sign_token(<<"admin">>, <<"public">>),
|
||||||
Path = emqx_mgmt_api_test_util:api_path(["plugins", "install"]),
|
Path = emqx_mgmt_api_test_util:api_path(["plugins", "install"]),
|
||||||
case
|
case
|
||||||
emqx_mgmt_api_test_util:upload_request(
|
emqx_mgmt_api_test_util:upload_request(
|
||||||
|
|
Loading…
Reference in New Issue