feat: logout
This commit is contained in:
parent
714ef57027
commit
69eacd7240
3 changed files with 94 additions and 0 deletions
|
|
@ -56,6 +56,9 @@ type ServerInterface interface {
|
||||||
// Get service impersontaion token
|
// Get service impersontaion token
|
||||||
// (POST /get-impersonation-token)
|
// (POST /get-impersonation-token)
|
||||||
GetImpersonationToken(c *gin.Context)
|
GetImpersonationToken(c *gin.Context)
|
||||||
|
// Logs out the user
|
||||||
|
// (POST /logout)
|
||||||
|
Logout(c *gin.Context)
|
||||||
// Refreshes access_token and refresh_token
|
// Refreshes access_token and refresh_token
|
||||||
// (GET /refresh-tokens)
|
// (GET /refresh-tokens)
|
||||||
RefreshTokens(c *gin.Context)
|
RefreshTokens(c *gin.Context)
|
||||||
|
|
@ -91,6 +94,19 @@ func (siw *ServerInterfaceWrapper) GetImpersonationToken(c *gin.Context) {
|
||||||
siw.Handler.GetImpersonationToken(c)
|
siw.Handler.GetImpersonationToken(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logout operation middleware
|
||||||
|
func (siw *ServerInterfaceWrapper) Logout(c *gin.Context) {
|
||||||
|
|
||||||
|
for _, middleware := range siw.HandlerMiddlewares {
|
||||||
|
middleware(c)
|
||||||
|
if c.IsAborted() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
siw.Handler.Logout(c)
|
||||||
|
}
|
||||||
|
|
||||||
// RefreshTokens operation middleware
|
// RefreshTokens operation middleware
|
||||||
func (siw *ServerInterfaceWrapper) RefreshTokens(c *gin.Context) {
|
func (siw *ServerInterfaceWrapper) RefreshTokens(c *gin.Context) {
|
||||||
|
|
||||||
|
|
@ -158,6 +174,7 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options
|
||||||
}
|
}
|
||||||
|
|
||||||
router.POST(options.BaseURL+"/get-impersonation-token", wrapper.GetImpersonationToken)
|
router.POST(options.BaseURL+"/get-impersonation-token", wrapper.GetImpersonationToken)
|
||||||
|
router.POST(options.BaseURL+"/logout", wrapper.Logout)
|
||||||
router.GET(options.BaseURL+"/refresh-tokens", wrapper.RefreshTokens)
|
router.GET(options.BaseURL+"/refresh-tokens", wrapper.RefreshTokens)
|
||||||
router.POST(options.BaseURL+"/sign-in", wrapper.PostSignIn)
|
router.POST(options.BaseURL+"/sign-in", wrapper.PostSignIn)
|
||||||
router.POST(options.BaseURL+"/sign-up", wrapper.PostSignUp)
|
router.POST(options.BaseURL+"/sign-up", wrapper.PostSignUp)
|
||||||
|
|
@ -199,6 +216,28 @@ func (response GetImpersonationToken401Response) VisitGetImpersonationTokenRespo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LogoutRequestObject struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type LogoutResponseObject interface {
|
||||||
|
VisitLogoutResponse(w http.ResponseWriter) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Logout200Response struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (response Logout200Response) VisitLogoutResponse(w http.ResponseWriter) error {
|
||||||
|
w.WriteHeader(200)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Logout500Response = ServerErrorResponse
|
||||||
|
|
||||||
|
func (response Logout500Response) VisitLogoutResponse(w http.ResponseWriter) error {
|
||||||
|
w.WriteHeader(500)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type RefreshTokensRequestObject struct {
|
type RefreshTokensRequestObject struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -286,6 +325,9 @@ type StrictServerInterface interface {
|
||||||
// Get service impersontaion token
|
// Get service impersontaion token
|
||||||
// (POST /get-impersonation-token)
|
// (POST /get-impersonation-token)
|
||||||
GetImpersonationToken(ctx context.Context, request GetImpersonationTokenRequestObject) (GetImpersonationTokenResponseObject, error)
|
GetImpersonationToken(ctx context.Context, request GetImpersonationTokenRequestObject) (GetImpersonationTokenResponseObject, error)
|
||||||
|
// Logs out the user
|
||||||
|
// (POST /logout)
|
||||||
|
Logout(ctx context.Context, request LogoutRequestObject) (LogoutResponseObject, error)
|
||||||
// Refreshes access_token and refresh_token
|
// Refreshes access_token and refresh_token
|
||||||
// (GET /refresh-tokens)
|
// (GET /refresh-tokens)
|
||||||
RefreshTokens(ctx context.Context, request RefreshTokensRequestObject) (RefreshTokensResponseObject, error)
|
RefreshTokens(ctx context.Context, request RefreshTokensRequestObject) (RefreshTokensResponseObject, error)
|
||||||
|
|
@ -342,6 +384,31 @@ func (sh *strictHandler) GetImpersonationToken(ctx *gin.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logout operation middleware
|
||||||
|
func (sh *strictHandler) Logout(ctx *gin.Context) {
|
||||||
|
var request LogoutRequestObject
|
||||||
|
|
||||||
|
handler := func(ctx *gin.Context, request interface{}) (interface{}, error) {
|
||||||
|
return sh.ssi.Logout(ctx, request.(LogoutRequestObject))
|
||||||
|
}
|
||||||
|
for _, middleware := range sh.middlewares {
|
||||||
|
handler = middleware(handler, "Logout")
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := handler(ctx, request)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(err)
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
} else if validResponse, ok := response.(LogoutResponseObject); ok {
|
||||||
|
if err := validResponse.VisitLogoutResponse(ctx.Writer); err != nil {
|
||||||
|
ctx.Error(err)
|
||||||
|
}
|
||||||
|
} else if response != nil {
|
||||||
|
ctx.Error(fmt.Errorf("unexpected response type: %T", response))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RefreshTokens operation middleware
|
// RefreshTokens operation middleware
|
||||||
func (sh *strictHandler) RefreshTokens(ctx *gin.Context) {
|
func (sh *strictHandler) RefreshTokens(ctx *gin.Context) {
|
||||||
var request RefreshTokensRequestObject
|
var request RefreshTokensRequestObject
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,17 @@ paths:
|
||||||
"500":
|
"500":
|
||||||
$ref: '#/components/responses/ServerError'
|
$ref: '#/components/responses/ServerError'
|
||||||
|
|
||||||
|
/logout:
|
||||||
|
post:
|
||||||
|
summary: Logs out the user
|
||||||
|
operationId: logout
|
||||||
|
tags: [Auth]
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Logout success
|
||||||
|
"500":
|
||||||
|
$ref: '#/components/responses/ServerError'
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
bearerAuth:
|
bearerAuth:
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,22 @@ func (s Server) RefreshTokens(ctx context.Context, req auth.RefreshTokensRequest
|
||||||
return auth.RefreshTokens200Response{}, nil
|
return auth.RefreshTokens200Response{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s Server) Logout(ctx context.Context, req auth.LogoutRequestObject) (auth.LogoutResponseObject, error) {
|
||||||
|
// TODO: get current tokens and add them to block list
|
||||||
|
ginCtx, ok := ctx.Value(gin.ContextKey).(*gin.Context)
|
||||||
|
if !ok {
|
||||||
|
log.Print("failed to get gin context")
|
||||||
|
return auth.Logout500Response{}, fmt.Errorf("failed to get gin.Context from context.Context")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete cookies by setting MaxAge negative
|
||||||
|
ginCtx.SetCookie("access_token", "", -1, "/api", "", true, true)
|
||||||
|
ginCtx.SetCookie("refresh_token", "", -1, "/auth", "", true, true)
|
||||||
|
ginCtx.SetCookie("xsrf_token", "", -1, "/", "", false, false)
|
||||||
|
|
||||||
|
return auth.Logout200Response{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func ExtractBearerToken(header string) (string, error) {
|
func ExtractBearerToken(header string) (string, error) {
|
||||||
const prefix = "Bearer "
|
const prefix = "Bearer "
|
||||||
if len(header) <= len(prefix) || header[:len(prefix)] != prefix {
|
if len(header) <= len(prefix) || header[:len(prefix)] != prefix {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue