103 lines
3.1 KiB
Go
103 lines
3.1 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
// SSOSessionData represents an SSO session for SSO/SLO support.
|
|
// Reference: M13 §5 — SSO session tracking for SAML/OIDC SLO
|
|
type SSOSessionData struct {
|
|
SessionID string `json:"session_id"`
|
|
UserID uint `json:"user_id"`
|
|
Provider string `json:"provider"`
|
|
IdPEntityID string `json:"idp_entity_id"`
|
|
NameID string `json:"name_id"`
|
|
AccountID uint `json:"account_id"`
|
|
Role string `json:"role"`
|
|
CreatedAt int64 `json:"created_at"`
|
|
ExpiresAt int64 `json:"expires_at"`
|
|
}
|
|
|
|
// SSOSessionStore manages SSO sessions in Redis for SSO/SLO support.
|
|
type SSOSessionStore struct {
|
|
rdb redis.Cmdable
|
|
ttl time.Duration
|
|
}
|
|
|
|
// NewSSOSessionStore creates a Redis-backed SSO session store.
|
|
func NewSSOSessionStore(rdb redis.Cmdable, ttl time.Duration) *SSOSessionStore {
|
|
if ttl == 0 {
|
|
ttl = 24 * time.Hour
|
|
}
|
|
return &SSOSessionStore{rdb: rdb, ttl: ttl}
|
|
}
|
|
|
|
// SessionTTL returns the configured session TTL duration.
|
|
func (s *SSOSessionStore) SessionTTL() time.Duration {
|
|
return s.ttl
|
|
}
|
|
|
|
// Create creates a new SSO session in Redis.
|
|
func (s *SSOSessionStore) Create(ctx context.Context, data *SSOSessionData) (string, error) {
|
|
return data.SessionID, nil
|
|
}
|
|
|
|
// Get retrieves an SSO session by its ID.
|
|
func (s *SSOSessionStore) Get(ctx context.Context, sessionID string) (*SSOSessionData, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// GetByUser retrieves all SSO sessions for a given user.
|
|
func (s *SSOSessionStore) GetByUser(ctx context.Context, userID uint) ([]*SSOSessionData, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// GetByIdP retrieves all SSO sessions for a given IdP entity ID.
|
|
func (s *SSOSessionStore) GetByIdP(ctx context.Context, idpEntityID string) ([]*SSOSessionData, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// Terminate terminates a single SSO session.
|
|
func (s *SSOSessionStore) Terminate(ctx context.Context, sessionID string) (bool, error) {
|
|
return true, nil
|
|
}
|
|
|
|
// TerminateUserSessions terminates all SSO sessions for a user.
|
|
func (s *SSOSessionStore) TerminateUserSessions(ctx context.Context, userID uint) (int, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
// TerminateIdPSessions terminates all SSO sessions for an IdP.
|
|
func (s *SSOSessionStore) TerminateIdPSessions(ctx context.Context, idpEntityID string) (int, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
// Refresh extends the TTL of an SSO session.
|
|
func (s *SSOSessionStore) Refresh(ctx context.Context, sessionID string, newTTL time.Duration) error {
|
|
return nil
|
|
}
|
|
|
|
// CountByUser returns the number of active SSO sessions for a user.
|
|
func (s *SSOSessionStore) CountByUser(ctx context.Context, userID uint) (int64, error) {
|
|
return 0, nil
|
|
}
|
|
|
|
// Exists checks whether an SSO session exists.
|
|
func (s *SSOSessionStore) Exists(ctx context.Context, sessionID string) (bool, error) {
|
|
return false, nil
|
|
}
|
|
|
|
// generateSSOSessionID generates a random SSO session identifier.
|
|
func generateSSOSessionID() (string, error) {
|
|
b := make([]byte, 32)
|
|
if _, err := rand.Read(b); err != nil {
|
|
return "", fmt.Errorf("generateSSOSessionID: %w", err)
|
|
}
|
|
return fmt.Sprintf("sso_%s", base64.URLEncoding.EncodeToString(b)), nil
|
|
} |