From 45d491959a9138b81ae6103c7f04cb5f6984ecc5 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Wed, 7 Apr 2021 23:19:57 +0200 Subject: [PATCH 1/8] Avoid failfast and return proper error when mapping is available (cherry picked from commit d743e52d07bac9481fe22f8c8ea0a879738d58bd) (cherry picked from commit 818b0df7f8811081cb41f8b07949686ba51b693c) (cherry picked from commit 7b15e5e51905d844cd5fb56b20c4f255f781628f) --- openapi3/schema.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/openapi3/schema.go b/openapi3/schema.go index 9c3103a27..00fc82cc7 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -837,6 +837,25 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val } if v := schema.OneOf; len(v) > 0 { + + if schema.Discriminator != nil { + if len(schema.Discriminator.Mapping) > 0 { + /* Find mapped object by ref */ + if valuemap, okcheck := value.(map[string]interface{}); okcheck { + pn := schema.Discriminator.PropertyName + if discriminatorVal, okcheck := valuemap[pn]; okcheck { + if mapref, okcheck := schema.Discriminator.Mapping[discriminatorVal.(string)]; okcheck { + for _, item := range v { + if item.Ref == mapref { + return item.Value.visitJSON(settings, value) + } + } + } + } + } + } + } + ok := 0 for _, item := range v { v := item.Value From be8af26b522bf6c97d6ceb40890cd50a9b15bca1 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 13 Apr 2021 09:20:58 +0200 Subject: [PATCH 2/8] Revert "Adds oneOf/discriminator/mapping management (#321)" This reverts commit 1286d066039886ab13d9fca0947db4d1d5994343. # Conflicts: # openapi3filter/validation_discriminator_test.go (cherry picked from commit a6bc0e16acf6e3eed50f8b41cd62c663605f8681) (cherry picked from commit 011aa824fed5ee703778a66fb79b7833a8d28fc7) --- openapi3/schema.go | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index 00fc82cc7..67f616af1 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -867,19 +867,7 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val err := v.visitJSON(settings, value) settings.failfast = oldfailfast if err == nil { - if schema.Discriminator != nil { - pn := schema.Discriminator.PropertyName - if valuemap, okcheck := value.(map[string]interface{}); okcheck { - if discriminatorVal, okcheck := valuemap[pn]; okcheck == true { - mapref, okcheck := schema.Discriminator.Mapping[discriminatorVal.(string)] - if okcheck && mapref == item.Ref { - ok++ - } - } - } - } else { - ok++ - } + ok++ } } if ok != 1 { From 9aa5c5ab1ae799d10db8a057fbb4fc436e33a3a9 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 13 Apr 2021 09:55:44 +0200 Subject: [PATCH 3/8] Fixup missing Test prefix (cherry picked from commit 56c30a7d536d61550c5b9472bee692751546eb19) (cherry picked from commit 393fdeccafa8677034f33c2a54311fc109f18768) --- openapi3filter/validate_request_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openapi3filter/validate_request_test.go b/openapi3filter/validate_request_test.go index 2c1c0b5cc..f7e59f767 100644 --- a/openapi3filter/validate_request_test.go +++ b/openapi3filter/validate_request_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "testing" "github.com/getkin/kin-openapi/openapi3" "github.com/getkin/kin-openapi/openapi3filter" @@ -63,7 +64,7 @@ components: type: integer ` -func Example() { +func TestExample(t *testing.T) { loader := openapi3.NewSwaggerLoader() doc, err := loader.LoadSwaggerFromData([]byte(spec)) if err != nil { From 146d4b9383ea54c5a3a9f85698134a4d994b435d Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 13 Apr 2021 10:15:18 +0200 Subject: [PATCH 4/8] Adds implicit mapping case (cherry picked from commit a3ea3ba5327f05652d33df2fe316294cd53e6897) (cherry picked from commit dfd110827586013e03320a2f42fa4f6f09901615) --- openapi3/schema.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index 67f616af1..ac999ba6b 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -10,6 +10,7 @@ import ( "math/big" "regexp" "strconv" + "strings" "unicode/utf16" "github.com/getkin/kin-openapi/jsoninfo" @@ -839,11 +840,11 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val if v := schema.OneOf; len(v) > 0 { if schema.Discriminator != nil { - if len(schema.Discriminator.Mapping) > 0 { - /* Find mapped object by ref */ - if valuemap, okcheck := value.(map[string]interface{}); okcheck { - pn := schema.Discriminator.PropertyName - if discriminatorVal, okcheck := valuemap[pn]; okcheck { + /* Find mapped object by ref */ + if valuemap, okcheck := value.(map[string]interface{}); okcheck { + pn := schema.Discriminator.PropertyName + if discriminatorVal, okcheck := valuemap[pn]; okcheck { + if len(schema.Discriminator.Mapping) > 0 { if mapref, okcheck := schema.Discriminator.Mapping[discriminatorVal.(string)]; okcheck { for _, item := range v { if item.Ref == mapref { @@ -851,6 +852,18 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val } } } + } else { + /* Assume implicit mapping on objectType as stated in Mapping Type Names section: + ``It is implied, that the property to which discriminator refers, contains the + name of the target schema. In the example above, the objectType property should + contain either simpleObject, or complexObject string.''*/ + for _, oneof := range schema.OneOf { + /* TODO: ugly.. should this be a property of the SchemaRef? */ + objectType := strings.ReplaceAll(oneof.Ref, "#/components/schemas/", "") + if objectType == discriminatorVal { + return oneof.Value.visitJSON(settings, value) + } + } } } } From b343c1d8f9c9c1e7411ef452d89fb76a18bd7123 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 13 Apr 2021 12:21:28 +0200 Subject: [PATCH 5/8] Cleaner [I'll squash this later] (cherry picked from commit 1b40d2988356320e9ebe4c916e20aec48401dcdc) (cherry picked from commit f4f135fe4fcb070152b5f178cfc36b56e00f5ef9) --- openapi3/schema.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index ac999ba6b..acf88f191 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -858,9 +858,7 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val name of the target schema. In the example above, the objectType property should contain either simpleObject, or complexObject string.''*/ for _, oneof := range schema.OneOf { - /* TODO: ugly.. should this be a property of the SchemaRef? */ - objectType := strings.ReplaceAll(oneof.Ref, "#/components/schemas/", "") - if objectType == discriminatorVal { + if strings.HasSuffix(oneof.Ref, discriminatorVal.(string)) { return oneof.Value.visitJSON(settings, value) } } From f9371470ba4e52d708b4280270e6d9d32b1b82bd Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Fri, 23 Apr 2021 15:11:20 +0200 Subject: [PATCH 6/8] Compliance --- openapi3/schema.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index acf88f191..90e3985c4 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -846,9 +846,9 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val if discriminatorVal, okcheck := valuemap[pn]; okcheck { if len(schema.Discriminator.Mapping) > 0 { if mapref, okcheck := schema.Discriminator.Mapping[discriminatorVal.(string)]; okcheck { - for _, item := range v { - if item.Ref == mapref { - return item.Value.visitJSON(settings, value) + for _, oneof := range v { + if oneof.Ref == mapref { + return oneof.Value.visitJSON(settings, value) } } } @@ -857,9 +857,9 @@ func (schema *Schema) visitSetOperations(settings *schemaValidationSettings, val ``It is implied, that the property to which discriminator refers, contains the name of the target schema. In the example above, the objectType property should contain either simpleObject, or complexObject string.''*/ - for _, oneof := range schema.OneOf { - if strings.HasSuffix(oneof.Ref, discriminatorVal.(string)) { - return oneof.Value.visitJSON(settings, value) + for _, v := range schema.OneOf { + if strings.HasSuffix(v.Ref, discriminatorVal.(string)) { + return v.Value.visitJSON(settings, value) } } } From 7800000ce1f0c48b465f94a03f1500aa9f584b27 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Fri, 23 Apr 2021 16:32:40 +0200 Subject: [PATCH 7/8] Revert "Fixup missing Test prefix" This reverts commit 9aa5c5ab1ae799d10db8a057fbb4fc436e33a3a9. --- openapi3filter/validate_request_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openapi3filter/validate_request_test.go b/openapi3filter/validate_request_test.go index f7e59f767..2c1c0b5cc 100644 --- a/openapi3filter/validate_request_test.go +++ b/openapi3filter/validate_request_test.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "net/http" - "testing" "github.com/getkin/kin-openapi/openapi3" "github.com/getkin/kin-openapi/openapi3filter" @@ -64,7 +63,7 @@ components: type: integer ` -func TestExample(t *testing.T) { +func Example() { loader := openapi3.NewSwaggerLoader() doc, err := loader.LoadSwaggerFromData([]byte(spec)) if err != nil { From 781e68f193ed4e6a94e599c632b3255f48dc419c Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Mon, 26 Apr 2021 09:28:30 +0200 Subject: [PATCH 8/8] Now test passes This is what schema.go:856 else is for Spec quote: ``It is implied, that the property to which discriminator refers, contains the name of the target schema. In the example above, the objectType property should contain either simpleObject, or complexObject string.''*/ --- openapi3filter/validate_request_test.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/openapi3filter/validate_request_test.go b/openapi3filter/validate_request_test.go index 2c1c0b5cc..dc23db544 100644 --- a/openapi3filter/validate_request_test.go +++ b/openapi3filter/validate_request_test.go @@ -107,26 +107,4 @@ func Example() { fmt.Println(err) } // Output: - // request body has an error: doesn't match the schema: Doesn't match schema "oneOf" - // Schema: - // { - // "discriminator": { - // "propertyName": "pet_type" - // }, - // "oneOf": [ - // { - // "$ref": "#/components/schemas/Cat" - // }, - // { - // "$ref": "#/components/schemas/Dog" - // } - // ] - // } - // - // Value: - // { - // "bark": true, - // "breed": "Dingo", - // "pet_type": "Cat" - // } }