connectors/oidc: truely ignore "email_verified" claim if configured that way
Fixes #1455, I hope. Signed-off-by: Stephan Renatus <srenatus@chef.io>
This commit is contained in:
		@@ -219,8 +219,12 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide
 | 
			
		||||
	}
 | 
			
		||||
	emailVerified, found := claims["email_verified"].(bool)
 | 
			
		||||
	if !found {
 | 
			
		||||
		if c.insecureSkipEmailVerified {
 | 
			
		||||
			emailVerified = true
 | 
			
		||||
		} else {
 | 
			
		||||
			return identity, errors.New("missing \"email_verified\" claim")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	hostedDomain, _ := claims["hd"].(string)
 | 
			
		||||
 | 
			
		||||
	if len(c.hostedDomains) > 0 {
 | 
			
		||||
@@ -237,10 +241,6 @@ func (c *oidcConnector) HandleCallback(s connector.Scopes, r *http.Request) (ide
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.insecureSkipEmailVerified {
 | 
			
		||||
		emailVerified = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.getUserInfo {
 | 
			
		||||
		userInfo, err := c.provider.UserInfo(r.Context(), oauth2.StaticTokenSource(token))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -47,15 +47,47 @@ func TestHandleCallback(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name                      string
 | 
			
		||||
		userIDKey                 string
 | 
			
		||||
		insecureSkipEmailVerified bool
 | 
			
		||||
		expectUserID              string
 | 
			
		||||
		token                     map[string]interface{}
 | 
			
		||||
	}{
 | 
			
		||||
		{"simpleCase", "", "sub"},
 | 
			
		||||
		{"withUserIDKey", "name", "name"},
 | 
			
		||||
		{
 | 
			
		||||
			name:         "simpleCase",
 | 
			
		||||
			userIDKey:    "", // not configured
 | 
			
		||||
			expectUserID: "subvalue",
 | 
			
		||||
			token: map[string]interface{}{
 | 
			
		||||
				"sub":            "subvalue",
 | 
			
		||||
				"name":           "namevalue",
 | 
			
		||||
				"email":          "emailvalue",
 | 
			
		||||
				"email_verified": true,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:                      "email_verified not in claims, configured to be skipped",
 | 
			
		||||
			insecureSkipEmailVerified: true,
 | 
			
		||||
			expectUserID:              "subvalue",
 | 
			
		||||
			token: map[string]interface{}{
 | 
			
		||||
				"sub":   "subvalue",
 | 
			
		||||
				"name":  "namevalue",
 | 
			
		||||
				"email": "emailvalue",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:         "withUserIDKey",
 | 
			
		||||
			userIDKey:    "name",
 | 
			
		||||
			expectUserID: "namevalue",
 | 
			
		||||
			token: map[string]interface{}{
 | 
			
		||||
				"sub":            "subvalue",
 | 
			
		||||
				"name":           "namevalue",
 | 
			
		||||
				"email":          "emailvalue",
 | 
			
		||||
				"email_verified": true,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tc := range tests {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			testServer, err := setupServer()
 | 
			
		||||
			testServer, err := setupServer(tc.token)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Fatal("failed to setup test server", err)
 | 
			
		||||
			}
 | 
			
		||||
@@ -68,6 +100,7 @@ func TestHandleCallback(t *testing.T) {
 | 
			
		||||
				Scopes:                    []string{"groups"},
 | 
			
		||||
				RedirectURI:               fmt.Sprintf("%s/callback", serverURL),
 | 
			
		||||
				UserIDKey:                 tc.userIDKey,
 | 
			
		||||
				InsecureSkipEmailVerified: tc.insecureSkipEmailVerified,
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			conn, err := newConnector(config)
 | 
			
		||||
@@ -86,14 +119,14 @@ func TestHandleCallback(t *testing.T) {
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			expectEquals(t, identity.UserID, tc.expectUserID)
 | 
			
		||||
			expectEquals(t, identity.Username, "name")
 | 
			
		||||
			expectEquals(t, identity.Email, "email")
 | 
			
		||||
			expectEquals(t, identity.Username, "namevalue")
 | 
			
		||||
			expectEquals(t, identity.Email, "emailvalue")
 | 
			
		||||
			expectEquals(t, identity.EmailVerified, true)
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setupServer() (*httptest.Server, error) {
 | 
			
		||||
func setupServer(tok map[string]interface{}) (*httptest.Server, error) {
 | 
			
		||||
	key, err := rsa.GenerateKey(rand.Reader, 1024)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("failed to generate rsa key: %v", err)
 | 
			
		||||
@@ -121,16 +154,10 @@ func setupServer() (*httptest.Server, error) {
 | 
			
		||||
 | 
			
		||||
	mux.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		url := fmt.Sprintf("http://%s", r.Host)
 | 
			
		||||
 | 
			
		||||
		token, err := newToken(&jwk, map[string]interface{}{
 | 
			
		||||
			"iss":            url,
 | 
			
		||||
			"aud":            "clientID",
 | 
			
		||||
			"exp":            time.Now().Add(time.Hour).Unix(),
 | 
			
		||||
			"sub":            "sub",
 | 
			
		||||
			"name":           "name",
 | 
			
		||||
			"email":          "email",
 | 
			
		||||
			"email_verified": true,
 | 
			
		||||
		})
 | 
			
		||||
		tok["iss"] = url
 | 
			
		||||
		tok["exp"] = time.Now().Add(time.Hour).Unix()
 | 
			
		||||
		tok["aud"] = "clientID"
 | 
			
		||||
		token, err := newToken(&jwk, tok)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			w.WriteHeader(http.StatusInternalServerError)
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user