Skip to content

Commit 4e7d031

Browse files
authored
openapi3: correct implementations of JSONLookup (#876)
1 parent c1681a9 commit 4e7d031

File tree

12 files changed

+163
-166
lines changed

12 files changed

+163
-166
lines changed

openapi3/callback.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,9 @@ package openapi3
22

33
import (
44
"context"
5-
"fmt"
65
"sort"
7-
8-
"github.com/go-openapi/jsonpointer"
96
)
107

11-
type Callbacks map[string]*CallbackRef
12-
13-
var _ jsonpointer.JSONPointable = (*Callbacks)(nil)
14-
15-
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
16-
func (c Callbacks) JSONLookup(token string) (interface{}, error) {
17-
ref, ok := c[token]
18-
if ref == nil || !ok {
19-
return nil, fmt.Errorf("object has no field %q", token)
20-
}
21-
22-
if ref.Ref != "" {
23-
return &Ref{Ref: ref.Ref}, nil
24-
}
25-
return ref.Value, nil
26-
}
27-
288
// Callback is specified by OpenAPI/Swagger standard version 3.
299
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callback-object
3010
type Callback map[string]*PathItem

openapi3/components.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ import (
55
"encoding/json"
66
"fmt"
77
"sort"
8+
9+
"github.com/go-openapi/jsonpointer"
10+
)
11+
12+
type (
13+
Callbacks map[string]*CallbackRef
14+
Examples map[string]*ExampleRef
15+
Headers map[string]*HeaderRef
16+
Links map[string]*LinkRef
17+
ParametersMap map[string]*ParameterRef
18+
RequestBodies map[string]*RequestBodyRef
19+
ResponseBodies map[string]*ResponseRef
20+
Schemas map[string]*SchemaRef
21+
SecuritySchemes map[string]*SecuritySchemeRef
822
)
923

1024
// Components is specified by OpenAPI/Swagger standard version 3.
@@ -228,3 +242,120 @@ func (components *Components) Validate(ctx context.Context, opts ...ValidationOp
228242

229243
return validateExtensions(ctx, components.Extensions)
230244
}
245+
246+
var _ jsonpointer.JSONPointable = (*Schemas)(nil)
247+
248+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
249+
func (m Schemas) JSONLookup(token string) (interface{}, error) {
250+
if v, ok := m[token]; !ok || v == nil {
251+
return nil, fmt.Errorf("no schema %q", token)
252+
} else if ref := v.Ref; ref != "" {
253+
return &Ref{Ref: ref}, nil
254+
} else {
255+
return v.Value, nil
256+
}
257+
}
258+
259+
var _ jsonpointer.JSONPointable = (*ParametersMap)(nil)
260+
261+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
262+
func (m ParametersMap) JSONLookup(token string) (interface{}, error) {
263+
if v, ok := m[token]; !ok || v == nil {
264+
return nil, fmt.Errorf("no parameter %q", token)
265+
} else if ref := v.Ref; ref != "" {
266+
return &Ref{Ref: ref}, nil
267+
} else {
268+
return v.Value, nil
269+
}
270+
}
271+
272+
var _ jsonpointer.JSONPointable = (*Headers)(nil)
273+
274+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
275+
func (m Headers) JSONLookup(token string) (interface{}, error) {
276+
if v, ok := m[token]; !ok || v == nil {
277+
return nil, fmt.Errorf("no header %q", token)
278+
} else if ref := v.Ref; ref != "" {
279+
return &Ref{Ref: ref}, nil
280+
} else {
281+
return v.Value, nil
282+
}
283+
}
284+
285+
var _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil)
286+
287+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
288+
func (m RequestBodies) JSONLookup(token string) (interface{}, error) {
289+
if v, ok := m[token]; !ok || v == nil {
290+
return nil, fmt.Errorf("no request body %q", token)
291+
} else if ref := v.Ref; ref != "" {
292+
return &Ref{Ref: ref}, nil
293+
} else {
294+
return v.Value, nil
295+
}
296+
}
297+
298+
var _ jsonpointer.JSONPointable = (*ResponseRef)(nil)
299+
300+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
301+
func (m ResponseBodies) JSONLookup(token string) (interface{}, error) {
302+
if v, ok := m[token]; !ok || v == nil {
303+
return nil, fmt.Errorf("no response body %q", token)
304+
} else if ref := v.Ref; ref != "" {
305+
return &Ref{Ref: ref}, nil
306+
} else {
307+
return v.Value, nil
308+
}
309+
}
310+
311+
var _ jsonpointer.JSONPointable = (*SecuritySchemes)(nil)
312+
313+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
314+
func (m SecuritySchemes) JSONLookup(token string) (interface{}, error) {
315+
if v, ok := m[token]; !ok || v == nil {
316+
return nil, fmt.Errorf("no security scheme body %q", token)
317+
} else if ref := v.Ref; ref != "" {
318+
return &Ref{Ref: ref}, nil
319+
} else {
320+
return v.Value, nil
321+
}
322+
}
323+
324+
var _ jsonpointer.JSONPointable = (*Examples)(nil)
325+
326+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
327+
func (m Examples) JSONLookup(token string) (interface{}, error) {
328+
if v, ok := m[token]; !ok || v == nil {
329+
return nil, fmt.Errorf("no example body %q", token)
330+
} else if ref := v.Ref; ref != "" {
331+
return &Ref{Ref: ref}, nil
332+
} else {
333+
return v.Value, nil
334+
}
335+
}
336+
337+
var _ jsonpointer.JSONPointable = (*Links)(nil)
338+
339+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
340+
func (m Links) JSONLookup(token string) (interface{}, error) {
341+
if v, ok := m[token]; !ok || v == nil {
342+
return nil, fmt.Errorf("no link body %q", token)
343+
} else if ref := v.Ref; ref != "" {
344+
return &Ref{Ref: ref}, nil
345+
} else {
346+
return v.Value, nil
347+
}
348+
}
349+
350+
var _ jsonpointer.JSONPointable = (*Callbacks)(nil)
351+
352+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
353+
func (m Callbacks) JSONLookup(token string) (interface{}, error) {
354+
if v, ok := m[token]; !ok || v == nil {
355+
return nil, fmt.Errorf("no callback body %q", token)
356+
} else if ref := v.Ref; ref != "" {
357+
return &Ref{Ref: ref}, nil
358+
} else {
359+
return v.Value, nil
360+
}
361+
}

openapi3/example.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,8 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7-
"fmt"
8-
9-
"github.com/go-openapi/jsonpointer"
107
)
118

12-
type Examples map[string]*ExampleRef
13-
14-
var _ jsonpointer.JSONPointable = (*Examples)(nil)
15-
16-
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
17-
func (e Examples) JSONLookup(token string) (interface{}, error) {
18-
ref, ok := e[token]
19-
if ref == nil || !ok {
20-
return nil, fmt.Errorf("object has no field %q", token)
21-
}
22-
23-
if ref.Ref != "" {
24-
return &Ref{Ref: ref.Ref}, nil
25-
}
26-
return ref.Value, nil
27-
}
28-
299
// Example is specified by OpenAPI/Swagger 3.0 standard.
3010
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#example-object
3111
type Example struct {

openapi3/header.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,6 @@ import (
88
"github.com/go-openapi/jsonpointer"
99
)
1010

11-
type Headers map[string]*HeaderRef
12-
13-
var _ jsonpointer.JSONPointable = (*Headers)(nil)
14-
15-
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
16-
func (h Headers) JSONLookup(token string) (interface{}, error) {
17-
ref, ok := h[token]
18-
if ref == nil || !ok {
19-
return nil, fmt.Errorf("object has no field %q", token)
20-
}
21-
22-
if ref.Ref != "" {
23-
return &Ref{Ref: ref.Ref}, nil
24-
}
25-
return ref.Value, nil
26-
}
27-
2811
// Header is specified by OpenAPI/Swagger 3.0 standard.
2912
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#header-object
3013
type Header struct {

openapi3/link.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,8 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8-
9-
"github.com/go-openapi/jsonpointer"
108
)
119

12-
type Links map[string]*LinkRef
13-
14-
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
15-
func (links Links) JSONLookup(token string) (interface{}, error) {
16-
ref, ok := links[token]
17-
if !ok {
18-
return nil, fmt.Errorf("object has no field %q", token)
19-
}
20-
21-
if ref != nil && ref.Ref != "" {
22-
return &Ref{Ref: ref.Ref}, nil
23-
}
24-
return ref.Value, nil
25-
}
26-
27-
var _ jsonpointer.JSONPointable = (*Links)(nil)
28-
2910
// Link is specified by OpenAPI/Swagger standard version 3.
3011
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#link-object
3112
type Link struct {

openapi3/openapi3.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
9+
"github.com/go-openapi/jsonpointer"
810
)
911

1012
// T is the root of an OpenAPI v3 document
@@ -24,6 +26,33 @@ type T struct {
2426
visited visitedComponent
2527
}
2628

29+
var _ jsonpointer.JSONPointable = (*T)(nil)
30+
31+
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
32+
func (doc *T) JSONLookup(token string) (interface{}, error) {
33+
switch token {
34+
case "openapi":
35+
return doc.OpenAPI, nil
36+
case "components":
37+
return doc.Components, nil
38+
case "info":
39+
return doc.Info, nil
40+
case "paths":
41+
return doc.Paths, nil
42+
case "security":
43+
return doc.Security, nil
44+
case "servers":
45+
return doc.Servers, nil
46+
case "tags":
47+
return doc.Tags, nil
48+
case "externalDocs":
49+
return doc.ExternalDocs, nil
50+
}
51+
52+
v, _, err := jsonpointer.GetForToken(doc.Extensions, token)
53+
return v, err
54+
}
55+
2756
// MarshalJSON returns the JSON encoding of T.
2857
func (doc T) MarshalJSON() ([]byte, error) {
2958
m := make(map[string]interface{}, 4+len(doc.Extensions))

openapi3/parameter.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,6 @@ import (
1111
"github.com/go-openapi/jsonpointer"
1212
)
1313

14-
type ParametersMap map[string]*ParameterRef
15-
16-
var _ jsonpointer.JSONPointable = (*ParametersMap)(nil)
17-
18-
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
19-
func (p ParametersMap) JSONLookup(token string) (interface{}, error) {
20-
ref, ok := p[token]
21-
if ref == nil || !ok {
22-
return nil, fmt.Errorf("object has no field %q", token)
23-
}
24-
25-
if ref.Ref != "" {
26-
return &Ref{Ref: ref.Ref}, nil
27-
}
28-
return ref.Value, nil
29-
}
30-
3114
// Parameters is specified by OpenAPI/Swagger 3.0 standard.
3215
type Parameters []*ParameterRef
3316

@@ -39,13 +22,11 @@ func (p Parameters) JSONLookup(token string) (interface{}, error) {
3922
if err != nil {
4023
return nil, err
4124
}
42-
4325
if index < 0 || index >= len(p) {
4426
return nil, fmt.Errorf("index %d out of bounds of array of length %d", index, len(p))
4527
}
4628

4729
ref := p[index]
48-
4930
if ref != nil && ref.Ref != "" {
5031
return &Ref{Ref: ref.Ref}, nil
5132
}

openapi3/refs_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,15 @@ components:
216216
- type: integer
217217
format: int32
218218
`[1:])
219+
219220
loader := NewLoader()
220221
doc, err := loader.LoadFromData(spec)
221222
require.NoError(t, err)
222223
require.NotNil(t, doc)
224+
223225
err = doc.Validate(loader.Context)
224226
require.NoError(t, err)
227+
225228
var ptr jsonpointer.Pointer
226229
var v interface{}
227230
var kind reflect.Kind

openapi3/request_body.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,8 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7-
"fmt"
8-
9-
"github.com/go-openapi/jsonpointer"
107
)
118

12-
type RequestBodies map[string]*RequestBodyRef
13-
14-
var _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil)
15-
16-
// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable
17-
func (r RequestBodies) JSONLookup(token string) (interface{}, error) {
18-
ref, ok := r[token]
19-
if !ok {
20-
return nil, fmt.Errorf("object has no field %q", token)
21-
}
22-
23-
if ref != nil && ref.Ref != "" {
24-
return &Ref{Ref: ref.Ref}, nil
25-
}
26-
return ref.Value, nil
27-
}
28-
299
// RequestBody is specified by OpenAPI/Swagger 3.0 standard.
3010
// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#request-body-object
3111
type RequestBody struct {

0 commit comments

Comments
 (0)