Skip to content

Commit eb6d2a2

Browse files
committed
[TT-16013] fix bug gateway panics when validating jwt claims - visor comments
1 parent e96e3eb commit eb6d2a2

2 files changed

Lines changed: 80 additions & 76 deletions

File tree

apidef/oas/authentication.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,41 @@ func (ss *SecuritySchemes) Get(key string) (interface{}, bool) {
268268
return value, ok
269269
}
270270

271+
// GetOrConvert fetches a scheme by name. If the stored value is a map[string]interface{},
272+
// it converts it into the concrete struct provided via 'out', stores it back once, and returns it.
273+
// Returns (value, true) if found; (nil, false) if missing.
274+
func (ss *SecuritySchemes) GetOrConvert(name string, out interface{}) (interface{}, bool) {
275+
if ss == nil {
276+
return nil, false
277+
}
278+
ss.mutex.RLock()
279+
v, ok := ss.container[name]
280+
ss.mutex.RUnlock()
281+
if !ok {
282+
return nil, false
283+
}
284+
if reflect.TypeOf(v) == reflect.TypeOf(out) {
285+
return v, true
286+
}
287+
288+
ss.mutex.Lock()
289+
defer ss.mutex.Unlock()
290+
291+
v, ok = ss.container[name]
292+
if !ok {
293+
return nil, false
294+
}
295+
if reflect.TypeOf(v) == reflect.TypeOf(out) {
296+
return v, true
297+
}
298+
299+
if toStructIfMap(v, out) {
300+
ss.container[name] = out
301+
return out, true
302+
}
303+
return out, true
304+
}
305+
271306
func (ss *SecuritySchemes) Delete(key string) {
272307
if ss == nil {
273308
return

apidef/oas/oas.go

Lines changed: 45 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -221,111 +221,80 @@ func (s *OAS) getTykAuthentication() (authentication *Authentication) {
221221
}
222222

223223
func (s *OAS) getTykTokenAuth(name string) (token *Token) {
224-
securityScheme := s.getTykSecurityScheme(name)
225-
if securityScheme == nil {
226-
return
227-
}
228-
224+
ss := s.getTykSecuritySchemes()
229225
token = &Token{}
230-
if tokenVal, ok := securityScheme.(*Token); ok {
231-
token = tokenVal
232-
} else {
233-
toStructIfMap(securityScheme, token)
226+
if v, ok := ss.GetOrConvert(name, token); ok {
227+
if t, ok := v.(*Token); ok {
228+
return t
229+
}
234230
}
235-
236-
s.getTykSecuritySchemes().Set(name, token)
237-
238-
return
231+
return token
239232
}
240233

241234
func (s *OAS) getTykJWTAuth(name string) (jwt *JWT) {
242-
securityScheme := s.getTykSecurityScheme(name)
243-
if securityScheme == nil {
244-
return
245-
}
246-
235+
ss := s.getTykSecuritySchemes()
247236
jwt = &JWT{}
248-
if jwtVal, ok := securityScheme.(*JWT); ok {
249-
jwt = jwtVal
250-
} else {
251-
toStructIfMap(securityScheme, jwt)
237+
if v, ok := ss.GetOrConvert(name, jwt); ok {
238+
if j, ok := v.(*JWT); ok {
239+
return j
240+
}
252241
}
253-
254-
s.getTykSecuritySchemes().Set(name, jwt)
255-
256-
return
242+
return jwt
257243
}
258244

259-
// getTykBasicAuth retrieves the Basic auth configuration from Tyk extension.
260-
// It handles both typed (*Basic) and untyped (map[string]interface{}) security schemes.
261-
// When an untyped scheme is found, it converts it to *Basic and caches the result.
245+
// getTykBasicAuth retrieves the Basic auth configuration from the Tyk extension.
246+
// Accepts both typed (*Basic) and untyped (map[string]interface{}) schemes.
247+
// Untyped values are converted and cached via SecuritySchemes.GetOrConvert.
262248
func (s *OAS) getTykBasicAuth(name string) (basic *Basic) {
249+
ss := s.getTykSecuritySchemes()
263250
basic = &Basic{}
264-
265-
securityScheme := s.getTykSecurityScheme(name)
266-
if securityScheme == nil {
267-
return
268-
}
269-
270-
if basicVal, ok := securityScheme.(*Basic); ok {
271-
basic = basicVal
272-
} else {
273-
// Security scheme is stored as map[string]interface{}, convert it to Basic struct
274-
if toStructIfMap(securityScheme, basic) {
275-
// Cache the converted struct for future use
276-
s.getTykSecuritySchemes().Set(name, basic)
251+
if v, ok := ss.GetOrConvert(name, basic); ok {
252+
if b, ok := v.(*Basic); ok {
253+
return b
277254
}
278255
}
279-
280-
return
256+
return basic
281257
}
282258

283259
func (s *OAS) getTykOAuthAuth(name string) (oauth *OAuth) {
284-
securityScheme := s.getTykSecurityScheme(name)
285-
if securityScheme == nil {
286-
return
287-
}
288-
260+
ss := s.getTykSecuritySchemes()
289261
oauth = &OAuth{}
290-
if oauthVal, ok := securityScheme.(*OAuth); ok {
291-
oauth = oauthVal
292-
} else {
293-
toStructIfMap(securityScheme, oauth)
262+
if v, ok := ss.GetOrConvert(name, oauth); ok {
263+
if o, ok := v.(*OAuth); ok {
264+
return o
265+
}
294266
}
295-
296-
s.getTykSecuritySchemes().Set(name, oauth)
297-
298-
return
267+
return oauth
299268
}
300269

301270
func (s *OAS) getTykExternalOAuthAuth(name string) (externalOAuth *ExternalOAuth) {
302-
securityScheme := s.getTykSecurityScheme(name)
303-
if securityScheme == nil {
304-
return
305-
}
306-
271+
ss := s.getTykSecuritySchemes()
307272
externalOAuth = &ExternalOAuth{}
308-
if oauthVal, ok := securityScheme.(*ExternalOAuth); ok {
309-
externalOAuth = oauthVal
310-
} else {
311-
toStructIfMap(securityScheme, externalOAuth)
273+
if v, ok := ss.GetOrConvert(name, externalOAuth); ok {
274+
if eo, ok := v.(*ExternalOAuth); ok {
275+
return eo
276+
}
312277
}
313-
314-
s.getTykSecuritySchemes().Set(name, externalOAuth)
315-
316-
return
278+
return externalOAuth
317279
}
318280

319-
func (s *OAS) getTykSecuritySchemes() (securitySchemes *SecuritySchemes) {
320-
if s.getTykAuthentication() != nil {
321-
securitySchemes = s.getTykAuthentication().SecuritySchemes
281+
func (s *OAS) getTykSecuritySchemes() *SecuritySchemes {
282+
ext := s.GetTykExtension()
283+
if ext == nil {
284+
ext = &XTykAPIGateway{}
285+
s.SetTykExtension(ext)
322286
}
323287

324-
if securitySchemes == nil {
325-
return NewSecuritySchemes()
288+
// Server is a value field; ensure Authentication exists.
289+
if ext.Server.Authentication == nil {
290+
ext.Server.Authentication = &Authentication{}
291+
}
292+
293+
if ext.Server.Authentication.SecuritySchemes == nil {
294+
ext.Server.Authentication.SecuritySchemes = NewSecuritySchemes()
326295
}
327296

328-
return securitySchemes
297+
return ext.Server.Authentication.SecuritySchemes
329298
}
330299

331300
func (s *OAS) getTykSecurityScheme(name string) interface{} {

0 commit comments

Comments
 (0)