github.com/snyk/vervet/v6@v6.2.4/inliner.go (about) 1 package vervet 2 3 import ( 4 "reflect" 5 6 "github.com/getkin/kin-openapi/openapi3" 7 "github.com/mitchellh/reflectwalk" 8 ) 9 10 // Inliner inlines the component. 11 type Inliner struct { 12 refs map[string]struct{} 13 } 14 15 // NewInliner returns a new Inliner instance. 16 func NewInliner() *Inliner { 17 return &Inliner{refs: map[string]struct{}{}} 18 } 19 20 // AddRef adds a JSON Reference URI to the set of references to be inlined. 21 func (in *Inliner) AddRef(ref string) { 22 in.refs[ref] = struct{}{} 23 } 24 25 // Inline inlines all the JSON References previously indicated with AddRef in 26 // the given OpenAPI document. 27 func (in *Inliner) Inline(doc *openapi3.T) error { 28 return reflectwalk.Walk(doc, in) 29 } 30 31 // Struct implements reflectwalk.StructWalker. 32 func (in *Inliner) Struct(v reflect.Value) error { 33 if !v.CanInterface() { 34 return nil 35 } 36 switch val := v.Interface().(type) { 37 case openapi3.SchemaRef: 38 if _, ok := in.refs[val.Ref]; ok { 39 valPointer := v.Addr().Interface().(*openapi3.SchemaRef) 40 refRemover := NewRefRemover(valPointer) 41 err := refRemover.RemoveRef() 42 if err != nil { 43 return err 44 } 45 } 46 case openapi3.ParameterRef: 47 if _, ok := in.refs[val.Ref]; ok { 48 valPointer := v.Addr().Interface().(*openapi3.ParameterRef) 49 refRemover := NewRefRemover(valPointer) 50 err := refRemover.RemoveRef() 51 if err != nil { 52 return err 53 } 54 } 55 case openapi3.HeaderRef: 56 if _, ok := in.refs[val.Ref]; ok { 57 valPointer := v.Addr().Interface().(*openapi3.HeaderRef) 58 refRemover := NewRefRemover(valPointer) 59 err := refRemover.RemoveRef() 60 if err != nil { 61 return err 62 } 63 } 64 case openapi3.RequestBodyRef: 65 if _, ok := in.refs[val.Ref]; ok { 66 valPointer := v.Addr().Interface().(*openapi3.RequestBodyRef) 67 refRemover := NewRefRemover(valPointer) 68 err := refRemover.RemoveRef() 69 if err != nil { 70 return err 71 } 72 } 73 case openapi3.ResponseRef: 74 if _, ok := in.refs[val.Ref]; ok { 75 valPointer := v.Addr().Interface().(*openapi3.ResponseRef) 76 refRemover := NewRefRemover(valPointer) 77 err := refRemover.RemoveRef() 78 if err != nil { 79 return err 80 } 81 } 82 case openapi3.SecuritySchemeRef: 83 if _, ok := in.refs[val.Ref]; ok { 84 valPointer := v.Addr().Interface().(*openapi3.SecuritySchemeRef) 85 refRemover := NewRefRemover(valPointer) 86 err := refRemover.RemoveRef() 87 if err != nil { 88 return err 89 } 90 } 91 case openapi3.ExampleRef: 92 if _, ok := in.refs[val.Ref]; ok { 93 valPointer := v.Addr().Interface().(*openapi3.ExampleRef) 94 refRemover := NewRefRemover(valPointer) 95 err := refRemover.RemoveRef() 96 if err != nil { 97 return err 98 } 99 } 100 case openapi3.LinkRef: 101 if _, ok := in.refs[val.Ref]; ok { 102 valPointer := v.Addr().Interface().(*openapi3.LinkRef) 103 refRemover := NewRefRemover(valPointer) 104 err := refRemover.RemoveRef() 105 if err != nil { 106 return err 107 } 108 } 109 case openapi3.CallbackRef: 110 if _, ok := in.refs[val.Ref]; ok { 111 valPointer := v.Addr().Interface().(*openapi3.CallbackRef) 112 refRemover := NewRefRemover(valPointer) 113 err := refRemover.RemoveRef() 114 if err != nil { 115 return err 116 } 117 } 118 } 119 return nil 120 } 121 122 // StructField implements reflectwalk.StructWalker. 123 func (in *Inliner) StructField(field reflect.StructField, v reflect.Value) error { 124 return nil 125 } 126 127 // RefRemover removes the ref from the component. 128 type RefRemover struct { 129 target interface{} 130 } 131 132 // NewRefRemover returns a new RefRemover instance. 133 func NewRefRemover(target interface{}) *RefRemover { 134 return &RefRemover{target: target} 135 } 136 137 // RemoveRef removes all $ref locations from an OpenAPI document object 138 // fragment. If the reference has already been resolved, this has the effect of 139 // "inlining" the formerly referenced object when serializing the OpenAPI 140 // document. 141 func (rr *RefRemover) RemoveRef() error { 142 return reflectwalk.Walk(rr.target, rr) 143 } 144 145 // Struct implements reflectwalk.StructWalker. 146 func (rr *RefRemover) Struct(v reflect.Value) error { 147 if !v.CanInterface() { 148 return nil 149 } 150 switch v.Interface().(type) { 151 case openapi3.SchemaRef: 152 valPointer := v.Addr().Interface().(*openapi3.SchemaRef) 153 valPointer.Ref = "" 154 case openapi3.ParameterRef: 155 valPointer := v.Addr().Interface().(*openapi3.ParameterRef) 156 valPointer.Ref = "" 157 case openapi3.HeaderRef: 158 valPointer := v.Addr().Interface().(*openapi3.HeaderRef) 159 valPointer.Ref = "" 160 case openapi3.RequestBodyRef: 161 valPointer := v.Addr().Interface().(*openapi3.RequestBodyRef) 162 valPointer.Ref = "" 163 case openapi3.ResponseRef: 164 valPointer := v.Addr().Interface().(*openapi3.ResponseRef) 165 valPointer.Ref = "" 166 case openapi3.SecuritySchemeRef: 167 valPointer := v.Addr().Interface().(*openapi3.SecuritySchemeRef) 168 valPointer.Ref = "" 169 case openapi3.ExampleRef: 170 valPointer := v.Addr().Interface().(*openapi3.ExampleRef) 171 valPointer.Ref = "" 172 case openapi3.LinkRef: 173 valPointer := v.Addr().Interface().(*openapi3.LinkRef) 174 valPointer.Ref = "" 175 case openapi3.CallbackRef: 176 valPointer := v.Addr().Interface().(*openapi3.CallbackRef) 177 valPointer.Ref = "" 178 } 179 180 return nil 181 } 182 183 // StructField implements reflectwalk.StructWalker. 184 func (rr *RefRemover) StructField(field reflect.StructField, v reflect.Value) error { 185 return nil 186 }