-
Notifications
You must be signed in to change notification settings - Fork 5
/
remove_elements.go
154 lines (141 loc) · 3.41 KB
/
remove_elements.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package vervet
import (
"regexp"
"github.com/getkin/kin-openapi/openapi3"
)
// ExcludePatterns defines patterns matching elements to be removed from an
// OpenAPI document.
type ExcludePatterns struct {
ExtensionPatterns []string
HeaderPatterns []string
Paths []string
}
type excluder struct {
doc *openapi3.T
extensionPatterns []*regexp.Regexp
headerPatterns []*regexp.Regexp
paths []string
}
// RemoveElements removes those elements from an OpenAPI document matching the
// given exclude patterns.
func RemoveElements(doc *openapi3.T, excludes ExcludePatterns) error {
ex := &excluder{
doc: doc,
extensionPatterns: make([]*regexp.Regexp, len(excludes.ExtensionPatterns)),
headerPatterns: make([]*regexp.Regexp, len(excludes.HeaderPatterns)),
paths: excludes.Paths,
}
for i, pat := range excludes.ExtensionPatterns {
re, err := regexp.Compile(pat)
if err != nil {
return err
}
ex.extensionPatterns[i] = re
}
for i, pat := range excludes.HeaderPatterns {
re, err := regexp.Compile(pat)
if err != nil {
return err
}
ex.headerPatterns[i] = re
}
// Remove excluded paths
excludedPaths := map[string]struct{}{}
for _, path := range doc.Paths.InMatchingOrder() {
if ex.isExcludedPath(path) {
excludedPaths[path] = struct{}{}
}
}
for path := range excludedPaths {
doc.Paths.Delete(path)
}
// Remove excluded elements
if err := ex.apply(); err != nil {
return err
}
return nil
}
func (ex *excluder) apply() error {
for _, pathItem := range ex.doc.Paths.Map() {
ex.applyExtensions(pathItem.Extensions)
for _, operation := range pathItem.Operations() {
ex.applyOperation(operation)
ex.applyExtensions(operation.Extensions)
if operation.Responses != nil {
ex.applyExtensions(operation.Responses.Extensions)
}
for _, responseRef := range operation.Responses.Map() {
ex.applyExtensions(responseRef.Extensions)
if responseRef.Value != nil {
ex.applyExtensions(responseRef.Value.Extensions)
}
}
}
}
return nil
}
func (ex *excluder) applyExtensions(extensions map[string]interface{}) {
for k := range extensions {
if ex.isExcludedExtension(k) {
delete(extensions, k)
}
}
}
func (ex *excluder) applyOperation(op *openapi3.Operation) {
var params []*openapi3.ParameterRef
for _, p := range op.Parameters {
if !ex.isExcludedHeaderParam(p) {
params = append(params, p)
}
}
op.Parameters = params
for _, resp := range op.Responses.Map() {
if resp.Value == nil {
continue
}
headers := openapi3.Headers{}
for headerName, header := range resp.Value.Headers {
var matched bool
for _, re := range ex.headerPatterns {
if re.MatchString(headerName) {
matched = true
break
}
}
if !matched {
headers[headerName] = header
}
}
resp.Value.Headers = headers
}
}
func (ex *excluder) isExcludedExtension(name string) bool {
for _, re := range ex.extensionPatterns {
if re.MatchString(name) {
return true
}
}
return false
}
func (ex *excluder) isExcludedPath(path string) bool {
for _, matchPath := range ex.paths {
if matchPath == path {
return true
}
}
return false
}
func (ex *excluder) isExcludedHeaderParam(p *openapi3.ParameterRef) bool {
if p.Value == nil {
return false
}
if p.Value.In != "header" {
return false
}
for _, re := range ex.headerPatterns {
if re.MatchString(p.Value.Name) {
return true
}
}
return false
}