Fix wrong user in OpenID response (#16736)
* Fixed usage of wrong user. * Added tests.
This commit is contained in:
		
							parent
							
								
									c9bca8c5e0
								
							
						
					
					
						commit
						4debb74eda
					
				|  | @ -5,3 +5,19 @@ | ||||||
|   scope: "openid profile" |   scope: "openid profile" | ||||||
|   created_unix: 1546869730 |   created_unix: 1546869730 | ||||||
|   updated_unix: 1546869730 |   updated_unix: 1546869730 | ||||||
|  | 
 | ||||||
|  | - id: 2 | ||||||
|  |   user_id: 3 | ||||||
|  |   application_id: 1 | ||||||
|  |   counter: 1 | ||||||
|  |   scope: "openid" | ||||||
|  |   created_unix: 1546869730 | ||||||
|  |   updated_unix: 1546869730 | ||||||
|  | 
 | ||||||
|  | - id: 3 | ||||||
|  |   user_id: 5 | ||||||
|  |   application_id: 1 | ||||||
|  |   counter: 1 | ||||||
|  |   scope: "openid profile email" | ||||||
|  |   created_unix: 1546869730 | ||||||
|  |   updated_unix: 1546869730 | ||||||
|  | @ -187,7 +187,7 @@ func newAccessTokenResponse(grant *models.OAuth2Grant, signingKey oauth2.JWTSign | ||||||
| 				ErrorDescription: "cannot find application", | 				ErrorDescription: "cannot find application", | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		err = app.LoadUser() | 		user, err := models.GetUserByID(grant.UserID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if models.IsErrUserNotExist(err) { | 			if models.IsErrUserNotExist(err) { | ||||||
| 				return nil, &AccessTokenError{ | 				return nil, &AccessTokenError{ | ||||||
|  | @ -212,17 +212,17 @@ func newAccessTokenResponse(grant *models.OAuth2Grant, signingKey oauth2.JWTSign | ||||||
| 			Nonce: grant.Nonce, | 			Nonce: grant.Nonce, | ||||||
| 		} | 		} | ||||||
| 		if grant.ScopeContains("profile") { | 		if grant.ScopeContains("profile") { | ||||||
| 			idToken.Name = app.User.FullName | 			idToken.Name = user.FullName | ||||||
| 			idToken.PreferredUsername = app.User.Name | 			idToken.PreferredUsername = user.Name | ||||||
| 			idToken.Profile = app.User.HTMLURL() | 			idToken.Profile = user.HTMLURL() | ||||||
| 			idToken.Picture = app.User.AvatarLink() | 			idToken.Picture = user.AvatarLink() | ||||||
| 			idToken.Website = app.User.Website | 			idToken.Website = user.Website | ||||||
| 			idToken.Locale = app.User.Language | 			idToken.Locale = user.Language | ||||||
| 			idToken.UpdatedAt = app.User.UpdatedUnix | 			idToken.UpdatedAt = user.UpdatedUnix | ||||||
| 		} | 		} | ||||||
| 		if grant.ScopeContains("email") { | 		if grant.ScopeContains("email") { | ||||||
| 			idToken.Email = app.User.Email | 			idToken.Email = user.Email | ||||||
| 			idToken.EmailVerified = app.User.IsActive | 			idToken.EmailVerified = user.IsActive | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		signedIDToken, err = idToken.SignToken(signingKey) | 		signedIDToken, err = idToken.SignToken(signingKey) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,75 @@ | ||||||
|  | // Copyright 2021 The Gitea Authors. All rights reserved.
 | ||||||
|  | // Use of this source code is governed by a MIT-style
 | ||||||
|  | // license that can be found in the LICENSE file.
 | ||||||
|  | 
 | ||||||
|  | package user | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"code.gitea.io/gitea/models" | ||||||
|  | 	"code.gitea.io/gitea/services/auth/source/oauth2" | ||||||
|  | 
 | ||||||
|  | 	"github.com/golang-jwt/jwt" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func createAndParseToken(t *testing.T, grant *models.OAuth2Grant) *oauth2.OIDCToken { | ||||||
|  | 	signingKey, err := oauth2.CreateJWTSingingKey("HS256", make([]byte, 32)) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.NotNil(t, signingKey) | ||||||
|  | 	oauth2.DefaultSigningKey = signingKey | ||||||
|  | 
 | ||||||
|  | 	response, terr := newAccessTokenResponse(grant, signingKey) | ||||||
|  | 	assert.Nil(t, terr) | ||||||
|  | 	assert.NotNil(t, response) | ||||||
|  | 
 | ||||||
|  | 	parsedToken, err := jwt.ParseWithClaims(response.IDToken, &oauth2.OIDCToken{}, func(token *jwt.Token) (interface{}, error) { | ||||||
|  | 		assert.NotNil(t, token.Method) | ||||||
|  | 		assert.Equal(t, signingKey.SigningMethod().Alg(), token.Method.Alg()) | ||||||
|  | 		return signingKey.VerifyKey(), nil | ||||||
|  | 	}) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.True(t, parsedToken.Valid) | ||||||
|  | 
 | ||||||
|  | 	oidcToken, ok := parsedToken.Claims.(*oauth2.OIDCToken) | ||||||
|  | 	assert.True(t, ok) | ||||||
|  | 	assert.NotNil(t, oidcToken) | ||||||
|  | 
 | ||||||
|  | 	return oidcToken | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestNewAccessTokenResponse_OIDCToken(t *testing.T) { | ||||||
|  | 	assert.NoError(t, models.PrepareTestDatabase()) | ||||||
|  | 
 | ||||||
|  | 	grants, err := models.GetOAuth2GrantsByUserID(3) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.Len(t, grants, 1) | ||||||
|  | 
 | ||||||
|  | 	// Scopes: openid
 | ||||||
|  | 	oidcToken := createAndParseToken(t, grants[0]) | ||||||
|  | 	assert.Empty(t, oidcToken.Name) | ||||||
|  | 	assert.Empty(t, oidcToken.PreferredUsername) | ||||||
|  | 	assert.Empty(t, oidcToken.Profile) | ||||||
|  | 	assert.Empty(t, oidcToken.Picture) | ||||||
|  | 	assert.Empty(t, oidcToken.Website) | ||||||
|  | 	assert.Empty(t, oidcToken.UpdatedAt) | ||||||
|  | 	assert.Empty(t, oidcToken.Email) | ||||||
|  | 	assert.False(t, oidcToken.EmailVerified) | ||||||
|  | 
 | ||||||
|  | 	user := models.AssertExistsAndLoadBean(t, &models.User{ID: 5}).(*models.User) | ||||||
|  | 	grants, err = models.GetOAuth2GrantsByUserID(user.ID) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.Len(t, grants, 1) | ||||||
|  | 
 | ||||||
|  | 	// Scopes: openid profile email
 | ||||||
|  | 	oidcToken = createAndParseToken(t, grants[0]) | ||||||
|  | 	assert.Equal(t, user.FullName, oidcToken.Name) | ||||||
|  | 	assert.Equal(t, user.Name, oidcToken.PreferredUsername) | ||||||
|  | 	assert.Equal(t, user.HTMLURL(), oidcToken.Profile) | ||||||
|  | 	assert.Equal(t, user.AvatarLink(), oidcToken.Picture) | ||||||
|  | 	assert.Equal(t, user.Website, oidcToken.Website) | ||||||
|  | 	assert.Equal(t, user.UpdatedUnix, oidcToken.UpdatedAt) | ||||||
|  | 	assert.Equal(t, user.Email, oidcToken.Email) | ||||||
|  | 	assert.Equal(t, user.IsActive, oidcToken.EmailVerified) | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue