diff --git a/auth/auth.gen.go b/auth/auth.gen.go index fd7a224..ebef832 100644 --- a/auth/auth.gen.go +++ b/auth/auth.gen.go @@ -56,6 +56,9 @@ type ServerInterface interface { // Get service impersontaion token // (POST /get-impersonation-token) GetImpersonationToken(c *gin.Context) + // Logs out the user + // (POST /logout) + Logout(c *gin.Context) // Refreshes access_token and refresh_token // (GET /refresh-tokens) RefreshTokens(c *gin.Context) @@ -91,6 +94,19 @@ func (siw *ServerInterfaceWrapper) GetImpersonationToken(c *gin.Context) { 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 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+"/logout", wrapper.Logout) router.GET(options.BaseURL+"/refresh-tokens", wrapper.RefreshTokens) router.POST(options.BaseURL+"/sign-in", wrapper.PostSignIn) router.POST(options.BaseURL+"/sign-up", wrapper.PostSignUp) @@ -199,6 +216,28 @@ func (response GetImpersonationToken401Response) VisitGetImpersonationTokenRespo 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 { } @@ -286,6 +325,9 @@ type StrictServerInterface interface { // Get service impersontaion token // (POST /get-impersonation-token) 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 // (GET /refresh-tokens) 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 func (sh *strictHandler) RefreshTokens(ctx *gin.Context) { var request RefreshTokensRequestObject diff --git a/auth/openapi-auth.yaml b/auth/openapi-auth.yaml index e95e8c2..8603423 100644 --- a/auth/openapi-auth.yaml +++ b/auth/openapi-auth.yaml @@ -132,6 +132,17 @@ paths: "500": $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: securitySchemes: bearerAuth: diff --git a/modules/auth/handlers/handlers.go b/modules/auth/handlers/handlers.go index 1813035..163efc2 100644 --- a/modules/auth/handlers/handlers.go +++ b/modules/auth/handlers/handlers.go @@ -284,6 +284,22 @@ func (s Server) RefreshTokens(ctx context.Context, req auth.RefreshTokensRequest 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) { const prefix = "Bearer " if len(header) <= len(prefix) || header[:len(prefix)] != prefix {