@@ -35,7 +35,8 @@ const (
3535// OAS holds the upstream OAS definition as well as adds functionality like custom JSON marshalling.
3636type OAS struct {
3737 openapi3.T
38- mu sync.RWMutex
38+ mu sync.RWMutex
39+ secMu sync.RWMutex
3940}
4041
4142// MarshalJSON implements json.Marshaller.
@@ -137,29 +138,38 @@ func (s *OAS) GetTykStreamingExtension() *XTykStreaming {
137138 return nil
138139 }
139140
140- // Convert outside the lock (no shared state modified)
141- var xTykStreaming XTykStreaming
141+ var x XTykStreaming
142142
143- if rawTykStreaming , ok := ext .(json.RawMessage ); ok {
144- if err := json .Unmarshal (rawTykStreaming , & xTykStreaming ); err != nil {
143+ if raw , ok := ext .(json.RawMessage ); ok {
144+ if err := json .Unmarshal (raw , & x ); err != nil {
145145 return nil
146146 }
147- return & xTykStreaming
147+ s .secMu .Lock ()
148+ if s .Extensions != nil {
149+ s .Extensions [ExtensionTykStreaming ] = & x
150+ }
151+ s .secMu .Unlock ()
152+ return & x
148153 }
149154
150- if mapTykAPIGateway , ok := ext .(map [string ]interface {}); ok {
151- dbByte , err := json .Marshal (mapTykAPIGateway )
155+ if m , ok := ext .(map [string ]interface {}); ok {
156+ dbByte , err := json .Marshal (m )
152157 if err != nil {
153158 return nil
154159 }
155- if err := json .Unmarshal (dbByte , & xTykStreaming ); err != nil {
160+ if err := json .Unmarshal (dbByte , & x ); err != nil {
156161 return nil
157162 }
158- return & xTykStreaming
163+ s .secMu .Lock ()
164+ if s .Extensions != nil {
165+ s .Extensions [ExtensionTykStreaming ] = & x
166+ }
167+ s .secMu .Unlock ()
168+ return & x
159169 }
160170
161- if xTyk , ok := ext .(* XTykStreaming ); ok {
162- return xTyk
171+ if typed , ok := ext .(* XTykStreaming ); ok {
172+ return typed
163173 }
164174
165175 return nil
@@ -196,29 +206,38 @@ func (s *OAS) GetTykExtension() *XTykAPIGateway {
196206 return nil
197207 }
198208
199- // Convert outside the lock (no shared state modified)
200- var xTykAPIGateway XTykAPIGateway
209+ var x XTykAPIGateway
201210
202- if rawTykAPIGateway , ok := ext .(json.RawMessage ); ok {
203- if err := json .Unmarshal (rawTykAPIGateway , & xTykAPIGateway ); err != nil {
211+ if raw , ok := ext .(json.RawMessage ); ok {
212+ if err := json .Unmarshal (raw , & x ); err != nil {
204213 return nil
205214 }
206- return & xTykAPIGateway
215+ s .secMu .Lock ()
216+ if s .Extensions != nil {
217+ s .Extensions [ExtensionTykAPIGateway ] = & x
218+ }
219+ s .secMu .Unlock ()
220+ return & x
207221 }
208222
209- if mapTykAPIGateway , ok := ext .(map [string ]interface {}); ok {
210- dbByte , err := json .Marshal (mapTykAPIGateway )
223+ if m , ok := ext .(map [string ]interface {}); ok {
224+ dbByte , err := json .Marshal (m )
211225 if err != nil {
212226 return nil
213227 }
214- if err := json .Unmarshal (dbByte , & xTykAPIGateway ); err != nil {
228+ if err := json .Unmarshal (dbByte , & x ); err != nil {
215229 return nil
216230 }
217- return & xTykAPIGateway
231+ s .secMu .Lock ()
232+ if s .Extensions != nil {
233+ s .Extensions [ExtensionTykAPIGateway ] = & x
234+ }
235+ s .secMu .Unlock ()
236+ return & x
218237 }
219238
220- if xTyk , ok := ext .(* XTykAPIGateway ); ok {
221- return xTyk
239+ if typed , ok := ext .(* XTykAPIGateway ); ok {
240+ return typed
222241 }
223242
224243 return nil
@@ -252,20 +271,30 @@ func (s *OAS) getTykTokenAuth(name string) (token *Token) {
252271 return nil
253272 }
254273
255- s .mu .RLock ()
274+ s .secMu .RLock ()
256275 securityScheme := tykAuth .SecuritySchemes [name ]
257- s .mu .RUnlock ()
258-
259276 if securityScheme == nil {
277+ s .secMu .RUnlock ()
260278 return nil
261279 }
262-
263- token = & Token {}
264- if tokenVal , ok := securityScheme .(* Token ); ok {
265- return tokenVal
280+ if v , ok := securityScheme .(* Token ); ok {
281+ s .secMu .RUnlock ()
282+ return v
266283 }
284+ s .secMu .RUnlock ()
267285
286+ token = & Token {}
268287 toStructIfMap (securityScheme , token )
288+
289+ s .secMu .Lock ()
290+ if cur := tykAuth .SecuritySchemes [name ]; cur != nil {
291+ if already , ok := cur .(* Token ); ok {
292+ token = already
293+ } else {
294+ tykAuth .SecuritySchemes [name ] = token
295+ }
296+ }
297+ s .secMu .Unlock ()
269298 return token
270299}
271300
@@ -275,20 +304,30 @@ func (s *OAS) getTykJWTAuth(name string) (jwt *JWT) {
275304 return nil
276305 }
277306
278- s .mu .RLock ()
307+ s .secMu .RLock ()
279308 securityScheme := tykAuth .SecuritySchemes [name ]
280- s .mu .RUnlock ()
281-
282309 if securityScheme == nil {
310+ s .secMu .RUnlock ()
283311 return nil
284312 }
285-
286- jwt = & JWT {}
287- if jwtVal , ok := securityScheme .(* JWT ); ok {
288- return jwtVal
313+ if v , ok := securityScheme .(* JWT ); ok {
314+ s .secMu .RUnlock ()
315+ return v
289316 }
317+ s .secMu .RUnlock ()
290318
319+ jwt = & JWT {}
291320 toStructIfMap (securityScheme , jwt )
321+
322+ s .secMu .Lock ()
323+ if cur := tykAuth .SecuritySchemes [name ]; cur != nil {
324+ if already , ok := cur .(* JWT ); ok {
325+ jwt = already
326+ } else {
327+ tykAuth .SecuritySchemes [name ] = jwt
328+ }
329+ }
330+ s .secMu .Unlock ()
292331 return jwt
293332}
294333
@@ -300,20 +339,30 @@ func (s *OAS) getTykBasicAuth(name string) (basic *Basic) {
300339 return nil
301340 }
302341
303- s .mu .RLock ()
342+ s .secMu .RLock ()
304343 securityScheme := tykAuth .SecuritySchemes [name ]
305- s .mu .RUnlock ()
306-
307344 if securityScheme == nil {
345+ s .secMu .RUnlock ()
308346 return nil
309347 }
310-
311- basic = & Basic {}
312- if basicVal , ok := securityScheme .(* Basic ); ok {
313- return basicVal
348+ if v , ok := securityScheme .(* Basic ); ok {
349+ s .secMu .RUnlock ()
350+ return v
314351 }
352+ s .secMu .RUnlock ()
315353
354+ basic = & Basic {}
316355 toStructIfMap (securityScheme , basic )
356+
357+ s .secMu .Lock ()
358+ if cur := tykAuth .SecuritySchemes [name ]; cur != nil {
359+ if already , ok := cur .(* Basic ); ok {
360+ basic = already
361+ } else {
362+ tykAuth .SecuritySchemes [name ] = basic
363+ }
364+ }
365+ s .secMu .Unlock ()
317366 return basic
318367}
319368
@@ -323,20 +372,30 @@ func (s *OAS) getTykOAuthAuth(name string) (oauth *OAuth) {
323372 return nil
324373 }
325374
326- s .mu .RLock ()
375+ s .secMu .RLock ()
327376 securityScheme := tykAuth .SecuritySchemes [name ]
328- s .mu .RUnlock ()
329-
330377 if securityScheme == nil {
378+ s .secMu .RUnlock ()
331379 return nil
332380 }
333-
334- oauth = & OAuth {}
335- if oauthVal , ok := securityScheme .(* OAuth ); ok {
336- return oauthVal
381+ if v , ok := securityScheme .(* OAuth ); ok {
382+ s .secMu .RUnlock ()
383+ return v
337384 }
385+ s .secMu .RUnlock ()
338386
387+ oauth = & OAuth {}
339388 toStructIfMap (securityScheme , oauth )
389+
390+ s .secMu .Lock ()
391+ if cur := tykAuth .SecuritySchemes [name ]; cur != nil {
392+ if already , ok := cur .(* OAuth ); ok {
393+ oauth = already
394+ } else {
395+ tykAuth .SecuritySchemes [name ] = oauth
396+ }
397+ }
398+ s .secMu .Unlock ()
340399 return oauth
341400}
342401
@@ -346,20 +405,30 @@ func (s *OAS) getTykExternalOAuthAuth(name string) (externalOAuth *ExternalOAuth
346405 return nil
347406 }
348407
349- s .mu .RLock ()
408+ s .secMu .RLock ()
350409 securityScheme := tykAuth .SecuritySchemes [name ]
351- s .mu .RUnlock ()
352-
353410 if securityScheme == nil {
411+ s .secMu .RUnlock ()
354412 return nil
355413 }
356-
357- externalOAuth = & ExternalOAuth {}
358- if oauthVal , ok := securityScheme .(* ExternalOAuth ); ok { // ✅ FIXED - check securityScheme, not externalOAuth
359- return oauthVal
414+ if v , ok := securityScheme .(* ExternalOAuth ); ok {
415+ s .secMu .RUnlock ()
416+ return v
360417 }
418+ s .secMu .RUnlock ()
361419
420+ externalOAuth = & ExternalOAuth {}
362421 toStructIfMap (securityScheme , externalOAuth )
422+
423+ s .secMu .Lock ()
424+ if cur := tykAuth .SecuritySchemes [name ]; cur != nil {
425+ if already , ok := cur .(* ExternalOAuth ); ok {
426+ externalOAuth = already
427+ } else {
428+ tykAuth .SecuritySchemes [name ] = externalOAuth
429+ }
430+ }
431+ s .secMu .Unlock ()
363432 return externalOAuth
364433}
365434
0 commit comments