@@ -52,10 +52,12 @@ func setupTestServer(t *testing.T) (*httptest.Server, repository.Repository, str
5252 store := cookie .NewStore (secret [:])
5353 router .Use (sessions .Sessions ("test_session" , store ))
5454
55- // Mock auth middleware that always passes
55+ // Mock auth middleware that always passes with user identity
5656 router .Use (func (c * gin.Context ) {
5757 session := sessions .Default (c )
5858 session .Set (auth .SessionKeyAuthorized , true )
59+ session .
Set (
auth .
SessionKeyUserID ,
"[email protected] " )
60+ session .
Set (
auth .
SessionKeyUserInfo ,
`{"email":"[email protected] ","name":"Test User"}` )
5961 err := session .Save ()
6062 if err != nil {
6163 c .JSON (500 , gin.H {"error" : "Failed to save session" })
@@ -466,3 +468,62 @@ func TestAccessTokenAudienceClaim(t *testing.T) {
466468 require .True (t , ok , "aud claim should be present as an array" )
467469 require .Contains (t , aud , "http://localhost:8080" , "aud should contain the external URL" )
468470}
471+
472+ func TestAccessTokenPreservesUserIdentity (t * testing.T ) {
473+ server , _ , _ := setupTestServer (t )
474+ regResp := registerTestClient (t , server .URL )
475+
476+ config := & oauth2.Config {
477+ ClientID : regResp .ClientID ,
478+ ClientSecret : regResp .ClientSecret ,
479+ RedirectURL : "http://localhost:8080/callback" ,
480+ Scopes : []string {},
481+ Endpoint : oauth2.Endpoint {
482+ AuthURL : server .URL + AuthorizationEndpoint ,
483+ TokenURL : server .URL + TokenEndpoint ,
484+ },
485+ }
486+
487+ callbackURL := testAuthFlowWithURL (t , server .URL , config .AuthCodeURL ("test-state" ))
488+ code := callbackURL .Query ().Get ("code" )
489+
490+ tokenReq := url.Values {}
491+ tokenReq .Set ("grant_type" , "authorization_code" )
492+ tokenReq .Set ("code" , code )
493+ tokenReq .Set ("redirect_uri" , "http://localhost:8080/callback" )
494+ tokenReq .Set ("client_id" , regResp .ClientID )
495+ tokenReq .Set ("client_secret" , regResp .ClientSecret )
496+
497+ tokenResp , err := http .PostForm (server .URL + TokenEndpoint , tokenReq )
498+ require .NoError (t , err )
499+ defer tokenResp .Body .Close ()
500+ require .Equal (t , http .StatusOK , tokenResp .StatusCode )
501+
502+ var tokenResult map [string ]any
503+ err = json .NewDecoder (tokenResp .Body ).Decode (& tokenResult )
504+ require .NoError (t , err )
505+
506+ accessToken := tokenResult ["access_token" ].(string )
507+
508+ // Decode JWT payload
509+ parts := strings .Split (accessToken , "." )
510+ require .Len (t , parts , 3 )
511+
512+ payload , err := base64 .RawURLEncoding .DecodeString (parts [1 ])
513+ require .NoError (t , err )
514+
515+ var claims map [string ]any
516+ err = json .Unmarshal (payload , & claims )
517+ require .NoError (t , err )
518+
519+ // Verify sub claim is preserved
520+ sub , ok := claims ["sub" ].(string )
521+ require .True (t , ok , "sub claim should be present" )
522+ require .
Equal (
t ,
"[email protected] " ,
sub )
523+
524+ // Verify userinfo claim is preserved
525+ userinfo , ok := claims ["userinfo" ].(map [string ]any )
526+ require .True (t , ok , "userinfo claim should be present" )
527+ require .
Equal (
t ,
"[email protected] " ,
userinfo [
"email" ])
528+ require .Equal (t , "Test User" , userinfo ["name" ])
529+ }
0 commit comments