/
parser.go
73 lines (69 loc) · 2.2 KB
/
parser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package oapi
import (
"context"
"crypto/sha1"
"encoding/json"
"fmt"
"github.com/bhatti/api-mock-service/internal/fuzz"
"github.com/bhatti/api-mock-service/internal/types"
"github.com/getkin/kin-openapi/openapi3"
)
// Parse parses Open-API and generates api scenarios
func Parse(ctx context.Context, data []byte, dataTemplate fuzz.DataTemplateRequest) (specs []*APISpec, err error) {
loader := &openapi3.Loader{Context: ctx, IsExternalRefsAllowed: true}
doc, err := loader.LoadFromData(data)
if err != nil {
doc = &openapi3.T{}
if err = json.Unmarshal(data, doc); err != nil {
return nil, fmt.Errorf("failed to parse open-api with size %d due to %w", len(data), err)
}
if err := loader.ResolveRefsIn(doc, nil); err != nil {
return nil, fmt.Errorf("failed to resolve refs in open-api with size %d due to %w", len(data), err)
}
}
var title string
if doc.Info != nil {
title = doc.Info.Title
if doc.Info.Version != "" {
title += "_V" + doc.Info.Version
}
}
if title == "" {
title = fmt.Sprintf("OAPI_%x", sha1.Sum(data))
}
for k, v := range doc.Paths {
for _, spec := range ParseAPISpec(title, types.Delete, k, v.Delete, dataTemplate) {
specs = append(specs, spec)
}
for _, spec := range ParseAPISpec(title, types.Get, k, v.Get, dataTemplate) {
specs = append(specs, spec)
}
for _, spec := range ParseAPISpec(title, types.Post, k, v.Post, dataTemplate) {
specs = append(specs, spec)
}
for _, spec := range ParseAPISpec(title, types.Put, k, v.Put, dataTemplate) {
specs = append(specs, spec)
}
for _, spec := range ParseAPISpec(title, types.Patch, k, v.Patch, dataTemplate) {
specs = append(specs, spec)
}
}
for _, ref := range doc.Components.SecuritySchemes {
for _, spec := range specs {
prop := Property{
Name: ref.Value.Name,
Description: ref.Value.Description,
Type: ref.Value.Type,
In: ref.Value.In,
Pattern: ref.Value.BearerFormat,
}
if ref.Value.In == "header" {
spec.Request.Headers = append(spec.Request.Headers, prop)
} else if ref.Value.In == "query" {
spec.Request.QueryParams = append(spec.Request.Headers, prop)
}
spec.SecuritySchemes = doc.Components.SecuritySchemes
}
}
return
}