// Package admin gère la configuration et les permissions de l'interface d'administration. package admin import ( "fmt" "os" "strings" "gopkg.in/yaml.v3" ) // AdminConfig représente la configuration complète de l'admin. type AdminConfig struct { Session SessionConfig `yaml:"session"` RateLimit RateLimitConfig `yaml:"rate_limit"` Users []AdminUser `yaml:"users"` } // SessionConfig configure les sessions. type SessionConfig struct { SecretFile string `yaml:"secret_file"` MaxAge int `yaml:"max_age"` // secondes CookieName string `yaml:"cookie_name"` Secret string `yaml:"-"` // chargé depuis fichier } // RateLimitConfig configure le rate limiting. type RateLimitConfig struct { LoginMax int `yaml:"login_max"` LoginWindow int `yaml:"login_window"` // secondes } // AdminUser représente un utilisateur admin. type AdminUser struct { Username string `yaml:"username"` PasswordHash string `yaml:"password_hash"` Role string `yaml:"role"` Email string `yaml:"email"` Apps []string `yaml:"apps,omitempty"` // pour app_admin Permissions []string `yaml:"permissions,omitempty"` // pour app_admin } // IsSuperAdmin retourne true si l'utilisateur est super_admin. func (u *AdminUser) IsSuperAdmin() bool { return u.Role == "super_admin" } // LoadAdminConfig charge la configuration admin depuis un fichier YAML. func LoadAdminConfig(path string) (*AdminConfig, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("read admin config: %w", err) } var cfg AdminConfig if err := yaml.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("parse admin config: %w", err) } // Valeurs par défaut if cfg.Session.MaxAge == 0 { cfg.Session.MaxAge = 3600 // 1 heure } if cfg.Session.CookieName == "" { cfg.Session.CookieName = "sogoms_admin_sid" } if cfg.RateLimit.LoginMax == 0 { cfg.RateLimit.LoginMax = 5 } if cfg.RateLimit.LoginWindow == 0 { cfg.RateLimit.LoginWindow = 60 } // Charger le secret de session depuis le fichier if cfg.Session.SecretFile != "" { secretData, err := os.ReadFile(cfg.Session.SecretFile) if err != nil { return nil, fmt.Errorf("read session secret: %w", err) } cfg.Session.Secret = strings.TrimSpace(string(secretData)) } // Valider if len(cfg.Users) == 0 { return nil, fmt.Errorf("no users defined") } if cfg.Session.Secret == "" { return nil, fmt.Errorf("session secret is required") } return &cfg, nil } // GetUser retourne un utilisateur par son username. func (cfg *AdminConfig) GetUser(username string) *AdminUser { for i := range cfg.Users { if cfg.Users[i].Username == username { return &cfg.Users[i] } } return nil } // GetUserByEmail retourne un utilisateur par son email. func (cfg *AdminConfig) GetUserByEmail(email string) *AdminUser { for i := range cfg.Users { if cfg.Users[i].Email == email { return &cfg.Users[i] } } return nil }