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 or public-key-files"))
 | 
						|
 | 
						|
	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))
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 |