From def670dbba718c232d6a8bce751205c6062c6dfb Mon Sep 17 00:00:00 2001 From: Dave Shanley Date: Mon, 20 Feb 2023 05:54:28 -0500 Subject: [PATCH] Adressed comments from @n0rig on #83 Fixed digital ocean test fix, bumped comments up a little --- datamodel/document_config.go | 3 ++ datamodel/high/v3/document_test.go | 46 ++++++++++++++++++++++++++---- document.go | 7 +++++ resolver/resolver.go | 2 +- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/datamodel/document_config.go b/datamodel/document_config.go index d44ad1b..26a4df4 100644 --- a/datamodel/document_config.go +++ b/datamodel/document_config.go @@ -7,6 +7,9 @@ import "net/url" // DocumentConfiguration is used to configure the document creation process. It was added in v0.6.0 to allow // for more fine-grained control over controls and new features. +// +// The default configuration will set AllowFileReferences to false and AllowRemoteReferences to false, which means +// any non-local (local being the specification, not the file system) references, will be ignored. type DocumentConfiguration struct { // if the document uses relative file references, this is the base url to use when resolving them. BaseURL *url.URL diff --git a/datamodel/high/v3/document_test.go b/datamodel/high/v3/document_test.go index 26284b2..1b79301 100644 --- a/datamodel/high/v3/document_test.go +++ b/datamodel/high/v3/document_test.go @@ -4,8 +4,8 @@ package v3 import ( - "fmt" "io/ioutil" + "net/url" "testing" "github.com/pb33f/libopenapi/datamodel" @@ -395,19 +395,52 @@ func TestAsanaAsDoc(t *testing.T) { panic("broken something") } d := NewDocument(lowDoc) - fmt.Println(d) + assert.NotNil(t, d) + assert.Equal(t, 118, len(d.Paths.PathItems)) } func TestDigitalOceanAsDoc(t *testing.T) { - data, _ := ioutil.ReadFile("../../../test_specs/asana.yaml") + data, _ := ioutil.ReadFile("../../../test_specs/digitalocean.yaml") info, _ := datamodel.ExtractSpecInfo(data) var err []error - lowDoc, err = lowv3.CreateDocument(info) + + baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/main/specification") + config := datamodel.DocumentConfiguration{ + AllowFileReferences: true, + AllowRemoteReferences: true, + BaseURL: baseURL, + } + + lowDoc, err = lowv3.CreateDocumentFromConfig(info, &config) if err != nil { panic("broken something") } d := NewDocument(lowDoc) - fmt.Println(d) + assert.NotNil(t, d) + assert.Equal(t, 183, len(d.Paths.PathItems)) + +} + +func TestDigitalOceanAsDocFromSHA(t *testing.T) { + data, _ := ioutil.ReadFile("../../../test_specs/digitalocean.yaml") + info, _ := datamodel.ExtractSpecInfo(data) + var err []error + + baseURL, _ := url.Parse("https://raw.githubusercontent.com/digitalocean/openapi/82e1d558e15a59edc1d47d2c5544e7138f5b3cbf/specification") + config := datamodel.DocumentConfiguration{ + AllowFileReferences: true, + AllowRemoteReferences: true, + BaseURL: baseURL, + } + + lowDoc, err = lowv3.CreateDocumentFromConfig(info, &config) + if err != nil { + panic("broken something") + } + d := NewDocument(lowDoc) + assert.NotNil(t, d) + assert.Equal(t, 183, len(d.Paths.PathItems)) + } func TestPetstoreAsDoc(t *testing.T) { @@ -419,7 +452,8 @@ func TestPetstoreAsDoc(t *testing.T) { panic("broken something") } d := NewDocument(lowDoc) - fmt.Println(d) + assert.NotNil(t, d) + assert.Equal(t, 13, len(d.Paths.PathItems)) } func TestCircularReferencesDoc(t *testing.T) { diff --git a/document.go b/document.go index 44b3b0f..47cd52b 100644 --- a/document.go +++ b/document.go @@ -83,6 +83,13 @@ type DocumentModel[T v2high.Swagger | v3high.Document] struct { // // After creating a Document, the option to build a model becomes available, in either V2 or V3 flavors. The models // are about 70% different between Swagger and OpenAPI 3, which is why two different models are available. +// +// This function will automatically follow (meaning load) any file or remote references that are found anywhere. +// Which means recursively also, like a spider, it will follow every reference found, local or remote. +// +// If this isn't the behavior you want, or that you feel this is a potential security risk, +// then you can use the NewDocumentWithConfiguration() function instead, which allows you to set a configuration that +// will allow you to control if file or remote references are allowed. func NewDocument(specByteArray []byte) (Document, error) { info, err := datamodel.ExtractSpecInfo(specByteArray) if err != nil { diff --git a/resolver/resolver.go b/resolver/resolver.go index fc10175..01d63f4 100644 --- a/resolver/resolver.go +++ b/resolver/resolver.go @@ -111,7 +111,7 @@ func (resolver *Resolver) GetIndexesVisited() int { return resolver.indexesVisited } -// +// GetRelativesSeen returns the number of siblings (nodes at the same level) seen for each reference found. func (resolver *Resolver) GetRelativesSeen() int { return resolver.relativesSeen }