package config import ( "encoding/json" "os" "sync" ) // Config represents the application configuration type Config struct { mu sync.RWMutex `json:"-"` FTP FTPConfig `json:"ftp"` Web WebConfig `json:"web"` HTTPFile HTTPFileConfig `json:"httpFile"` Admin AdminConfig `json:"admin"` FTPUsers []FTPUser `json:"ftpUsers"` } // FTPConfig holds FTP server settings type FTPConfig struct { Host string `json:"host"` Port int `json:"port"` PassiveMin int `json:"passivePortMin"` PassiveMax int `json:"passivePortMax"` RootDir string `json:"rootDir"` } // WebConfig holds web admin panel settings type WebConfig struct { Host string `json:"host"` Port int `json:"port"` } // HTTPFileConfig holds HTTP file server settings type HTTPFileConfig struct { Enable bool `json:"enable"` Host string `json:"host"` Port int `json:"port"` RootDir string `json:"rootDir"` Upload bool `json:"upload"` } // AdminConfig holds admin credentials type AdminConfig struct { Username string `json:"username"` Password string `json:"password"` } // FTPUser represents an FTP user account type FTPUser struct { Username string `json:"username"` Password string `json:"password"` HomeDir string `json:"homeDir"` Write bool `json:"write"` } // DefaultConfig returns a default configuration func DefaultConfig() *Config { return &Config{ FTP: FTPConfig{ Host: "0.0.0.0", Port: 2121, PassiveMin: 50000, PassiveMax: 50100, RootDir: "./ftp_root", }, Web: WebConfig{ Host: "0.0.0.0", Port: 8080, }, HTTPFile: HTTPFileConfig{ Enable: true, Host: "0.0.0.0", Port: 9090, RootDir: "./ftp_root", Upload: true, }, Admin: AdminConfig{ Username: "admin", Password: "admin123", }, FTPUsers: []FTPUser{ { Username: "ftpuser", Password: "ftp123", HomeDir: "./ftp_root", Write: true, }, }, } } // Load loads configuration from a file func Load(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { if os.IsNotExist(err) { cfg := DefaultConfig() if saveErr := cfg.Save(path); saveErr != nil { return nil, saveErr } return cfg, nil } return nil, err } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return nil, err } return &cfg, nil } // Save saves configuration to a file func (c *Config) Save(path string) error { c.mu.RLock() defer c.mu.RUnlock() data, err := json.MarshalIndent(c, "", " ") if err != nil { return err } return os.WriteFile(path, data, 0644) } // GetFTPUser finds an FTP user by username func (c *Config) GetFTPUser(username string) *FTPUser { c.mu.RLock() defer c.mu.RUnlock() for i := range c.FTPUsers { if c.FTPUsers[i].Username == username { return &c.FTPUsers[i] } } return nil } // AddFTPUser adds a new FTP user func (c *Config) AddFTPUser(user FTPUser) { c.mu.Lock() defer c.mu.Unlock() c.FTPUsers = append(c.FTPUsers, user) } // DeleteFTPUser removes an FTP user by username func (c *Config) DeleteFTPUser(username string) bool { c.mu.Lock() defer c.mu.Unlock() for i, u := range c.FTPUsers { if u.Username == username { c.FTPUsers = append(c.FTPUsers[:i], c.FTPUsers[i+1:]...) return true } } return false } // UpdateFTPUser updates an existing FTP user func (c *Config) UpdateFTPUser(username string, user FTPUser) bool { c.mu.Lock() defer c.mu.Unlock() for i, u := range c.FTPUsers { if u.Username == username { c.FTPUsers[i] = user return true } } return false } // AuthenticateAdmin checks admin credentials func (c *Config) AuthenticateAdmin(username, password string) bool { c.mu.RLock() defer c.mu.RUnlock() return c.Admin.Username == username && c.Admin.Password == password } // GetFTPUsers returns a copy of all FTP users func (c *Config) GetFTPUsers() []FTPUser { c.mu.RLock() defer c.mu.RUnlock() users := make([]FTPUser, len(c.FTPUsers)) copy(users, c.FTPUsers) return users }