oapi-codegen icon indicating copy to clipboard operation
oapi-codegen copied to clipboard

Middleware Errors are NOT honored

Open juigilkishore opened this issue 3 years ago • 1 comments

Using oapi-codegen v1.11.0 to generate the server stub for the below spec

~/go/bin/oapi-codegen -package main -generate gin,types,spec -old-config-style schema.yaml > server.gen.go
paths:
  /status:
    get:
      description: Get Status
      operationId: GetStatus
      parameters:
        - name: token
          in: header
          description: Validation Token
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Status OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
components:
  schemas:
    Status:
      type: object
      required:
        - status
      properties:
        status:
          type: string

In main.go, a token check middleware is added as a Gin Server Option

type handler struct {}

func (h *handler) GetStatus(c *gin.Context, params GetStatusParams) {
	c.JSON(http.StatusOK, Status{Status: "ok"})
}

func main() {
	swagger, _ := GetSwagger()
	swagger.Servers = nil

	r := gin.Default()
	r.Use(middleware.OapiRequestValidator(swagger))
	RegisterHandlersWithOptions(r, &handler{}, GinServerOptions{Middlewares: []MiddlewareFunc{tokenCheck}})
	r.Run(":8081")
}

func tokenCheck(c *gin.Context) {
	if c.GetHeader("token") == "my-token" {
		c.Next()
		return
	}
	c.AbortWithStatusJSON(http.StatusUnauthorized, Status{Status: "failure"})
}

Sample output

Success - correct token

$ curl -i -X GET http://localhost:8081/status -H "token: my-token"
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Sun, 29 May 2022 18:33:21 GMT
Content-Length: 15

{"status":"ok"}

Undesired reponse - wrong token

$ curl -i -X GET http://localhost:8081/status -H "token: wrong-token"
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Date: Sun, 29 May 2022 18:33:27 GMT
Content-Length: 35

{"status":"failure"}{"status":"ok"}

From the code

https://github.com/deepmap/oapi-codegen/blob/b3eedde3c868b1b4c3f55e3283af30e0edd29c31/pkg/codegen/templates/gin/gin-wrappers.tmpl#L169

it seems no checks on middleware's call is being made. Changing the MiddlewareFunc type to func(c *gin.Context) (err error) and acting according as per the returned error would honor the defined middleware in case of failures.

var err error
for _, middleware := range siw.HandlerMiddlewares {
    err = middleware(c)
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"msg": "Middleware failure: " + err.Error()})
        return
    }
}

Please let me know if this can be acheived through any other ways. Thank you.

juigilkishore avatar May 29 '22 18:05 juigilkishore

@deepmap-marcinr Is there any way to Abort the request for a middlware failure ?

juigilkishore avatar Jun 03 '22 13:06 juigilkishore

I think this issue is a duplicate of #485 and is fixed in #914 (in master, but not released yet)

festinuz avatar Jan 28 '23 12:01 festinuz

I think this issue is a duplicate of #485 and is fixed in #914 (in master, but not released yet)

Agreed! #914 is also released now, so it should be ok to close this issue as resolved

alexstojda avatar Jun 20 '23 16:06 alexstojda