From 8ee09a686203b5bfd6ccee1ca0608289fd540f43 Mon Sep 17 00:00:00 2001 From: Adrien CARLIER-MORY Date: Thu, 8 Jun 2023 17:47:06 +0200 Subject: [PATCH] openapi: Add support for external refs Set IsExternalRefsAllowed to true and provide a ReadFromURIFunc. Fixes #8067 --- tpl/openapi/openapi3/integration_test.go | 26 +++++++++++++----------- tpl/openapi/openapi3/openapi3.go | 22 +++++++++++++++++++- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/tpl/openapi/openapi3/integration_test.go b/tpl/openapi/openapi3/integration_test.go index d3be0eda94b..47f2fd700cc 100644 --- a/tpl/openapi/openapi3/integration_test.go +++ b/tpl/openapi/openapi3/integration_test.go @@ -37,18 +37,20 @@ servers: description: Optional server description, e.g. Internal staging server for testing paths: /users: - get: - summary: Returns a list of users. - description: Optional extended description in CommonMark or HTML. - responses: - '200': # status code - description: A JSON array of user names - content: - application/json: - schema: - type: array - items: - type: string + $ref: ./methods/get.yaml +-- assets/api/methods/get.yaml -- +get: + summary: Returns a list of users. + description: Optional extended description in CommonMark or HTML. + responses: + '200': # status code + description: A JSON array of user names + content: + application/json: + schema: + type: array + items: + type: string -- config.toml -- baseURL = 'http://example.com/' -- layouts/index.html -- diff --git a/tpl/openapi/openapi3/openapi3.go b/tpl/openapi/openapi3/openapi3.go index 38857dd9893..02954680b81 100644 --- a/tpl/openapi/openapi3/openapi3.go +++ b/tpl/openapi/openapi3/openapi3.go @@ -17,6 +17,8 @@ package openapi3 import ( "fmt" "io" + "net/url" + "strings" gyaml "github.com/ghodss/yaml" @@ -90,7 +92,25 @@ func (ns *Namespace) Unmarshal(r resource.UnmarshableResource) (*OpenAPIDocument return nil, err } - err = kopenapi3.NewLoader().ResolveRefsIn(s, nil) + loader := kopenapi3.NewLoader() + loader.IsExternalRefsAllowed = true + loader.ReadFromURIFunc = func(loader *kopenapi3.Loader, url *url.URL) ([]byte, error) { + relativePath := url.Path + + if strings.HasPrefix(url.Path, "./") { + relativePath = strings.TrimRightFunc(key, func(r rune) bool { return r != '/' }) + strings.TrimPrefix(url.Path, "./") + } + + file, err := ns.deps.SourceFilesystems.Assets.Fs.Open(relativePath) + if err != nil { + return nil, err + } + defer file.Close() + + return io.ReadAll(file) + } + + err = loader.ResolveRefsIn(s, nil) return &OpenAPIDocument{T: s}, err })