feat: add CODER_OIDC_IGNORE_EMAIL_VERIFIED config knob (#5165)

* Adds a configuration knob CODER_OIDC_IGNORE_EMAIL_VERIFIED that allows
  ignoring the email_verified OIDC claim
* Adds warning message at startup if CODER_OIDC_IGNORE_EMAIL_VERIFIED=true
* Adds warning whenever an unverified OIDC email is let through
* Skips flaky test on non-linux platforms

Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
This commit is contained in:
Cian Johnston
2022-11-25 10:10:09 +00:00
committed by GitHub
parent 6ed12ade54
commit a4a319a76e
10 changed files with 91 additions and 26 deletions

View File

@ -195,6 +195,9 @@ type OIDCConfig struct {
// EmailDomain is the domain to enforce when a user authenticates.
EmailDomain string
AllowSignups bool
// IgnoreEmailVerified allows ignoring the email_verified claim
// from an upstream OIDC provider. See #5065 for context.
IgnoreEmailVerified bool
}
func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
@ -264,10 +267,13 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) {
if ok {
verified, ok := verifiedRaw.(bool)
if ok && !verified {
httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{
Message: fmt.Sprintf("Verify the %q email address on your OIDC provider to authenticate!", email),
})
return
if !api.OIDCConfig.IgnoreEmailVerified {
httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{
Message: fmt.Sprintf("Verify the %q email address on your OIDC provider to authenticate!", email),
})
return
}
api.Logger.Warn(ctx, "allowing unverified oidc email %q")
}
}
// The username is a required property in Coder. We make a best-effort

View File

@ -479,13 +479,14 @@ func TestUserOIDC(t *testing.T) {
t.Parallel()
for _, tc := range []struct {
Name string
Claims jwt.MapClaims
AllowSignups bool
EmailDomain string
Username string
AvatarURL string
StatusCode int
Name string
Claims jwt.MapClaims
AllowSignups bool
EmailDomain string
Username string
AvatarURL string
StatusCode int
IgnoreEmailVerified bool
}{{
Name: "EmailOnly",
Claims: jwt.MapClaims{
@ -502,6 +503,24 @@ func TestUserOIDC(t *testing.T) {
},
AllowSignups: true,
StatusCode: http.StatusForbidden,
}, {
Name: "EmailNotAString",
Claims: jwt.MapClaims{
"email": 3.14159,
"email_verified": false,
},
AllowSignups: true,
StatusCode: http.StatusBadRequest,
}, {
Name: "EmailNotVerifiedIgnored",
Claims: jwt.MapClaims{
"email": "kyle@kwc.io",
"email_verified": false,
},
AllowSignups: true,
StatusCode: http.StatusTemporaryRedirect,
Username: "kyle",
IgnoreEmailVerified: true,
}, {
Name: "NotInRequiredEmailDomain",
Claims: jwt.MapClaims{
@ -593,6 +612,7 @@ func TestUserOIDC(t *testing.T) {
config := conf.OIDCConfig()
config.AllowSignups = tc.AllowSignups
config.EmailDomain = tc.EmailDomain
config.IgnoreEmailVerified = tc.IgnoreEmailVerified
client := coderdtest.New(t, &coderdtest.Options{
OIDCConfig: config,