Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG][go-server] enforcement of minimum, maximum; application of default #14013

Closed
5 tasks done
davewalker-wk opened this issue Nov 14, 2022 · 2 comments · Fixed by #15185
Closed
5 tasks done

[BUG][go-server] enforcement of minimum, maximum; application of default #14013

davewalker-wk opened this issue Nov 14, 2022 · 2 comments · Fixed by #15185

Comments

@davewalker-wk
Copy link

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
    • Similar issues have been raised in grander/different scales, or targeting the client implementation
  • What's the actual output vs expected output?
Description

The go-server templates ignore defined maximum, minimum, and defaults for parameters. This is problematic for optional query parameters which have default values, and minimums higher than the languages zero value for that type.

This bug (and referenced template changes) hope to address the limitation for at least integer-type path and query parameters. This issue does not aim to address the default, maximum, minimum or required-ness of fields within models. A separate issue/code will hope to address the issues with having required fields where a 0 value is a valid value exist.

openapi-generator version
openapi-generator --version
openapi-generator-cli 6.0.0
  commit : 69f79fb
  built  : 2022-05-26T02:54:15Z
OpenAPI declaration file content or url
openapi: 3.0.2
info:
  title: Min, Max, Default
  description: >
    Expose issues with go-server templates and the lack of enforcement of min max and default
  version: 0.0.0
tags:
  - name: example
paths:
  /example:
    get:
      summary: example to highlight min max and default
      parameters:
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            example: 10
            default: 100
            minimum: 1
            maximum: 200
      tags:
        - example
      responses:
        "200":
          description: OK
Generation Details

Existing api_example.go(ExampleGet) and routers.go(parseInt32Parameter)

// ExampleGet - example to highlight min max and default
func (c *ExampleApiController) ExampleGet(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	limitParam, err := parseInt32Parameter(query.Get("limit"), false)
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	result, err := c.service.ExampleGet(r.Context(), limitParam)
	// If an error occurred, encode the error with the status code
	if err != nil {
		c.errorHandler(w, r, err, &result)
		return
	}
	// If no error, encode the body and the result code
	EncodeJSONResponse(result.Body, &result.Code, w)

}

// parseInt32Parameter parses a string parameter to an int32.
func parseInt32Parameter(param string, required bool, minVal, maxVal, defVal *int64) (int32, error) {
	if param == "" {
		if required {
			return 0, errors.New(errMsgRequiredMissing)
		}

		return 0, nil
	}

	val, err := strconv.ParseInt(param, 10, 32)
	if err != nil {
		return -1, err
	}

	return int32(val), nil
}

Proposed/Expected of above

// ExampleGet - example to highlight min max and default
func (c *ExampleApiController) ExampleGet(w http.ResponseWriter, r *http.Request) {
	query := r.URL.Query()
	limitParam, err := parseInt32Parameter(query.Get("limit"), false, GetInt64Ptr(1), GetInt64Ptr(200), GetInt64Ptr(100))
	if err != nil {
		c.errorHandler(w, r, &ParsingError{Err: err}, nil)
		return
	}
	result, err := c.service.ExampleGet(r.Context(), limitParam)
	// If an error occurred, encode the error with the status code
	if err != nil {
		c.errorHandler(w, r, err, &result)
		return
	}
	// If no error, encode the body and the result code
	EncodeJSONResponse(result.Body, &result.Code, w)

}

// parseInt32Parameter parses a string parameter to an int32.
func parseInt32Parameter(param string, required bool, minVal, maxVal, defVal *int64) (int32, error) {
	if param == "" {
		if required {
			return 0, errors.New(errMsgRequiredMissing)
		}

		if defVal != nil {
			return int32(*defVal), nil
		}

		return 0, nil
	}

	val, err := strconv.ParseInt(param, 10, 32)
	if err != nil {
		return -1, err
	}

	if minVal != nil && val < *minVal {
		return 0, errors.New(fmt.Sprintf(errMsgMinValueConstraint, val, minVal))
	} else if maxVal != nil && val > *maxVal {
		return 0, errors.New(fmt.Sprintf(errMsgMaxValueConstraint, val, maxVal))
	}

	return int32(val), nil
}
Steps to reproduce

The bug can be replicated by having no support today.

Related issues/PRs

Related:
(client) #4579
(server most similar) #12201

Suggest a fix

Suggested fix to implement for only path/query parameters of integer values for max/min/default

davewalker-wk@5d4595c

@lwj5
Copy link
Contributor

lwj5 commented Mar 30, 2023

Would you be opening a PR for the changes?

@rledisez
Copy link
Contributor

@lwj5 I created a PR based on the code of @davewalker-wk with some fixes and support for body values

rledisez added a commit to rledisez/openapi-generator that referenced this issue Apr 21, 2023
Enforce, for the go-server, to check the minimum and maximum values
specified in the openapi description. Also apply the default if the
parameter is not passed.

Fix OpenAPITools#14013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants