308 lines
12 KiB
Go
308 lines
12 KiB
Go
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 time.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 time.Duration `json:"default_token_duration,omitempty"`
|
|
MaxTokenDuration time.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 time.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 > 0 {
|
|
return t.Settings.SessionTimeout
|
|
}
|
|
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"`
|
|
}
|