Skip to content

Commit c628a8a

Browse files
committed
[TT-16013] fix bug gateway panics when validating jwt claims - fix visor comments4
1 parent 8857f11 commit c628a8a

1 file changed

Lines changed: 127 additions & 58 deletions

File tree

apidef/oas/oas.go

Lines changed: 127 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ const (
3535
// OAS holds the upstream OAS definition as well as adds functionality like custom JSON marshalling.
3636
type 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

Comments
 (0)