mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
c3f23cb99b
* Resolve issue with opaque tokens not being parsed correctly * Increase test coverage * Further improvements to test coverage and code quality * Add new providers. * fixup! Add new providers. * Cleanup. * fixup! Cleanup. * fixup! fixup! Cleanup. * fixup! fixup! fixup! Cleanup. * fixup! fixup! fixup! fixup! Cleanup. * Memory management optimisation 24 bytes per Put < 256-4096 bytes per buffer allocation avoided (10-170x difference) * Pooling cleanup.
151 lines
4.5 KiB
Go
151 lines
4.5 KiB
Go
package providers
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
// ProviderFactory encapsulates the logic for creating and configuring OIDC providers.
|
|
type ProviderFactory struct {
|
|
registry *ProviderRegistry
|
|
}
|
|
|
|
// NewProviderFactory creates a new factory with a pre-configured registry.
|
|
func NewProviderFactory() *ProviderFactory {
|
|
registry := NewProviderRegistry()
|
|
|
|
registry.RegisterProvider(NewGenericProvider())
|
|
registry.RegisterProvider(NewGoogleProvider())
|
|
registry.RegisterProvider(NewAzureProvider())
|
|
registry.RegisterProvider(NewGitHubProvider())
|
|
registry.RegisterProvider(NewAuth0Provider())
|
|
registry.RegisterProvider(NewOktaProvider())
|
|
registry.RegisterProvider(NewKeycloakProvider())
|
|
registry.RegisterProvider(NewAWSCognitoProvider())
|
|
registry.RegisterProvider(NewGitLabProvider())
|
|
|
|
return &ProviderFactory{
|
|
registry: registry,
|
|
}
|
|
}
|
|
|
|
// CreateProvider creates an OIDC provider based on the issuer URL.
|
|
// It automatically detects the provider type and returns a configured instance.
|
|
func (f *ProviderFactory) CreateProvider(issuerURL string) (OIDCProvider, error) {
|
|
if issuerURL == "" {
|
|
return nil, fmt.Errorf("issuer URL cannot be empty")
|
|
}
|
|
|
|
parsedURL, err := url.Parse(issuerURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid issuer URL format: %w", err)
|
|
}
|
|
|
|
// Check if the URL has a valid scheme and host
|
|
if parsedURL.Scheme == "" || parsedURL.Host == "" {
|
|
return nil, fmt.Errorf("invalid issuer URL format: URL must have a valid scheme and host")
|
|
}
|
|
|
|
provider := f.registry.DetectProvider(issuerURL)
|
|
if provider == nil {
|
|
return nil, fmt.Errorf("unable to detect provider for issuer URL: %s", issuerURL)
|
|
}
|
|
|
|
if err := provider.ValidateConfig(); err != nil {
|
|
return nil, fmt.Errorf("provider configuration validation failed: %w", err)
|
|
}
|
|
|
|
return provider, nil
|
|
}
|
|
|
|
// CreateProviderByType creates a provider instance of the specified type.
|
|
// This is useful when you want to force a specific provider type regardless of URL.
|
|
func (f *ProviderFactory) CreateProviderByType(providerType ProviderType) (OIDCProvider, error) {
|
|
var provider OIDCProvider
|
|
|
|
switch providerType {
|
|
case ProviderTypeGeneric:
|
|
provider = NewGenericProvider()
|
|
case ProviderTypeGoogle:
|
|
provider = NewGoogleProvider()
|
|
case ProviderTypeAzure:
|
|
provider = NewAzureProvider()
|
|
case ProviderTypeGitHub:
|
|
provider = NewGitHubProvider()
|
|
case ProviderTypeAuth0:
|
|
provider = NewAuth0Provider()
|
|
case ProviderTypeOkta:
|
|
provider = NewOktaProvider()
|
|
case ProviderTypeKeycloak:
|
|
provider = NewKeycloakProvider()
|
|
case ProviderTypeAWSCognito:
|
|
provider = NewAWSCognitoProvider()
|
|
case ProviderTypeGitLab:
|
|
provider = NewGitLabProvider()
|
|
default:
|
|
return nil, fmt.Errorf("unsupported provider type: %d", providerType)
|
|
}
|
|
|
|
if err := provider.ValidateConfig(); err != nil {
|
|
return nil, fmt.Errorf("provider configuration validation failed: %w", err)
|
|
}
|
|
|
|
return provider, nil
|
|
}
|
|
|
|
// GetSupportedProviders returns a list of all supported provider types and their detection patterns.
|
|
func (f *ProviderFactory) GetSupportedProviders() map[ProviderType][]string {
|
|
return map[ProviderType][]string{
|
|
ProviderTypeGeneric: {"*"},
|
|
ProviderTypeGoogle: {"accounts.google.com"},
|
|
ProviderTypeAzure: {"login.microsoftonline.com", "sts.windows.net"},
|
|
ProviderTypeGitHub: {"github.com"},
|
|
ProviderTypeAuth0: {".auth0.com"},
|
|
ProviderTypeOkta: {".okta.com", ".oktapreview.com", ".okta-emea.com"},
|
|
ProviderTypeKeycloak: {"keycloak"},
|
|
ProviderTypeAWSCognito: {"cognito-idp", ".amazonaws.com"},
|
|
ProviderTypeGitLab: {"gitlab.com"},
|
|
}
|
|
}
|
|
|
|
// DetectProviderType determines the provider type for a given issuer URL.
|
|
// This is useful for diagnostic purposes or UI display.
|
|
func (f *ProviderFactory) DetectProviderType(issuerURL string) (ProviderType, error) {
|
|
provider, err := f.CreateProvider(issuerURL)
|
|
if err != nil {
|
|
return ProviderTypeGeneric, err
|
|
}
|
|
return provider.GetType(), nil
|
|
}
|
|
|
|
// IsProviderSupported checks if a given issuer URL is supported by any registered provider.
|
|
func (f *ProviderFactory) IsProviderSupported(issuerURL string) bool {
|
|
if issuerURL == "" {
|
|
return false
|
|
}
|
|
|
|
normalizedURL, err := url.Parse(issuerURL)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// Check if the URL has a valid scheme and host
|
|
if normalizedURL.Scheme == "" || normalizedURL.Host == "" {
|
|
return false
|
|
}
|
|
|
|
host := strings.ToLower(normalizedURL.Host)
|
|
supportedProviders := f.GetSupportedProviders()
|
|
|
|
for _, patterns := range supportedProviders {
|
|
for _, pattern := range patterns {
|
|
if pattern == "*" || strings.Contains(host, strings.ToLower(pattern)) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|