Skip to content

feat(coderd): set full name from IDP name claim #13468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 6, 2024
Prev Previous commit
Next Next commit
chore(coderd): RED: update OAuth2/OIDC login tests to require full na…
…me from IDP
  • Loading branch information
johnstcn committed Jun 4, 2024
commit 2ac8287adad3a23959ee95bb15efa686e22158a1
106 changes: 86 additions & 20 deletions coderd/userauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func TestUserOAuth2Github(t *testing.T) {
return &github.User{
ID: github.Int64(100),
Login: github.String("kyle"),
Name: github.String("Kylium Carbonate"),
}, nil
},
TeamMembership: func(ctx context.Context, client *http.Client, org, team, username string) (*github.Membership, error) {
Expand Down Expand Up @@ -273,7 +274,9 @@ func TestUserOAuth2Github(t *testing.T) {
},
AuthenticatedUser: func(ctx context.Context, client *http.Client) (*github.User, error) {
return &github.User{
ID: github.Int64(100),
ID: github.Int64(100),
Login: github.String("testuser"),
Name: github.String("The Right Honorable Sir Test McUser"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand Down Expand Up @@ -306,7 +309,9 @@ func TestUserOAuth2Github(t *testing.T) {
},
AuthenticatedUser: func(ctx context.Context, client *http.Client) (*github.User, error) {
return &github.User{
ID: github.Int64(100),
ID: github.Int64(100),
Login: github.String("testuser"),
Name: github.String("The Right Honorable Sir Test McUser"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand Down Expand Up @@ -347,9 +352,10 @@ func TestUserOAuth2Github(t *testing.T) {
},
AuthenticatedUser: func(ctx context.Context, _ *http.Client) (*github.User, error) {
return &github.User{
Login: github.String("kyle"),
ID: i64ptr(1234),
AvatarURL: github.String("/hello-world"),
ID: i64ptr(1234),
Login: github.String("kyle"),
Name: github.String("Kylium Carbonate"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand All @@ -373,6 +379,7 @@ func TestUserOAuth2Github(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "kyle@coder.com", user.Email)
require.Equal(t, "kyle", user.Username)
require.Equal(t, "Kylium Carbonate", user.Name)
require.Equal(t, "/hello-world", user.AvatarURL)

require.Len(t, auditor.AuditLogs(), numLogs)
Expand Down Expand Up @@ -402,8 +409,10 @@ func TestUserOAuth2Github(t *testing.T) {
},
AuthenticatedUser: func(ctx context.Context, client *http.Client) (*github.User, error) {
return &github.User{
ID: github.Int64(100),
Login: github.String("kyle"),
AvatarURL: github.String("/hello-world"),
ID: github.Int64(100),
Login: github.String("kyle"),
Name: github.String("Kylium Carbonate"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand All @@ -420,6 +429,14 @@ func TestUserOAuth2Github(t *testing.T) {
resp := oauth2Callback(t, client)
numLogs++ // add an audit log for login

client.SetSessionToken(authCookieValue(resp.Cookies()))
user, err := client.User(context.Background(), "me")
require.NoError(t, err)
require.Equal(t, "kyle@coder.com", user.Email)
require.Equal(t, "kyle", user.Username)
require.Equal(t, "Kylium Carbonate", user.Name)
require.Equal(t, "/hello-world", user.AvatarURL)

require.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
require.Len(t, auditor.AuditLogs(), numLogs)
require.Equal(t, database.AuditActionRegister, auditor.AuditLogs()[numLogs-1].Action)
Expand Down Expand Up @@ -457,6 +474,7 @@ func TestUserOAuth2Github(t *testing.T) {
return &github.User{
ID: github.Int64(100),
Login: github.String("mathias"),
Name: github.String("Mathias Mathias"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand All @@ -473,6 +491,13 @@ func TestUserOAuth2Github(t *testing.T) {
resp := oauth2Callback(t, client)
numLogs++ // add an audit log for login

client.SetSessionToken(authCookieValue(resp.Cookies()))
user, err := client.User(context.Background(), "me")
require.NoError(t, err)
require.Equal(t, "mathias@coder.com", user.Email)
require.Equal(t, "mathias", user.Username)
require.Equal(t, "Mathias Mathias", user.Name)

require.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
require.Len(t, auditor.AuditLogs(), numLogs)
require.Equal(t, database.AuditActionRegister, auditor.AuditLogs()[numLogs-1].Action)
Expand Down Expand Up @@ -510,6 +535,7 @@ func TestUserOAuth2Github(t *testing.T) {
return &github.User{
ID: github.Int64(100),
Login: github.String("mathias"),
Name: github.String("Mathias Mathias"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand All @@ -526,6 +552,13 @@ func TestUserOAuth2Github(t *testing.T) {
resp := oauth2Callback(t, client)
numLogs++ // add an audit log for login

client.SetSessionToken(authCookieValue(resp.Cookies()))
user, err := client.User(context.Background(), "me")
require.NoError(t, err)
require.Equal(t, "mathias@coder.com", user.Email)
require.Equal(t, "mathias", user.Username)
require.Equal(t, "Mathias Mathias", user.Name)

require.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
require.Len(t, auditor.AuditLogs(), numLogs)
require.Equal(t, database.AuditActionRegister, auditor.AuditLogs()[numLogs-1].Action)
Expand All @@ -549,6 +582,7 @@ func TestUserOAuth2Github(t *testing.T) {
return &github.User{
ID: github.Int64(100),
Login: github.String("mathias"),
Name: github.String("Mathias Mathias"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand All @@ -565,6 +599,13 @@ func TestUserOAuth2Github(t *testing.T) {
resp := oauth2Callback(t, client)
numLogs++ // add an audit log for login

client.SetSessionToken(authCookieValue(resp.Cookies()))
user, err := client.User(context.Background(), "me")
require.NoError(t, err)
require.Equal(t, "mathias@coder.com", user.Email)
require.Equal(t, "mathias", user.Username)
require.Equal(t, "Mathias Mathias", user.Name)

require.Equal(t, http.StatusTemporaryRedirect, resp.StatusCode)
require.Len(t, auditor.AuditLogs(), numLogs)
require.Equal(t, database.AuditActionRegister, auditor.AuditLogs()[numLogs-1].Action)
Expand Down Expand Up @@ -592,6 +633,7 @@ func TestUserOAuth2Github(t *testing.T) {
return &github.User{
ID: github.Int64(100),
Login: github.String("kyle"),
Name: github.String("Kylium Carbonate"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand Down Expand Up @@ -653,6 +695,7 @@ func TestUserOAuth2Github(t *testing.T) {
return &github.User{
Login: github.String("alice"),
ID: github.Int64(ghID),
Name: github.String("Alice Liddell"),
}, nil
},
ListEmails: func(ctx context.Context, client *http.Client) ([]*github.UserEmail, error) {
Expand Down Expand Up @@ -740,7 +783,7 @@ func TestUserOIDC(t *testing.T) {
UserInfoClaims jwt.MapClaims
AllowSignups bool
EmailDomain []string
AssertUser func(u codersdk.User)
AssertUser func(t testing.TB, u codersdk.User)
StatusCode int
IgnoreEmailVerified bool
IgnoreUserInfo bool
Expand All @@ -752,7 +795,7 @@ func TestUserOIDC(t *testing.T) {
},
AllowSignups: true,
StatusCode: http.StatusOK,
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "kyle", u.Username)
},
},
Expand Down Expand Up @@ -782,7 +825,7 @@ func TestUserOIDC(t *testing.T) {
},
AllowSignups: true,
StatusCode: http.StatusOK,
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, u.Username, "kyle")
},
IgnoreEmailVerified: true,
Expand All @@ -806,6 +849,9 @@ func TestUserOIDC(t *testing.T) {
"email_verified": true,
},
AllowSignups: true,
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, u.Username, "kyle")
},
EmailDomain: []string{
"kwc.io",
},
Expand Down Expand Up @@ -843,7 +889,7 @@ func TestUserOIDC(t *testing.T) {
"email": "kyle@kwc.io",
"email_verified": true,
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "kyle", u.Username)
},
AllowSignups: true,
Expand All @@ -856,22 +902,36 @@ func TestUserOIDC(t *testing.T) {
"email_verified": true,
"preferred_username": "hotdog",
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "hotdog", u.Username)
},
AllowSignups: true,
StatusCode: http.StatusOK,
},
{
Name: "FullNameFromClaims",
IDTokenClaims: jwt.MapClaims{
"email": "kyle@kwc.io",
"email_verified": true,
"name": "Hot Dog",
},
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "Hot Dog", u.Name)
},
AllowSignups: true,
StatusCode: http.StatusOK,
},
{
// Services like Okta return the email as the username:
// https://developer.okta.com/docs/reference/api/oidc/#base-claims-always-present
Name: "UsernameAsEmail",
IDTokenClaims: jwt.MapClaims{
"email": "kyle@kwc.io",
"email_verified": true,
"name": "Kylium Carbonate",
"preferred_username": "kyle@kwc.io",
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "kyle", u.Username)
},
AllowSignups: true,
Expand All @@ -883,8 +943,9 @@ func TestUserOIDC(t *testing.T) {
IDTokenClaims: jwt.MapClaims{
"preferred_username": "kyle@kwc.io",
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "kyle", u.Username)
assert.Equal(t, "Kylium Carbonate", u.Name)
},
AllowSignups: true,
StatusCode: http.StatusOK,
Expand All @@ -897,7 +958,7 @@ func TestUserOIDC(t *testing.T) {
"preferred_username": "kyle",
"picture": "/example.png",
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "/example.png", u.AvatarURL)
assert.Equal(t, "kyle", u.Username)
},
Expand All @@ -913,9 +974,11 @@ func TestUserOIDC(t *testing.T) {
UserInfoClaims: jwt.MapClaims{
"preferred_username": "potato",
"picture": "/example.png",
"name": "Kylium Carbonate",
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "/example.png", u.AvatarURL)
assert.Equal(t, "Kylium Carbonate", u.Name)
assert.Equal(t, "potato", u.Username)
},
AllowSignups: true,
Expand All @@ -941,7 +1004,7 @@ func TestUserOIDC(t *testing.T) {
"email_verified": true,
"preferred_username": "user",
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "user", u.Username)
},
AllowSignups: true,
Expand All @@ -966,14 +1029,17 @@ func TestUserOIDC(t *testing.T) {
IDTokenClaims: jwt.MapClaims{
"email": "user@internal.domain",
"email_verified": true,
"name": "User McName",
"preferred_username": "user",
},
UserInfoClaims: jwt.MapClaims{
"email": "user.mcname@external.domain",
"name": "Mr. User McName",
"preferred_username": "Mr. User McName",
},
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "user", u.Username)
assert.Equal(t, "User Name", u.Name)
},
IgnoreUserInfo: true,
AllowSignups: true,
Expand All @@ -985,7 +1051,7 @@ func TestUserOIDC(t *testing.T) {
"email": "user@domain.tld",
"email_verified": true,
}, 65536),
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "user", u.Username)
},
AllowSignups: true,
Expand All @@ -998,7 +1064,7 @@ func TestUserOIDC(t *testing.T) {
"email_verified": true,
},
UserInfoClaims: inflateClaims(t, jwt.MapClaims{}, 65536),
AssertUser: func(u codersdk.User) {
AssertUser: func(t testing.TB, u codersdk.User) {
assert.Equal(t, "user", u.Username)
},
AllowSignups: true,
Expand Down Expand Up @@ -1041,7 +1107,7 @@ func TestUserOIDC(t *testing.T) {
user, err := client.User(ctx, "me")
require.NoError(t, err)

tc.AssertUser(user)
tc.AssertUser(t, user)
require.Len(t, auditor.AuditLogs(), numLogs)
require.NotEqual(t, uuid.Nil, auditor.AuditLogs()[numLogs-1].UserID)
require.Equal(t, database.AuditActionRegister, auditor.AuditLogs()[numLogs-1].Action)
Expand Down
Loading