@@ -435,6 +435,128 @@ func TestOIDCController(t *testing.T) {
435435 assert .False (t , ok , "Did not expect email claim in userinfo response" )
436436 },
437437 },
438+ {
439+ description : "Ensure userinfo forbids access with no authorization header" ,
440+ middlewares : []gin.HandlerFunc {},
441+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
442+ req := httptest .NewRequest ("GET" , "/api/oidc/userinfo" , nil )
443+ router .ServeHTTP (recorder , req )
444+ assert .Equal (t , 401 , recorder .Code )
445+
446+ var res map [string ]any
447+ err := json .Unmarshal (recorder .Body .Bytes (), & res )
448+ assert .NoError (t , err )
449+ assert .Equal (t , "invalid_request" , res ["error" ])
450+ },
451+ },
452+ {
453+ description : "Ensure userinfo forbids access with malformed authorization header" ,
454+ middlewares : []gin.HandlerFunc {},
455+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
456+ req := httptest .NewRequest ("GET" , "/api/oidc/userinfo" , nil )
457+ req .Header .Set ("Authorization" , "Bearer" )
458+ router .ServeHTTP (recorder , req )
459+ assert .Equal (t , 401 , recorder .Code )
460+
461+ var res map [string ]any
462+ err := json .Unmarshal (recorder .Body .Bytes (), & res )
463+ assert .NoError (t , err )
464+ assert .Equal (t , "invalid_request" , res ["error" ])
465+ },
466+ },
467+ {
468+ description : "Ensure userinfo forbids access with invalid token type" ,
469+ middlewares : []gin.HandlerFunc {},
470+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
471+ req := httptest .NewRequest ("GET" , "/api/oidc/userinfo" , nil )
472+ req .Header .Set ("Authorization" , "Basic some-token" )
473+ router .ServeHTTP (recorder , req )
474+ assert .Equal (t , 401 , recorder .Code )
475+
476+ var res map [string ]any
477+ err := json .Unmarshal (recorder .Body .Bytes (), & res )
478+ assert .NoError (t , err )
479+ assert .Equal (t , "invalid_request" , res ["error" ])
480+ },
481+ },
482+ {
483+ description : "Ensure userinfo forbids access with empty bearer token" ,
484+ middlewares : []gin.HandlerFunc {},
485+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
486+ req := httptest .NewRequest ("GET" , "/api/oidc/userinfo" , nil )
487+ req .Header .Set ("Authorization" , "Bearer " )
488+ router .ServeHTTP (recorder , req )
489+ assert .Equal (t , 401 , recorder .Code )
490+
491+ var res map [string ]any
492+ err := json .Unmarshal (recorder .Body .Bytes (), & res )
493+ assert .NoError (t , err )
494+ assert .Equal (t , "invalid_grant" , res ["error" ])
495+ },
496+ },
497+ {
498+ description : "Ensure userinfo POST rejects missing access token in body" ,
499+ middlewares : []gin.HandlerFunc {},
500+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
501+ req := httptest .NewRequest ("POST" , "/api/oidc/userinfo" , strings .NewReader ("" ))
502+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
503+ router .ServeHTTP (recorder , req )
504+ assert .Equal (t , 401 , recorder .Code )
505+
506+ var res map [string ]any
507+ err := json .Unmarshal (recorder .Body .Bytes (), & res )
508+ assert .NoError (t , err )
509+ assert .Equal (t , "invalid_request" , res ["error" ])
510+ },
511+ },
512+ {
513+ description : "Ensure userinfo POST rejects wrong content type" ,
514+ middlewares : []gin.HandlerFunc {},
515+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
516+ req := httptest .NewRequest ("POST" , "/api/oidc/userinfo" , strings .NewReader (`{"access_token":"some-token"}` ))
517+ req .Header .Set ("Content-Type" , "application/json" )
518+ router .ServeHTTP (recorder , req )
519+ assert .Equal (t , 400 , recorder .Code )
520+
521+ var res map [string ]any
522+ err := json .Unmarshal (recorder .Body .Bytes (), & res )
523+ assert .NoError (t , err )
524+ assert .Equal (t , "invalid_request" , res ["error" ])
525+ },
526+ },
527+ {
528+ description : "Ensure userinfo accepts access token via POST body" ,
529+ middlewares : []gin.HandlerFunc {
530+ simpleCtx ,
531+ },
532+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
533+ tokenTest , found := getTestByDescription ("Ensure we can get a token with a valid request" )
534+ assert .True (t , found , "Token test not found" )
535+ tokenRecorder := httptest .NewRecorder ()
536+ tokenTest (t , router , tokenRecorder )
537+
538+ var tokenRes map [string ]any
539+ err := json .Unmarshal (tokenRecorder .Body .Bytes (), & tokenRes )
540+ assert .NoError (t , err )
541+
542+ accessToken := tokenRes ["access_token" ].(string )
543+ assert .NotEmpty (t , accessToken )
544+
545+ body := url.Values {}
546+ body .Set ("access_token" , accessToken )
547+ req := httptest .NewRequest ("POST" , "/api/oidc/userinfo" , strings .NewReader (body .Encode ()))
548+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
549+ router .ServeHTTP (recorder , req )
550+ assert .Equal (t , 200 , recorder .Code )
551+
552+ var userInfoRes map [string ]any
553+ err = json .Unmarshal (recorder .Body .Bytes (), & userInfoRes )
554+ assert .NoError (t , err )
555+
556+ _ , ok := userInfoRes ["sub" ]
557+ assert .True (t , ok , "Expected sub claim in userinfo response" )
558+ },
559+ },
438560 {
439561 description : "Ensure plain PKCE succeeds" ,
440562 middlewares : []gin.HandlerFunc {
0 commit comments