package domain import ( "time" "github.com/google/uuid" ) // TenantStatus represents the status of a tenant type TenantStatus string const ( TenantStatusActive TenantStatus = "active" TenantStatusSuspended TenantStatus = "suspended" TenantStatusInactive TenantStatus = "inactive" ) // Tenant represents a tenant in the multi-tenant system type Tenant struct { ID uuid.UUID `json:"id" db:"id"` Name string `json:"name" validate:"required,min=1,max=255" db:"name"` Slug string `json:"slug" validate:"required,min=1,max=100,alphanum" db:"slug"` Status TenantStatus `json:"status" validate:"required,oneof=active suspended inactive" db:"status"` Domain string `json:"domain,omitempty" validate:"omitempty,fqdn" db:"domain"` Description string `json:"description,omitempty" validate:"max=1000" db:"description"` Settings TenantSettings `json:"settings" db:"settings"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` CreatedBy string `json:"created_by" db:"created_by"` UpdatedBy string `json:"updated_by" db:"updated_by"` } // TenantSettings contains tenant-specific configuration type TenantSettings struct { // Authentication settings AuthProvider string `json:"auth_provider,omitempty"` // oauth2, saml, header SAMLSettings *SAMLSettings `json:"saml_settings,omitempty"` OAuth2Settings *OAuth2Settings `json:"oauth2_settings,omitempty"` // Session settings SessionTimeout Duration `json:"session_timeout,omitempty"` MaxConcurrentSessions int `json:"max_concurrent_sessions,omitempty"` // Security settings RequireMFA bool `json:"require_mfa"` AllowedIPRanges []string `json:"allowed_ip_ranges,omitempty"` PasswordPolicy *PasswordPolicy `json:"password_policy,omitempty"` // Token settings DefaultTokenDuration Duration `json:"default_token_duration,omitempty"` MaxTokenDuration Duration `json:"max_token_duration,omitempty"` // Feature flags Features map[string]bool `json:"features,omitempty"` // Custom attributes CustomAttributes map[string]string `json:"custom_attributes,omitempty"` } // SAMLSettings contains SAML-specific configuration for a tenant type SAMLSettings struct { IDPMetadataURL string `json:"idp_metadata_url,omitempty"` SPEntityID string `json:"sp_entity_id,omitempty"` ACSURL string `json:"acs_url,omitempty"` SPPrivateKey string `json:"sp_private_key,omitempty"` SPCertificate string `json:"sp_certificate,omitempty"` AttributeMapping map[string]string `json:"attribute_mapping,omitempty"` } // OAuth2Settings contains OAuth2-specific configuration for a tenant type OAuth2Settings struct { ProviderURL string `json:"provider_url,omitempty"` ClientID string `json:"client_id,omitempty"` ClientSecret string `json:"client_secret,omitempty"` Scopes []string `json:"scopes,omitempty"` AttributeMapping map[string]string `json:"attribute_mapping,omitempty"` } // PasswordPolicy defines password requirements for a tenant type PasswordPolicy struct { MinLength int `json:"min_length"` RequireUppercase bool `json:"require_uppercase"` RequireLowercase bool `json:"require_lowercase"` RequireNumbers bool `json:"require_numbers"` RequireSymbols bool `json:"require_symbols"` MaxAge Duration `json:"max_age,omitempty"` PreventReuse int `json:"prevent_reuse"` // Number of previous passwords to prevent reuse } // TenantUser represents a user within a specific tenant type TenantUser struct { ID uuid.UUID `json:"id" db:"id"` TenantID uuid.UUID `json:"tenant_id" validate:"required" db:"tenant_id"` UserID string `json:"user_id" validate:"required" db:"user_id"` Email string `json:"email" validate:"required,email" db:"email"` Name string `json:"name" validate:"required" db:"name"` Roles []string `json:"roles" db:"roles"` Permissions []string `json:"permissions" db:"permissions"` Status UserStatus `json:"status" validate:"required,oneof=active inactive suspended" db:"status"` Metadata map[string]string `json:"metadata,omitempty" db:"metadata"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` LastLoginAt *time.Time `json:"last_login_at,omitempty" db:"last_login_at"` } // UserStatus represents the status of a user within a tenant type UserStatus string const ( UserStatusActive UserStatus = "active" UserStatusInactive UserStatus = "inactive" UserStatusSuspended UserStatus = "suspended" ) // TenantRole represents a role within a tenant type TenantRole struct { ID uuid.UUID `json:"id" db:"id"` TenantID uuid.UUID `json:"tenant_id" validate:"required" db:"tenant_id"` Name string `json:"name" validate:"required,min=1,max=100" db:"name"` Description string `json:"description,omitempty" validate:"max=500" db:"description"` Permissions []string `json:"permissions" db:"permissions"` IsSystem bool `json:"is_system" db:"is_system"` // System roles cannot be deleted CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` CreatedBy string `json:"created_by" db:"created_by"` UpdatedBy string `json:"updated_by" db:"updated_by"` } // CreateTenantRequest represents a request to create a new tenant type CreateTenantRequest struct { Name string `json:"name" validate:"required,min=1,max=255"` Slug string `json:"slug" validate:"required,min=1,max=100,alphanum"` Domain string `json:"domain,omitempty" validate:"omitempty,fqdn"` Description string `json:"description,omitempty" validate:"max=1000"` Settings TenantSettings `json:"settings,omitempty"` } // UpdateTenantRequest represents a request to update a tenant type UpdateTenantRequest struct { Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"` Status *TenantStatus `json:"status,omitempty" validate:"omitempty,oneof=active suspended inactive"` Domain *string `json:"domain,omitempty" validate:"omitempty,fqdn"` Description *string `json:"description,omitempty" validate:"omitempty,max=1000"` Settings *TenantSettings `json:"settings,omitempty"` } // CreateTenantUserRequest represents a request to create a user in a tenant type CreateTenantUserRequest struct { TenantID uuid.UUID `json:"tenant_id" validate:"required"` UserID string `json:"user_id" validate:"required"` Email string `json:"email" validate:"required,email"` Name string `json:"name" validate:"required"` Roles []string `json:"roles,omitempty"` Permissions []string `json:"permissions,omitempty"` Metadata map[string]string `json:"metadata,omitempty"` } // UpdateTenantUserRequest represents a request to update a tenant user type UpdateTenantUserRequest struct { Email *string `json:"email,omitempty" validate:"omitempty,email"` Name *string `json:"name,omitempty" validate:"omitempty,min=1"` Roles []string `json:"roles,omitempty"` Permissions []string `json:"permissions,omitempty"` Status *UserStatus `json:"status,omitempty" validate:"omitempty,oneof=active inactive suspended"` Metadata map[string]string `json:"metadata,omitempty"` } // CreateTenantRoleRequest represents a request to create a role in a tenant type CreateTenantRoleRequest struct { TenantID uuid.UUID `json:"tenant_id" validate:"required"` Name string `json:"name" validate:"required,min=1,max=100"` Description string `json:"description,omitempty" validate:"max=500"` Permissions []string `json:"permissions,omitempty"` } // UpdateTenantRoleRequest represents a request to update a tenant role type UpdateTenantRoleRequest struct { Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=100"` Description *string `json:"description,omitempty" validate:"omitempty,max=500"` Permissions []string `json:"permissions,omitempty"` } // TenantListRequest represents a request to list tenants type TenantListRequest struct { Status *TenantStatus `json:"status,omitempty"` Domain string `json:"domain,omitempty"` Limit int `json:"limit" validate:"min=1,max=100"` Offset int `json:"offset" validate:"min=0"` } // TenantListResponse represents a response for listing tenants type TenantListResponse struct { Tenants []*Tenant `json:"tenants"` Total int `json:"total"` Limit int `json:"limit"` Offset int `json:"offset"` } // IsActive checks if the tenant is active func (t *Tenant) IsActive() bool { return t.Status == TenantStatusActive } // IsSuspended checks if the tenant is suspended func (t *Tenant) IsSuspended() bool { return t.Status == TenantStatusSuspended } // HasFeature checks if a feature is enabled for the tenant func (t *Tenant) HasFeature(feature string) bool { if t.Settings.Features == nil { return false } enabled, exists := t.Settings.Features[feature] return exists && enabled } // GetAuthProvider returns the authentication provider for the tenant func (t *Tenant) GetAuthProvider() string { if t.Settings.AuthProvider != "" { return t.Settings.AuthProvider } return "header" // default } // GetSessionTimeout returns the session timeout for the tenant func (t *Tenant) GetSessionTimeout() time.Duration { if t.Settings.SessionTimeout.Duration > 0 { return t.Settings.SessionTimeout.Duration } return 8 * time.Hour // default } // GetMaxConcurrentSessions returns the maximum concurrent sessions for the tenant func (t *Tenant) GetMaxConcurrentSessions() int { if t.Settings.MaxConcurrentSessions > 0 { return t.Settings.MaxConcurrentSessions } return 10 // default } // IsActive checks if the tenant user is active func (tu *TenantUser) IsActive() bool { return tu.Status == UserStatusActive } // IsSuspended checks if the tenant user is suspended func (tu *TenantUser) IsSuspended() bool { return tu.Status == UserStatusSuspended } // HasRole checks if the user has a specific role func (tu *TenantUser) HasRole(role string) bool { for _, r := range tu.Roles { if r == role { return true } } return false } // HasPermission checks if the user has a specific permission func (tu *TenantUser) HasPermission(permission string) bool { for _, p := range tu.Permissions { if p == permission { return true } } return false } // UpdateLastLogin updates the last login timestamp func (tu *TenantUser) UpdateLastLogin() { now := time.Now() tu.LastLoginAt = &now tu.UpdatedAt = now } // IsSystemRole checks if the role is a system role func (tr *TenantRole) IsSystemRole() bool { return tr.IsSystem } // HasPermission checks if the role has a specific permission func (tr *TenantRole) HasPermission(permission string) bool { for _, p := range tr.Permissions { if p == permission { return true } } return false } // TenantContext represents the tenant context for a request type TenantContext struct { TenantID uuid.UUID `json:"tenant_id"` TenantSlug string `json:"tenant_slug"` UserID string `json:"user_id"` Roles []string `json:"roles"` Permissions []string `json:"permissions"` } // MultiTenantAuthContext extends AuthContext with tenant information type MultiTenantAuthContext struct { *AuthContext TenantContext *TenantContext `json:"tenant_context,omitempty"` }