aboutsummaryrefslogtreecommitdiff
path: root/weed/iam/oidc/mock_provider.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/iam/oidc/mock_provider.go')
-rw-r--r--weed/iam/oidc/mock_provider.go203
1 files changed, 203 insertions, 0 deletions
diff --git a/weed/iam/oidc/mock_provider.go b/weed/iam/oidc/mock_provider.go
new file mode 100644
index 000000000..c4ff9a401
--- /dev/null
+++ b/weed/iam/oidc/mock_provider.go
@@ -0,0 +1,203 @@
+// This file contains mock OIDC provider implementations for testing only.
+// These should NOT be used in production environments.
+
+package oidc
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/golang-jwt/jwt/v5"
+ "github.com/seaweedfs/seaweedfs/weed/iam/providers"
+)
+
+// MockOIDCProvider is a mock implementation for testing
+type MockOIDCProvider struct {
+ *OIDCProvider
+ TestTokens map[string]*providers.TokenClaims
+ TestUsers map[string]*providers.ExternalIdentity
+}
+
+// NewMockOIDCProvider creates a mock OIDC provider for testing
+func NewMockOIDCProvider(name string) *MockOIDCProvider {
+ return &MockOIDCProvider{
+ OIDCProvider: NewOIDCProvider(name),
+ TestTokens: make(map[string]*providers.TokenClaims),
+ TestUsers: make(map[string]*providers.ExternalIdentity),
+ }
+}
+
+// AddTestToken adds a test token with expected claims
+func (m *MockOIDCProvider) AddTestToken(token string, claims *providers.TokenClaims) {
+ m.TestTokens[token] = claims
+}
+
+// AddTestUser adds a test user with expected identity
+func (m *MockOIDCProvider) AddTestUser(userID string, identity *providers.ExternalIdentity) {
+ m.TestUsers[userID] = identity
+}
+
+// Authenticate overrides the parent Authenticate method to use mock data
+func (m *MockOIDCProvider) Authenticate(ctx context.Context, token string) (*providers.ExternalIdentity, error) {
+ if !m.initialized {
+ return nil, fmt.Errorf("provider not initialized")
+ }
+
+ if token == "" {
+ return nil, fmt.Errorf("token cannot be empty")
+ }
+
+ // Validate token using mock validation
+ claims, err := m.ValidateToken(ctx, token)
+ if err != nil {
+ return nil, err
+ }
+
+ // Map claims to external identity
+ email, _ := claims.GetClaimString("email")
+ displayName, _ := claims.GetClaimString("name")
+ groups, _ := claims.GetClaimStringSlice("groups")
+
+ return &providers.ExternalIdentity{
+ UserID: claims.Subject,
+ Email: email,
+ DisplayName: displayName,
+ Groups: groups,
+ Provider: m.name,
+ }, nil
+}
+
+// ValidateToken validates tokens using test data
+func (m *MockOIDCProvider) ValidateToken(ctx context.Context, token string) (*providers.TokenClaims, error) {
+ if !m.initialized {
+ return nil, fmt.Errorf("provider not initialized")
+ }
+
+ if token == "" {
+ return nil, fmt.Errorf("token cannot be empty")
+ }
+
+ // Special test tokens
+ if token == "expired_token" {
+ return nil, fmt.Errorf("token has expired")
+ }
+ if token == "invalid_token" {
+ return nil, fmt.Errorf("invalid token")
+ }
+
+ // Try to parse as JWT token first
+ if len(token) > 20 && strings.Count(token, ".") >= 2 {
+ parsedToken, _, err := new(jwt.Parser).ParseUnverified(token, jwt.MapClaims{})
+ if err == nil {
+ if jwtClaims, ok := parsedToken.Claims.(jwt.MapClaims); ok {
+ issuer, _ := jwtClaims["iss"].(string)
+ subject, _ := jwtClaims["sub"].(string)
+ audience, _ := jwtClaims["aud"].(string)
+
+ // Verify the issuer matches our configuration
+ if issuer == m.config.Issuer && subject != "" {
+ // Extract expiration and issued at times
+ var expiresAt, issuedAt time.Time
+ if exp, ok := jwtClaims["exp"].(float64); ok {
+ expiresAt = time.Unix(int64(exp), 0)
+ }
+ if iat, ok := jwtClaims["iat"].(float64); ok {
+ issuedAt = time.Unix(int64(iat), 0)
+ }
+
+ return &providers.TokenClaims{
+ Subject: subject,
+ Issuer: issuer,
+ Audience: audience,
+ ExpiresAt: expiresAt,
+ IssuedAt: issuedAt,
+ Claims: map[string]interface{}{
+ "email": subject + "@test-domain.com",
+ "name": "Test User " + subject,
+ },
+ }, nil
+ }
+ }
+ }
+ }
+
+ // Check test tokens
+ if claims, exists := m.TestTokens[token]; exists {
+ return claims, nil
+ }
+
+ // Default test token for basic testing
+ if token == "valid_test_token" {
+ return &providers.TokenClaims{
+ Subject: "test-user-id",
+ Issuer: m.config.Issuer,
+ Audience: m.config.ClientID,
+ ExpiresAt: time.Now().Add(time.Hour),
+ IssuedAt: time.Now(),
+ Claims: map[string]interface{}{
+ "email": "test@example.com",
+ "name": "Test User",
+ "groups": []string{"developers", "users"},
+ },
+ }, nil
+ }
+
+ return nil, fmt.Errorf("unknown test token: %s", token)
+}
+
+// GetUserInfo returns test user info
+func (m *MockOIDCProvider) GetUserInfo(ctx context.Context, userID string) (*providers.ExternalIdentity, error) {
+ if !m.initialized {
+ return nil, fmt.Errorf("provider not initialized")
+ }
+
+ if userID == "" {
+ return nil, fmt.Errorf("user ID cannot be empty")
+ }
+
+ // Check test users
+ if identity, exists := m.TestUsers[userID]; exists {
+ return identity, nil
+ }
+
+ // Default test user
+ return &providers.ExternalIdentity{
+ UserID: userID,
+ Email: userID + "@example.com",
+ DisplayName: "Test User " + userID,
+ Provider: m.name,
+ }, nil
+}
+
+// SetupDefaultTestData configures common test data
+func (m *MockOIDCProvider) SetupDefaultTestData() {
+ // Create default token claims
+ defaultClaims := &providers.TokenClaims{
+ Subject: "test-user-123",
+ Issuer: "https://test-issuer.com",
+ Audience: "test-client-id",
+ ExpiresAt: time.Now().Add(time.Hour),
+ IssuedAt: time.Now(),
+ Claims: map[string]interface{}{
+ "email": "testuser@example.com",
+ "name": "Test User",
+ "groups": []string{"developers"},
+ },
+ }
+
+ // Add multiple token variants for compatibility
+ m.AddTestToken("valid_token", defaultClaims)
+ m.AddTestToken("valid-oidc-token", defaultClaims) // For integration tests
+ m.AddTestToken("valid_test_token", defaultClaims) // For STS tests
+
+ // Add default test users
+ m.AddTestUser("test-user-123", &providers.ExternalIdentity{
+ UserID: "test-user-123",
+ Email: "testuser@example.com",
+ DisplayName: "Test User",
+ Groups: []string{"developers"},
+ Provider: m.name,
+ })
+}