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 groups", configuredType: "oidc", configuredScope: "", expectedScope: "openid email profile 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", }, { name: "github: with a configured scope provided", configuredType: "github", configuredScope: "user:email org:read", expectedScope: "user:email org:read", }, } 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)) }) } }