314 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			314 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			Go
		
	
	
	
| package providers
 | |
| 
 | |
| import (
 | |
| 	"os"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
 | |
| 	. "github.com/onsi/gomega"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	clientID     = "bazquux"
 | |
| 	clientSecret = "xyzzyplugh"
 | |
| 	providerID   = "providerID"
 | |
| 
 | |
| 	msIssuerURL = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/v2.0/"
 | |
| 	msKeysURL   = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/discovery/v2.0/keys"
 | |
| 	msAuthURL   = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_sign_in"
 | |
| 	msTokenURL  = "https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/oauth2/v2.0/token?p=b2c_1_sign_in"
 | |
| )
 | |
| 
 | |
| func TestClientSecretFileOptionFails(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 
 | |
| 	providerConfig := options.Provider{
 | |
| 		ID:               providerID,
 | |
| 		Type:             "google",
 | |
| 		ClientID:         clientID,
 | |
| 		ClientSecretFile: clientSecret,
 | |
| 	}
 | |
| 
 | |
| 	p, err := newProviderDataFromConfig(providerConfig)
 | |
| 	g.Expect(err).ToNot(HaveOccurred())
 | |
| 	g.Expect(p.ClientSecretFile).To(Equal(clientSecret))
 | |
| 	g.Expect(p.ClientSecret).To(BeEmpty())
 | |
| 
 | |
| 	s, err := p.GetClientSecret()
 | |
| 	g.Expect(err).To(HaveOccurred())
 | |
| 	g.Expect(s).To(BeEmpty())
 | |
| }
 | |
| 
 | |
| func TestClientSecretFileOption(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 
 | |
| 	f, err := os.CreateTemp("", "client_secret_temp_file_")
 | |
| 	g.Expect(err).ToNot(HaveOccurred())
 | |
| 
 | |
| 	clientSecretFileName := f.Name()
 | |
| 
 | |
| 	defer func() {
 | |
| 		g.Expect(f.Close()).To(Succeed())
 | |
| 		g.Expect(os.Remove(clientSecretFileName)).To(Succeed())
 | |
| 	}()
 | |
| 
 | |
| 	_, err = f.WriteString("testcase")
 | |
| 	g.Expect(err).ToNot(HaveOccurred())
 | |
| 
 | |
| 	providerConfig := options.Provider{
 | |
| 		ID:               providerID,
 | |
| 		Type:             "google",
 | |
| 		ClientID:         clientID,
 | |
| 		ClientSecretFile: clientSecretFileName,
 | |
| 	}
 | |
| 
 | |
| 	p, err := newProviderDataFromConfig(providerConfig)
 | |
| 	g.Expect(err).ToNot(HaveOccurred())
 | |
| 	g.Expect(p.ClientSecretFile).To(Equal(clientSecretFileName))
 | |
| 	g.Expect(p.ClientSecret).To(BeEmpty())
 | |
| 
 | |
| 	s, err := p.GetClientSecret()
 | |
| 	g.Expect(err).ToNot(HaveOccurred())
 | |
| 	g.Expect(s).To(Equal("testcase"))
 | |
| }
 | |
| 
 | |
| func TestSkipOIDCDiscovery(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 	providerConfig := options.Provider{
 | |
| 		ID:               providerID,
 | |
| 		Type:             "oidc",
 | |
| 		ClientID:         clientID,
 | |
| 		ClientSecretFile: clientSecret,
 | |
| 		OIDCConfig: options.OIDCOptions{
 | |
| 			IssuerURL:     msIssuerURL,
 | |
| 			SkipDiscovery: true,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	_, err := newProviderDataFromConfig(providerConfig)
 | |
| 	g.Expect(err).To(MatchError("error building OIDC ProviderVerifier: invalid provider verifier options: missing required setting: jwks-url"))
 | |
| 
 | |
| 	providerConfig.LoginURL = msAuthURL
 | |
| 	providerConfig.RedeemURL = msTokenURL
 | |
| 	providerConfig.OIDCConfig.JwksURL = msKeysURL
 | |
| 
 | |
| 	_, err = newProviderDataFromConfig(providerConfig)
 | |
| 	g.Expect(err).ToNot(HaveOccurred())
 | |
| }
 | |
| 
 | |
| func TestURLsCorrectlyParsed(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 
 | |
| 	providerConfig := options.Provider{
 | |
| 		ID:               providerID,
 | |
| 		Type:             "oidc",
 | |
| 		ClientID:         clientID,
 | |
| 		ClientSecretFile: clientSecret,
 | |
| 		LoginURL:         msAuthURL,
 | |
| 		RedeemURL:        msTokenURL,
 | |
| 		OIDCConfig: options.OIDCOptions{
 | |
| 			IssuerURL:     msIssuerURL,
 | |
| 			SkipDiscovery: true,
 | |
| 			JwksURL:       msKeysURL,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	pd, err := newProviderDataFromConfig(providerConfig)
 | |
| 	g.Expect(err).ToNot(HaveOccurred())
 | |
| 
 | |
| 	g.Expect(pd.LoginURL.String()).To(Equal(msAuthURL))
 | |
| 	g.Expect(pd.RedeemURL.String()).To(Equal(msTokenURL))
 | |
| }
 | |
| 
 | |
| func TestScope(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name            string
 | |
| 		configuredType  options.ProviderType
 | |
| 		configuredScope string
 | |
| 		expectedScope   string
 | |
| 		allowedGroups   []string
 | |
| 	}{
 | |
| 		{
 | |
| 			name:            "oidc: with no scope provided",
 | |
| 			configuredType:  "oidc",
 | |
| 			configuredScope: "",
 | |
| 			expectedScope:   "openid email profile",
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "oidc: with no scope provided and allowed groups",
 | |
| 			configuredType:  "oidc",
 | |
| 			configuredScope: "",
 | |
| 			expectedScope:   "openid email profile groups",
 | |
| 			allowedGroups:   []string{"foo"},
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "oidc: with custom scope including groups without allowed groups",
 | |
| 			configuredType:  "oidc",
 | |
| 			configuredScope: "myscope groups",
 | |
| 			expectedScope:   "myscope groups",
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "oidc: with custom scope without groups but allowed groups",
 | |
| 			configuredType:  "oidc",
 | |
| 			configuredScope: "myscope",
 | |
| 			expectedScope:   "myscope",
 | |
| 			allowedGroups:   []string{"foo"},
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "oidc: with custom scope with groups and allowed groups",
 | |
| 			configuredType:  "oidc",
 | |
| 			configuredScope: "myscope groups",
 | |
| 			expectedScope:   "myscope groups",
 | |
| 			allowedGroups:   []string{"foo"},
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "oidc: with a configured scope provided",
 | |
| 			configuredType:  "oidc",
 | |
| 			configuredScope: "openid",
 | |
| 			expectedScope:   "openid",
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "github: with no scope provided",
 | |
| 			configuredType:  "github",
 | |
| 			configuredScope: "",
 | |
| 			expectedScope:   "user:email read:org",
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "github: with a configured scope provided",
 | |
| 			configuredType:  "github",
 | |
| 			configuredScope: "read:user read:org",
 | |
| 			expectedScope:   "read:user read:org",
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "keycloak: with no scope provided and groups",
 | |
| 			configuredType:  "keycloak-oidc",
 | |
| 			configuredScope: "",
 | |
| 			expectedScope:   "openid email profile groups",
 | |
| 			allowedGroups:   []string{"foo"},
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "keycloak: with custom scope and groups",
 | |
| 			configuredType:  "keycloak-oidc",
 | |
| 			configuredScope: "myscope",
 | |
| 			expectedScope:   "myscope",
 | |
| 			allowedGroups:   []string{"foo"},
 | |
| 		},
 | |
| 		{
 | |
| 			name:            "keycloak: with custom scope and groups scope",
 | |
| 			configuredType:  "keycloak-oidc",
 | |
| 			configuredScope: "myscope groups",
 | |
| 			expectedScope:   "myscope groups",
 | |
| 			allowedGroups:   []string{"foo"},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, tc := range testCases {
 | |
| 		providerConfig := options.Provider{
 | |
| 			ID:               providerID,
 | |
| 			Type:             tc.configuredType,
 | |
| 			ClientID:         clientID,
 | |
| 			ClientSecretFile: clientSecret,
 | |
| 			LoginURL:         msAuthURL,
 | |
| 			RedeemURL:        msTokenURL,
 | |
| 			Scope:            tc.configuredScope,
 | |
| 			AllowedGroups:    tc.allowedGroups,
 | |
| 			OIDCConfig: options.OIDCOptions{
 | |
| 				IssuerURL:     msIssuerURL,
 | |
| 				SkipDiscovery: true,
 | |
| 				JwksURL:       msKeysURL,
 | |
| 			},
 | |
| 		}
 | |
| 
 | |
| 		pd, err := NewProvider(providerConfig)
 | |
| 		g.Expect(err).ToNot(HaveOccurred())
 | |
| 
 | |
| 		g.Expect(pd.Data().Scope).To(Equal(tc.expectedScope))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestForcedMethodS256(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 	options := options.NewOptions()
 | |
| 	options.Providers[0].CodeChallengeMethod = CodeChallengeMethodS256
 | |
| 	method := parseCodeChallengeMethod(options.Providers[0])
 | |
| 
 | |
| 	g.Expect(method).To(Equal(CodeChallengeMethodS256))
 | |
| }
 | |
| 
 | |
| func TestForcedMethodPlain(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 	options := options.NewOptions()
 | |
| 	options.Providers[0].CodeChallengeMethod = CodeChallengeMethodPlain
 | |
| 	method := parseCodeChallengeMethod(options.Providers[0])
 | |
| 
 | |
| 	g.Expect(method).To(Equal(CodeChallengeMethodPlain))
 | |
| }
 | |
| 
 | |
| func TestPrefersS256(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 	options := options.NewOptions()
 | |
| 	method := parseCodeChallengeMethod(options.Providers[0])
 | |
| 
 | |
| 	g.Expect(method).To(Equal(""))
 | |
| }
 | |
| 
 | |
| func TestCanOverwriteS256(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 	options := options.NewOptions()
 | |
| 	options.Providers[0].CodeChallengeMethod = "plain"
 | |
| 	method := parseCodeChallengeMethod(options.Providers[0])
 | |
| 
 | |
| 	g.Expect(method).To(Equal(CodeChallengeMethodPlain))
 | |
| }
 | |
| 
 | |
| func TestEmailClaimCorrectlySet(t *testing.T) {
 | |
| 	g := NewWithT(t)
 | |
| 
 | |
| 	testCases := []struct {
 | |
| 		name               string
 | |
| 		userIDClaim        string
 | |
| 		emailClaim         string
 | |
| 		expectedEmailClaim string
 | |
| 	}{
 | |
| 		{
 | |
| 			name:               "do not override EmailClaim if UserIDClaim is empty",
 | |
| 			userIDClaim:        "",
 | |
| 			emailClaim:         "email",
 | |
| 			expectedEmailClaim: "email",
 | |
| 		},
 | |
| 		{
 | |
| 			name:               "set EmailClaim to UserIDClaim",
 | |
| 			userIDClaim:        "user_id_claim",
 | |
| 			emailClaim:         "email",
 | |
| 			expectedEmailClaim: "user_id_claim",
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.name, func(t *testing.T) {
 | |
| 			providerConfig := options.Provider{
 | |
| 				ID:               providerID,
 | |
| 				Type:             "oidc",
 | |
| 				ClientID:         clientID,
 | |
| 				ClientSecretFile: clientSecret,
 | |
| 				LoginURL:         msAuthURL,
 | |
| 				RedeemURL:        msTokenURL,
 | |
| 				OIDCConfig: options.OIDCOptions{
 | |
| 					IssuerURL:     msIssuerURL,
 | |
| 					SkipDiscovery: true,
 | |
| 					JwksURL:       msKeysURL,
 | |
| 					UserIDClaim:   tc.userIDClaim,
 | |
| 					EmailClaim:    tc.emailClaim,
 | |
| 				},
 | |
| 			}
 | |
| 
 | |
| 			pd, err := newProviderDataFromConfig(providerConfig)
 | |
| 			g.Expect(err).ToNot(HaveOccurred())
 | |
| 
 | |
| 			g.Expect(pd.EmailClaim).To(Equal(tc.expectedEmailClaim))
 | |
| 		})
 | |
| 	}
 | |
| }
 |