121 lines
3.8 KiB
Go
121 lines
3.8 KiB
Go
package repository
|
|
|
|
// Reference: M13 §4.5 — Account OIDC settings repository
|
|
// Per-account OIDC configuration CRUD, following AccountSamlSettingsRepo pattern.
|
|
// Enables enterprise administrators to configure OIDC/OAuth SSO for their accounts
|
|
// with full multi-tenant isolation.
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
)
|
|
|
|
// AccountOIDCSettingsRepo manages per-account OIDC SSO settings in the database.
|
|
type AccountOIDCSettingsRepo struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewAccountOIDCSettingsRepo creates a new AccountOIDCSettings repository.
|
|
func NewAccountOIDCSettingsRepo(db *gorm.DB) *AccountOIDCSettingsRepo {
|
|
return &AccountOIDCSettingsRepo{db: db}
|
|
}
|
|
|
|
// GetByAccount retrieves the OIDC settings for an account.
|
|
// Returns nil if no settings exist for the account.
|
|
func (r *AccountOIDCSettingsRepo) GetByAccount(accountID uint) (*model.AccountOIDCSettings, error) {
|
|
var settings model.AccountOIDCSettings
|
|
err := r.db.Where("account_id = ?", accountID).First(&settings).Error
|
|
if err == gorm.ErrRecordNotFound {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &settings, nil
|
|
}
|
|
|
|
// GetActiveByAccount retrieves the active OIDC settings for an account.
|
|
// Returns nil if no active settings exist.
|
|
func (r *AccountOIDCSettingsRepo) GetActiveByAccount(accountID uint) (*model.AccountOIDCSettings, error) {
|
|
var settings model.AccountOIDCSettings
|
|
err := r.db.Where("account_id = ? AND active = ?", accountID, true).First(&settings).Error
|
|
if err == gorm.ErrRecordNotFound {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &settings, nil
|
|
}
|
|
|
|
// Create creates new OIDC settings for an account.
|
|
// Returns an error if settings already exist for the account (unique constraint).
|
|
func (r *AccountOIDCSettingsRepo) Create(settings *model.AccountOIDCSettings) error {
|
|
return r.db.Create(settings).Error
|
|
}
|
|
|
|
// Update updates existing OIDC settings for an account.
|
|
func (r *AccountOIDCSettingsRepo) Update(settings *model.AccountOIDCSettings) error {
|
|
return r.db.Save(settings).Error
|
|
}
|
|
|
|
// UpdateFields updates specific fields of the OIDC settings.
|
|
// Only non-zero fields in the updates map will be changed.
|
|
func (r *AccountOIDCSettingsRepo) UpdateFields(accountID uint, updates map[string]interface{}) error {
|
|
// Handle RoleMappings separately — it needs JSON serialization
|
|
if roleMappings, ok := updates["role_mappings"]; ok {
|
|
switch v := roleMappings.(type) {
|
|
case json.RawMessage:
|
|
updates["role_mappings"] = v
|
|
case string:
|
|
updates["role_mappings"] = json.RawMessage(v)
|
|
case map[string]interface{}:
|
|
data, err := json.Marshal(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
updates["role_mappings"] = json.RawMessage(data)
|
|
}
|
|
}
|
|
|
|
// Handle Scopes separately — stored as JSON array in DB
|
|
if scopes, ok := updates["scopes"]; ok {
|
|
switch v := scopes.(type) {
|
|
case json.RawMessage:
|
|
updates["scopes"] = v
|
|
case string:
|
|
updates["scopes"] = json.RawMessage(v)
|
|
case []string:
|
|
data, err := json.Marshal(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
updates["scopes"] = json.RawMessage(data)
|
|
case map[string]interface{}:
|
|
data, err := json.Marshal(v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
updates["scopes"] = json.RawMessage(data)
|
|
}
|
|
}
|
|
|
|
return r.db.Model(&model.AccountOIDCSettings{}).
|
|
Where("account_id = ?", accountID).
|
|
Updates(updates).Error
|
|
}
|
|
|
|
// Delete removes OIDC settings for an account (soft delete via DeletedAt).
|
|
func (r *AccountOIDCSettingsRepo) Delete(accountID uint) error {
|
|
return r.db.Where("account_id = ?", accountID).Delete(&model.AccountOIDCSettings{}).Error
|
|
}
|
|
|
|
// SetActive toggles the active status of OIDC settings for an account.
|
|
func (r *AccountOIDCSettingsRepo) SetActive(accountID uint, active bool) error {
|
|
return r.db.Model(&model.AccountOIDCSettings{}).
|
|
Where("account_id = ?", accountID).
|
|
Update("active", active).Error
|
|
} |