package providers

import (
	"context"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"

	"github.com/coreos/go-oidc/v3/oidc"
	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/encryption"
	internaloidc "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/providers/oidc"
	"github.com/stretchr/testify/assert"
)

type redeemTokenResponse struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int64  `json:"expires_in"`
	TokenType    string `json:"token_type"`
	IDToken      string `json:"id_token,omitempty"`
}

func newOIDCProvider(serverURL *url.URL, skipNonce bool) *OIDCProvider {
	verificationOptions := internaloidc.IDTokenVerificationOptions{
		AudienceClaims: []string{"aud"},
		ClientID:       "https://test.myapp.com",
	}
	providerData := &ProviderData{
		ProviderName: "oidc",
		ClientID:     oidcClientID,
		ClientSecret: oidcSecret,
		LoginURL: &url.URL{
			Scheme: serverURL.Scheme,
			Host:   serverURL.Host,
			Path:   "/login/oauth/authorize"},
		RedeemURL: &url.URL{
			Scheme: serverURL.Scheme,
			Host:   serverURL.Host,
			Path:   "/login/oauth/access_token"},
		ProfileURL: &url.URL{
			Scheme: serverURL.Scheme,
			Host:   serverURL.Host,
			Path:   "/profile"},
		IntrospectURL: &url.URL{
			Scheme: serverURL.Scheme,
			Host:   serverURL.Host,
			Path:   "/introspect"},
		ValidateURL: &url.URL{
			Scheme: serverURL.Scheme,
			Host:   serverURL.Host,
			Path:   "/api"},
		Scope:       "openid profile offline_access",
		EmailClaim:  "email",
		GroupsClaim: "groups",
		UserClaim:   "sub",
		Verifier: internaloidc.NewVerifier(oidc.NewVerifier(
			oidcIssuer,
			mockJWKS{},
			&oidc.Config{ClientID: oidcClientID},
		), verificationOptions),
	}

	p := NewOIDCProvider(providerData, options.OIDCOptions{
		InsecureSkipNonce: skipNonce,
	})

	return p
}

func newOIDCServer(redeemJSON []byte, profileJSON []byte, introspectJSON []byte) (*url.URL, *httptest.Server) {
	mux := http.NewServeMux()
	if len(redeemJSON) > 0 {
		mux.HandleFunc("/login/oauth/access_token", func(rw http.ResponseWriter, req *http.Request) {
			rw.Header().Add("content-type", "application/json")
			_, _ = rw.Write(redeemJSON)
		})
	}
	if len(profileJSON) > 0 {
		mux.HandleFunc("/profile", func(rw http.ResponseWriter, req *http.Request) {
			rw.Header().Add("content-type", "application/json")
			_, _ = rw.Write(profileJSON)
		})
	}
	if len(introspectJSON) > 0 {
		mux.HandleFunc("/introspect", func(rw http.ResponseWriter, req *http.Request) {
			rw.Header().Add("content-type", "application/json")
			_, _ = rw.Write(introspectJSON)
		})
	}
	testserver := httptest.NewServer(mux)
	u, _ := url.Parse(testserver.URL)
	fmt.Println("The URL was: " + u.String())
	return u, testserver
}

func newTestOIDCSetup(redeemJSON []byte, profileJSON []byte, introspectJSON []byte) (*httptest.Server, *OIDCProvider) {
	_, server := newOIDCServer(redeemJSON, profileJSON, introspectJSON)
	serverURL, _ := url.Parse(server.URL)
	provider := newOIDCProvider(serverURL, false)
	return server, provider
}

func TestOIDCProviderGetLoginURL(t *testing.T) {
	serverURL := &url.URL{
		Scheme: "https",
		Host:   "oauth2proxy.oidctest",
	}
	provider := newOIDCProvider(serverURL, true)

	n, err := encryption.Nonce(32)
	assert.NoError(t, err)
	nonce := base64.RawURLEncoding.EncodeToString(n)

	// SkipNonce defaults to true
	skipNonce := provider.GetLoginURL("http://redirect/", "", nonce, url.Values{})
	assert.NotContains(t, skipNonce, "nonce")

	provider.SkipNonce = false
	withNonce := provider.GetLoginURL("http://redirect/", "", nonce, url.Values{})
	assert.Contains(t, withNonce, fmt.Sprintf("nonce=%s", nonce))
	assert.NotContains(t, withNonce, "code_challenge")
	assert.NotContains(t, withNonce, "code_challenge_method")
}

func TestOIDCProviderRedeem(t *testing.T) {
	idToken, _ := newSignedTestIDToken(defaultIDToken)
	body, _ := json.Marshal(redeemTokenResponse{
		AccessToken:  accessToken,
		ExpiresIn:    10,
		TokenType:    "Bearer",
		RefreshToken: refreshToken,
		IDToken:      idToken,
	})
	server, provider := newTestOIDCSetup(body, []byte(`{}`), []byte(`{}`))
	defer server.Close()

	session, err := provider.Redeem(context.Background(), provider.RedeemURL.String(), "code1234", "")
	assert.Equal(t, nil, err)
	assert.Equal(t, defaultIDToken.Email, session.Email)
	assert.Equal(t, accessToken, session.AccessToken)
	assert.Equal(t, idToken, session.IDToken)
	assert.Equal(t, refreshToken, session.RefreshToken)
	assert.Equal(t, "123456789", session.User)
}

func TestOIDCProviderRedeem_custom_userid(t *testing.T) {
	idToken, _ := newSignedTestIDToken(defaultIDToken)
	body, _ := json.Marshal(redeemTokenResponse{
		AccessToken:  accessToken,
		ExpiresIn:    10,
		TokenType:    "Bearer",
		RefreshToken: refreshToken,
		IDToken:      idToken,
	})

	server, provider := newTestOIDCSetup(body, []byte(`{}`), []byte(`{}`))
	provider.EmailClaim = "phone_number"
	defer server.Close()

	session, err := provider.Redeem(context.Background(), provider.RedeemURL.String(), "code1234", "")
	assert.Equal(t, nil, err)
	assert.Equal(t, defaultIDToken.Phone, session.Email)
}

func TestOIDCProviderRefreshSessionIfNeededWithoutIdToken(t *testing.T) {

	idToken, _ := newSignedTestIDToken(defaultIDToken)
	body, _ := json.Marshal(redeemTokenResponse{
		AccessToken:  accessToken,
		ExpiresIn:    10,
		TokenType:    "Bearer",
		RefreshToken: refreshToken,
	})

	server, provider := newTestOIDCSetup(body, []byte(`{}`), []byte(`{}`))
	defer server.Close()

	existingSession := &sessions.SessionState{
		AccessToken:  "changeit",
		IDToken:      idToken,
		CreatedAt:    nil,
		ExpiresOn:    nil,
		RefreshToken: refreshToken,
		Email:        "janedoe@example.com",
		User:         "11223344",
	}

	refreshed, err := provider.RefreshSession(context.Background(), existingSession)
	assert.Equal(t, nil, err)
	assert.Equal(t, refreshed, true)
	assert.Equal(t, "janedoe@example.com", existingSession.Email)
	assert.Equal(t, accessToken, existingSession.AccessToken)
	assert.Equal(t, idToken, existingSession.IDToken)
	assert.Equal(t, refreshToken, existingSession.RefreshToken)
	assert.Equal(t, "11223344", existingSession.User)
}

func TestOIDCProviderRefreshSessionIfNeededWithIdToken(t *testing.T) {

	idToken, _ := newSignedTestIDToken(defaultIDToken)
	body, _ := json.Marshal(redeemTokenResponse{
		AccessToken:  accessToken,
		ExpiresIn:    10,
		TokenType:    "Bearer",
		RefreshToken: refreshToken,
		IDToken:      idToken,
	})

	server, provider := newTestOIDCSetup(body, []byte(`{}`), []byte(`{}`))
	defer server.Close()

	existingSession := &sessions.SessionState{
		AccessToken:  "changeit",
		IDToken:      "changeit",
		CreatedAt:    nil,
		ExpiresOn:    nil,
		RefreshToken: refreshToken,
		Email:        "changeit",
		User:         "changeit",
	}
	refreshed, err := provider.RefreshSession(context.Background(), existingSession)
	assert.Equal(t, nil, err)
	assert.Equal(t, refreshed, true)
	assert.Equal(t, defaultIDToken.Email, existingSession.Email)
	assert.Equal(t, defaultIDToken.Subject, existingSession.User)
	assert.Equal(t, accessToken, existingSession.AccessToken)
	assert.Equal(t, idToken, existingSession.IDToken)
	assert.Equal(t, refreshToken, existingSession.RefreshToken)
}

func TestOIDCProviderCreateSessionFromToken(t *testing.T) {
	testCases := map[string]struct {
		IDToken        idTokenClaims
		GroupsClaim    string
		ExpectedUser   string
		ExpectedEmail  string
		ExpectedGroups []string
	}{
		"Default IDToken": {
			IDToken:        defaultIDToken,
			GroupsClaim:    "groups",
			ExpectedUser:   "123456789",
			ExpectedEmail:  "janed@me.com",
			ExpectedGroups: []string{"test:a", "test:b"},
		},
		"Minimal IDToken with no email claim": {
			IDToken:        minimalIDToken,
			GroupsClaim:    "groups",
			ExpectedUser:   "123456789",
			ExpectedEmail:  "123456789",
			ExpectedGroups: nil,
		},
		"Custom Groups Claim": {
			IDToken:        defaultIDToken,
			GroupsClaim:    "roles",
			ExpectedUser:   "123456789",
			ExpectedEmail:  "janed@me.com",
			ExpectedGroups: []string{"test:c", "test:d"},
		},
		"Complex Groups Claim": {
			IDToken:       complexGroupsIDToken,
			GroupsClaim:   "groups",
			ExpectedUser:  "123456789",
			ExpectedEmail: "complex@claims.com",
			ExpectedGroups: []string{
				"{\"groupId\":\"Admin Group Id\",\"roles\":[\"Admin\"]}",
				"12345",
				"Just::A::String",
			},
		},
	}
	for testName, tc := range testCases {
		t.Run(testName, func(t *testing.T) {
			server, provider := newTestOIDCSetup([]byte(`{}`), []byte(`{}`), []byte(`{}`))
			provider.GroupsClaim = tc.GroupsClaim
			defer server.Close()

			rawIDToken, err := newSignedTestIDToken(tc.IDToken)
			assert.NoError(t, err)

			ss, err := provider.CreateSessionFromToken(context.Background(), rawIDToken)
			assert.NoError(t, err)

			assert.Equal(t, tc.ExpectedUser, ss.User)
			assert.Equal(t, tc.ExpectedEmail, ss.Email)
			assert.Equal(t, tc.ExpectedGroups, ss.Groups)
			assert.Equal(t, rawIDToken, ss.IDToken)
			assert.Equal(t, rawIDToken, ss.AccessToken)
			assert.Equal(t, "", ss.RefreshToken)
		})
	}
}

// Vozniak
// func TestOIDCProvider_EnrichSession(t *testing.T) {
// 	testCases := map[string]struct {
// 		ExistingSession *sessions.SessionState
// 		EmailClaim      string
// 		GroupsClaim     string
// 		ProfileJSON     map[string]interface{}
// 		IntrospectJSON  map[string]interface{}
// 		ExpectedError   error
// 		ExpectedSession *sessions.SessionState
// 	}{
// 		"Already Populated": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				Groups:       []string{"already", "populated"},
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email":  "new@thing.com",
// 				"groups": []string{"new", "thing"},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				Groups:           []string{"already", "populated"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Email": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "missing.email",
// 				Groups:       []string{"already", "populated"},
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email":  "found@email.com",
// 				"groups": []string{"new", "thing"},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "missing.email",
// 				Email:            "found@email.com",
// 				Groups:           []string{"already", "populated"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},

// 		"Missing Email Only in Profile URL": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "missing.email",
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email": "found@email.com",
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "missing.email",
// 				Email:            "found@email.com",
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Email with Custom Claim": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "missing.email",
// 				Groups:       []string{"already", "populated"},
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "weird",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"weird":  "weird@claim.com",
// 				"groups": []string{"new", "thing"},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "missing.email",
// 				Email:            "weird@claim.com",
// 				Groups:           []string{"already", "populated"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Email not in Profile URL": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "missing.email",
// 				Groups:       []string{"already", "populated"},
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"groups": []string{"new", "thing"},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: errors.New("neither the id_token nor the profileURL set an email"),
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "missing.email",
// 				Groups:           []string{"already", "populated"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Groups": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				Groups:       nil,
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email":  "new@thing.com",
// 				"groups": []string{"new", "thing"},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				Groups:           []string{"new", "thing"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Groups with Complex Groups in Profile URL": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				Groups:       nil,
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email": "new@thing.com",
// 				"groups": []map[string]interface{}{
// 					{
// 						"groupId": "Admin Group Id",
// 						"roles":   []string{"Admin"},
// 					},
// 				},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				Groups:           []string{"{\"groupId\":\"Admin Group Id\",\"roles\":[\"Admin\"]}"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Groups with Singleton Complex Group in Profile URL": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				Groups:       nil,
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email": "new@thing.com",
// 				"groups": map[string]interface{}{
// 					"groupId": "Admin Group Id",
// 					"roles":   []string{"Admin"},
// 				},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				Groups:           []string{"{\"groupId\":\"Admin Group Id\",\"roles\":[\"Admin\"]}"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Empty Groups Claims": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				Groups:       []string{},
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email":  "new@thing.com",
// 				"groups": []string{"new", "thing"},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				Groups:           []string{},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Groups with Custom Claim": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				Groups:       nil,
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "roles",
// 			ProfileJSON: map[string]interface{}{
// 				"email": "new@thing.com",
// 				"roles": []string{"new", "thing", "roles"},
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				Groups:           []string{"new", "thing", "roles"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Groups String Profile URL Response": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				Groups:       nil,
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email":  "new@thing.com",
// 				"groups": "singleton",
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				Groups:           []string{"singleton"},
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Missing Groups in both Claims and Profile URL": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email": "new@thing.com",
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active": true,
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWV9",
// 			},
// 		},
// 		"Introspection Response added in session": {
// 			ExistingSession: &sessions.SessionState{
// 				User:         "already",
// 				Email:        "already@populated.com",
// 				IDToken:      idToken,
// 				AccessToken:  accessToken,
// 				RefreshToken: refreshToken,
// 			},
// 			EmailClaim:  "email",
// 			GroupsClaim: "groups",
// 			ProfileJSON: map[string]interface{}{
// 				"email": "new@thing.com",
// 			},
// 			IntrospectJSON: map[string]interface{}{
// 				"active":     true,
// 				"exp":        1613553280,
// 				"iat":        1613549680,
// 				"sub":        "00u65ah10oSUDoNd65d6",
// 				"aud":        "0oa5t6ts1XZgPOOSA5d6",
// 				"iss":        "https://dev.authprovider.com/oauth2/default",
// 				"jti":        "ID.ShxppK0vysORHsr8S9GSPPRV-Dy1PFhqx3fPYwtijc0",
// 				"token_type": "Bearer",
// 				"at_hash":    "_1EsbE1ZpyMOLiu-VdBTlg",
// 				"idp":        "0oa5t8x90SALHBBk85d6",
// 				"auth_time":  1613549026,
// 				"amr":        []string{"pwd"},
// 			},
// 			ExpectedError: nil,
// 			ExpectedSession: &sessions.SessionState{
// 				User:             "already",
// 				Email:            "already@populated.com",
// 				IDToken:          idToken,
// 				AccessToken:      accessToken,
// 				RefreshToken:     refreshToken,
// 				IntrospectClaims: "eyJhY3RpdmUiOnRydWUsImFtciI6WyJwd2QiXSwiYXRfaGFzaCI6Il8xRXNiRTFacHlNT0xpdS1WZEJUbGciLCJhdWQiOiIwb2E1dDZ0czFYWmdQT09TQTVkNiIsImF1dGhfdGltZSI6MTYxMzU0OTAyNiwiZXhwIjoxNjEzNTUzMjgwLCJpYXQiOjE2MTM1NDk2ODAsImlkcCI6IjBvYTV0OHg5MFNBTEhCQms4NWQ2IiwiaXNzIjoiaHR0cHM6Ly9kZXYuYXV0aHByb3ZpZGVyLmNvbS9vYXV0aDIvZGVmYXVsdCIsImp0aSI6IklELlNoeHBwSzB2eXNPUkhzcjhTOUdTUFBSVi1EeTFQRmhxeDNmUFl3dGlqYzAiLCJzdWIiOiIwMHU2NWFoMTBvU1VEb05kNjVkNiIsInRva2VuX3R5cGUiOiJCZWFyZXIifQ==",
// 			},
// 		},
// 	}
// 	for testName, tc := range testCases {
// 		t.Run(testName, func(t *testing.T) {
// 			profileJSON, err := json.Marshal(tc.ProfileJSON)
// 			assert.NoError(t, err)

// 			introspectJSON, err := json.Marshal(tc.IntrospectJSON)
// 			assert.NoError(t, err)

// 			server, provider := newTestOIDCSetup([]byte(`{}`), profileJSON, introspectJSON)
// 			assert.NoError(t, err)

// 			provider.EmailClaim = tc.EmailClaim
// 			provider.GroupsClaim = tc.GroupsClaim
// 			defer server.Close()

// 			err = provider.EnrichSession(context.Background(), tc.ExistingSession)
// 			assert.Equal(t, tc.ExpectedError, err)
// 			assert.Equal(t, *tc.ExpectedSession, *tc.ExistingSession)
// 		})
// 	}
// }
