Skip to content

Separate validation of the integer type schema from the number type schema #123

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions errors/parameter_errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,22 @@ func IncorrectCookieParamArrayBoolean(
}
}

func IncorrectQueryParamArrayInteger(
param *v3.Parameter, item string, sch *base.Schema, itemsSchema *base.Schema,
) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
ValidationSubType: helpers.ParameterValidationQuery,
Message: fmt.Sprintf("Query array parameter '%s' is not a valid integer", param.Name),
Reason: fmt.Sprintf("The query parameter (which is an array) '%s' is defined as being an integer, "+
"however the value '%s' is not a valid integer", param.Name, item),
SpecLine: sch.Items.A.GoLow().Schema().Type.KeyNode.Line,
SpecCol: sch.Items.A.GoLow().Schema().Type.KeyNode.Column,
Context: itemsSchema,
HowToFix: fmt.Sprintf(HowToFixParamInvalidInteger, item),
}
}

func IncorrectQueryParamArrayNumber(
param *v3.Parameter, item string, sch *base.Schema, itemsSchema *base.Schema,
) *ValidationError {
Expand Down Expand Up @@ -226,6 +242,20 @@ func IncorrectQueryParamBool(param *v3.Parameter, ef string, sch *base.Schema) *
}
}

func InvalidQueryParamInteger(param *v3.Parameter, ef string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
ValidationSubType: helpers.ParameterValidationQuery,
Message: fmt.Sprintf("Query parameter '%s' is not a valid integer", param.Name),
Reason: fmt.Sprintf("The query parameter '%s' is defined as being an integer, "+
"however the value '%s' is not a valid integer", param.Name, ef),
SpecLine: param.GoLow().Schema.KeyNode.Line,
SpecCol: param.GoLow().Schema.KeyNode.Column,
Context: sch,
HowToFix: fmt.Sprintf(HowToFixParamInvalidInteger, ef),
}
}

func InvalidQueryParamNumber(param *v3.Parameter, ef string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
Expand Down Expand Up @@ -294,6 +324,20 @@ func IncorrectReservedValues(param *v3.Parameter, ef string, sch *base.Schema) *
}
}

func InvalidHeaderParamInteger(param *v3.Parameter, ef string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
ValidationSubType: helpers.ParameterValidationHeader,
Message: fmt.Sprintf("Header parameter '%s' is not a valid integer", param.Name),
Reason: fmt.Sprintf("The header parameter '%s' is defined as being an integer, "+
"however the value '%s' is not a valid integer", param.Name, ef),
SpecLine: param.GoLow().Schema.KeyNode.Line,
SpecCol: param.GoLow().Schema.KeyNode.Column,
Context: sch,
HowToFix: fmt.Sprintf(HowToFixParamInvalidInteger, ef),
}
}

func InvalidHeaderParamNumber(param *v3.Parameter, ef string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
Expand All @@ -308,6 +352,20 @@ func InvalidHeaderParamNumber(param *v3.Parameter, ef string, sch *base.Schema)
}
}

func InvalidCookieParamInteger(param *v3.Parameter, ef string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
ValidationSubType: helpers.ParameterValidationCookie,
Message: fmt.Sprintf("Cookie parameter '%s' is not a valid integer", param.Name),
Reason: fmt.Sprintf("The cookie parameter '%s' is defined as being an integer, "+
"however the value '%s' is not a valid integer", param.Name, ef),
SpecLine: param.GoLow().Schema.KeyNode.Line,
SpecCol: param.GoLow().Schema.KeyNode.Column,
Context: sch,
HowToFix: fmt.Sprintf(HowToFixParamInvalidInteger, ef),
}
}

func InvalidCookieParamNumber(param *v3.Parameter, ef string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
Expand Down Expand Up @@ -434,6 +492,20 @@ func IncorrectPathParamEnum(param *v3.Parameter, ef string, sch *base.Schema) *V
}
}

func IncorrectPathParamInteger(param *v3.Parameter, item string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
ValidationSubType: helpers.ParameterValidationPath,
Message: fmt.Sprintf("Path parameter '%s' is not a valid integer", param.Name),
Reason: fmt.Sprintf("The path parameter '%s' is defined as being an integer, "+
"however the value '%s' is not a valid integer", param.Name, item),
SpecLine: param.GoLow().Schema.KeyNode.Line,
SpecCol: param.GoLow().Schema.KeyNode.Column,
Context: sch,
HowToFix: fmt.Sprintf(HowToFixParamInvalidInteger, item),
}
}

func IncorrectPathParamNumber(param *v3.Parameter, item string, sch *base.Schema) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
Expand Down Expand Up @@ -464,6 +536,22 @@ func IncorrectPathParamArrayNumber(
}
}

func IncorrectPathParamArrayInteger(
param *v3.Parameter, item string, sch *base.Schema, itemsSchema *base.Schema,
) *ValidationError {
return &ValidationError{
ValidationType: helpers.ParameterValidation,
ValidationSubType: helpers.ParameterValidationPath,
Message: fmt.Sprintf("Path array parameter '%s' is not a valid integer", param.Name),
Reason: fmt.Sprintf("The path parameter (which is an array) '%s' is defined as being an integer, "+
"however the value '%s' is not a valid integer", param.Name, item),
SpecLine: sch.Items.A.GoLow().Schema().Type.KeyNode.Line,
SpecCol: sch.Items.A.GoLow().Schema().Type.KeyNode.Column,
Context: itemsSchema,
HowToFix: fmt.Sprintf(HowToFixParamInvalidNumber, item),
}
}

func IncorrectPathParamArrayBoolean(
param *v3.Parameter, item string, sch *base.Schema, itemsSchema *base.Schema,
) *ValidationError {
Expand Down
132 changes: 132 additions & 0 deletions errors/parameter_errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,25 @@ func createMockLowBaseSchemaForNumberArray() *lowbase.Schema {
return itemsSchema
}

func TestIncorrectQueryParamArrayInteger(t *testing.T) {
// Create mock parameter and schemas
param := createMockParameterForNumberArray()
baseSchema := createMockLowBaseSchemaForNumberArray()
s := base.NewSchema(baseSchema)
itemsSchema := base.NewSchema(baseSchema.Items.Value.A.Schema())

// Call the function with an invalid number value in the array
err := IncorrectQueryParamArrayInteger(param, "notNumber", s, itemsSchema)

// Validate the error
require.NotNil(t, err)
require.Equal(t, helpers.ParameterValidation, err.ValidationType)
require.Equal(t, helpers.ParameterValidationQuery, err.ValidationSubType)
require.Contains(t, err.Message, "Query array parameter 'testQueryParam' is not a valid integer")
require.Contains(t, err.Reason, "the value 'notNumber' is not a valid integer")
require.Contains(t, err.HowToFix, "notNumber")
}

func TestIncorrectQueryParamArrayNumber(t *testing.T) {
// Create mock parameter and schemas
param := createMockParameterForNumberArray()
Expand Down Expand Up @@ -568,6 +587,22 @@ func TestInvalidQueryParamNumber(t *testing.T) {
require.Contains(t, err.HowToFix, "notNumber")
}

func TestInvalidQueryParamInteger(t *testing.T) {
param := createMockParameter()
baseSchema := createMockLowBaseSchema()

// Call the function with an invalid number value
err := InvalidQueryParamInteger(param, "notNumber", base.NewSchema(baseSchema))

// Validate the error
require.NotNil(t, err)
require.Equal(t, helpers.ParameterValidation, err.ValidationType)
require.Equal(t, helpers.ParameterValidationQuery, err.ValidationSubType)
require.Contains(t, err.Message, "Query parameter 'testQueryParam' is not a valid integer")
require.Contains(t, err.Reason, "the value 'notNumber' is not a valid integer")
require.Contains(t, err.HowToFix, "notNumber")
}

func TestIncorrectQueryParamEnum(t *testing.T) {
enum := `enum: [fish, crab, lobster]`
var n yaml.Node
Expand Down Expand Up @@ -645,6 +680,29 @@ func TestIncorrectReservedValues(t *testing.T) {
require.Contains(t, err.HowToFix, "borked%3A%3A%3F%5E%26%2A")
}

func TestInvalidHeaderParamInteger(t *testing.T) {
enum := `name: blip`
var n yaml.Node
_ = yaml.Unmarshal([]byte(enum), &n)

schemaProxy := &lowbase.SchemaProxy{}
require.NoError(t, schemaProxy.Build(context.Background(), n.Content[0], n.Content[0], nil))

highSchema := base.NewSchema(schemaProxy.Schema())
param := createMockParameter()
param.Name = "bunny"

err := InvalidHeaderParamInteger(param, "bunmy", highSchema)

// Validate the error
require.NotNil(t, err)
require.Equal(t, helpers.ParameterValidation, err.ValidationType)
require.Equal(t, helpers.ParameterValidationHeader, err.ValidationSubType)
require.Contains(t, err.Message, "Header parameter 'bunny' is not a valid integer")
require.Contains(t, err.Reason, "The header parameter 'bunny' is defined as being an integer")
require.Contains(t, err.HowToFix, "bunmy")
}

func TestInvalidHeaderParamNumber(t *testing.T) {
enum := `name: blip`
var n yaml.Node
Expand Down Expand Up @@ -691,6 +749,29 @@ func TestInvalidCookieParamNumber(t *testing.T) {
require.Contains(t, err.HowToFix, "milky")
}

func TestInvalidCookieParamInteger(t *testing.T) {
enum := `name: blip`
var n yaml.Node
_ = yaml.Unmarshal([]byte(enum), &n)

schemaProxy := &lowbase.SchemaProxy{}
require.NoError(t, schemaProxy.Build(context.Background(), n.Content[0], n.Content[0], nil))

highSchema := base.NewSchema(schemaProxy.Schema())
param := createMockParameter()
param.Name = "cookies"

err := InvalidCookieParamInteger(param, "milky", highSchema)

// Validate the error
require.NotNil(t, err)
require.Equal(t, helpers.ParameterValidation, err.ValidationType)
require.Equal(t, helpers.ParameterValidationCookie, err.ValidationSubType)
require.Contains(t, err.Message, "Cookie parameter 'cookies' is not a valid integer")
require.Contains(t, err.Reason, "The cookie parameter 'cookies' is defined as being an integer")
require.Contains(t, err.HowToFix, "milky")
}

func TestIncorrectHeaderParamBool(t *testing.T) {
enum := `name: blip`
var n yaml.Node
Expand Down Expand Up @@ -900,6 +981,31 @@ func TestIncorrectPathParamNumber(t *testing.T) {
require.Contains(t, err.HowToFix, "milky")
}

func TestIncorrectPathParamInteger(t *testing.T) {
items := `items:
type: integer`
var n yaml.Node
_ = yaml.Unmarshal([]byte(items), &n)

schemaProxy := &lowbase.SchemaProxy{}
require.NoError(t, schemaProxy.Build(context.Background(), n.Content[0], n.Content[0], nil))

highSchema := base.NewSchema(schemaProxy.Schema())
param := createMockParameter()
param.Schema = base.CreateSchemaProxy(highSchema)
param.GoLow().Schema.KeyNode = &yaml.Node{}

err := IncorrectPathParamInteger(param, "milky", highSchema)

// Validate the error
require.NotNil(t, err)
require.Equal(t, helpers.ParameterValidation, err.ValidationType)
require.Equal(t, helpers.ParameterValidationPath, err.ValidationSubType)
require.Contains(t, err.Message, "Path parameter 'testQueryParam' is not a valid integer")
require.Contains(t, err.Reason, "The path parameter 'testQueryParam' is defined as being an integer")
require.Contains(t, err.HowToFix, "milky")
}

func TestIncorrectPathParamArrayNumber(t *testing.T) {
items := `items:
type: number`
Expand All @@ -926,6 +1032,32 @@ func TestIncorrectPathParamArrayNumber(t *testing.T) {
require.Contains(t, err.HowToFix, "milky")
}

func TestIncorrectPathParamArrayInteger(t *testing.T) {
items := `items:
type: integer`
var n yaml.Node
_ = yaml.Unmarshal([]byte(items), &n)

schemaProxy := &lowbase.SchemaProxy{}
require.NoError(t, schemaProxy.Build(context.Background(), n.Content[0], n.Content[0], nil))

highSchema := base.NewSchema(schemaProxy.Schema())
highSchema.GoLow().Items.Value.A.Schema()

param := createMockParameter()
param.Name = "bubbles"

err := IncorrectPathParamArrayInteger(param, "milky", highSchema, nil)

// Validate the error
require.NotNil(t, err)
require.Equal(t, helpers.ParameterValidation, err.ValidationType)
require.Equal(t, helpers.ParameterValidationPath, err.ValidationSubType)
require.Contains(t, err.Message, "Path array parameter 'bubbles' is not a valid integer")
require.Contains(t, err.Reason, "The path parameter (which is an array) 'bubbles' is defined as being an integer")
require.Contains(t, err.HowToFix, "milky")
}

func TestIncorrectPathParamArrayBoolean(t *testing.T) {
items := `items:
type: number`
Expand Down
1 change: 1 addition & 0 deletions errors/parameters_howtofix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package errors
const (
HowToFixReservedValues string = "parameter values need to URL Encoded to ensure reserved " +
"values are correctly encoded, for example: '%s'"
HowToFixParamInvalidInteger string = "Convert the value '%s' into an integer"
HowToFixParamInvalidNumber string = "Convert the value '%s' into a number"
HowToFixParamInvalidString string = "Convert the value '%s' into a string (cannot start with a number, or be a floating point)"
HowToFixParamInvalidBoolean string = "Convert the value '%s' into a true/false value"
Expand Down
22 changes: 21 additions & 1 deletion parameters/cookie_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,27 @@ func (v *paramValidator) ValidateCookieParamsWithPathItem(request *http.Request,

for _, ty := range pType {
switch ty {
case helpers.Integer, helpers.Number:
case helpers.Integer:
if _, err := strconv.ParseInt(cookie.Value, 10, 64); err != nil {
validationErrors = append(validationErrors,
errors.InvalidCookieParamInteger(p, strings.ToLower(cookie.Value), sch))
break
}
// check if enum is in range
if sch.Enum != nil {
matchFound := false
for _, enumVal := range sch.Enum {
if strings.TrimSpace(cookie.Value) == fmt.Sprint(enumVal.Value) {
matchFound = true
break
}
}
if !matchFound {
validationErrors = append(validationErrors,
errors.IncorrectCookieParamEnum(p, strings.ToLower(cookie.Value), sch))
}
}
case helpers.Number:
if _, err := strconv.ParseFloat(cookie.Value, 64); err != nil {
validationErrors = append(validationErrors,
errors.InvalidCookieParamNumber(p, strings.ToLower(cookie.Value), sch))
Expand Down
Loading
Loading