package db import ( "database/sql" "encoding/json" "time" ) // ProviderType represents the type of authentication provider type ProviderType string const ( // ProviderTypeAuthentik represents an Authentik authentication provider ProviderTypeAuthentik ProviderType = "authentik" // ProviderTypeOIDC represents an OpenID Connect authentication provider ProviderTypeOIDC ProviderType = "oidc" // ProviderTypeSAML represents a SAML authentication provider ProviderTypeSAML ProviderType = "saml" // ProviderTypeOAuth2 represents an OAuth2 authentication provider ProviderTypeOAuth2 ProviderType = "oauth2" ) // AuthProvider represents an external authentication provider configuration type AuthProvider struct { ID uint `gorm:"primarykey" json:"id"` Name string `gorm:"not null" json:"name"` Type ProviderType `gorm:"not null" json:"type"` Enabled *bool `gorm:"default:true" json:"enabled"` Description string `json:"description"` ProviderURL string `json:"provider_url"` ClientID string `json:"client_id"` ClientSecret string `json:"-"` // Not returned in JSON responses RedirectURL string `json:"redirect_url"` Scopes string `json:"scopes"` AttributeMapping string `json:"attribute_mapping"` Config string `json:"-"` // Stores provider-specific configuration IconURL string `json:"icon_url"` // URL to provider icon SuccessfulLogins int `json:"successful_logins"` LastUsed sql.NullTime `json:"last_used"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` // Unmarshalled config configData map[string]interface{} `gorm:"-" json:"-"` } // GetConfig returns the unmarshalled configuration data func (p *AuthProvider) GetConfig() (map[string]interface{}, error) { if p.configData == nil && p.Config != "" { err := json.Unmarshal([]byte(p.Config), &p.configData) if err != nil { return nil, err } } if p.configData == nil { p.configData = make(map[string]interface{}) } return p.configData, nil } // SetConfig sets the configuration data and marshals it to JSON func (p *AuthProvider) SetConfig(data map[string]interface{}) error { jsonData, err := json.Marshal(data) if err != nil { return err } p.Config = string(jsonData) p.configData = data return nil } // --- AuthProvider Helper Methods --- // GetEnabled returns the value of Enabled with a default if nil func (p *AuthProvider) GetEnabled() bool { if p.Enabled == nil { return true // Default to true if not set } return *p.Enabled } // SetEnabled sets the Enabled field func (p *AuthProvider) SetEnabled(value bool) { p.Enabled = &value } // ExternalUserIdentity represents a user identity from an external authentication provider type ExternalUserIdentity struct { ID uint `gorm:"primarykey" json:"id"` UserID uint `gorm:"not null" json:"user_id"` ProviderID uint `gorm:"not null" json:"provider_id"` ProviderType ProviderType `gorm:"not null" json:"provider_type"` ExternalID string `gorm:"not null" json:"external_id"` Email string `gorm:"not null" json:"email"` Username string `json:"username"` DisplayName string `json:"display_name"` Groups string `json:"groups"` // JSON array of groups LastLogin sql.NullTime `json:"last_login"` ProviderData string `json:"-"` // Raw data from provider CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` // Foreign key relationships User User `gorm:"foreignKey:UserID" json:"-"` Provider AuthProvider `gorm:"foreignKey:ProviderID" json:"-"` // Unmarshalled provider data providerDataObj map[string]interface{} `gorm:"-" json:"-"` } // GetProviderData returns the unmarshalled provider data func (e *ExternalUserIdentity) GetProviderData() (map[string]interface{}, error) { if e.providerDataObj == nil && e.ProviderData != "" { err := json.Unmarshal([]byte(e.ProviderData), &e.providerDataObj) if err != nil { return nil, err } } if e.providerDataObj == nil { e.providerDataObj = make(map[string]interface{}) } return e.providerDataObj, nil } // SetProviderData sets the provider data and marshals it to JSON func (e *ExternalUserIdentity) SetProviderData(data map[string]interface{}) error { jsonData, err := json.Marshal(data) if err != nil { return err } e.ProviderData = string(jsonData) e.providerDataObj = data return nil } // GetGroups returns the unmarshalled groups func (e *ExternalUserIdentity) GetGroups() ([]string, error) { var groups []string if e.Groups == "" { return groups, nil } err := json.Unmarshal([]byte(e.Groups), &groups) if err != nil { return nil, err } return groups, nil } // SetGroups sets the groups and marshals them to JSON func (e *ExternalUserIdentity) SetGroups(groups []string) error { jsonData, err := json.Marshal(groups) if err != nil { return err } e.Groups = string(jsonData) return nil }