mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 15:43:49 +01:00
refactor(usercheck): use credentials from config.json by default.
This commit is contained in:
@@ -14,6 +14,8 @@ go build -o usercheck
|
||||
./usercheck <command> [options]
|
||||
```
|
||||
|
||||
By default, the tool reads database credentials from `config.json` in the project root.
|
||||
|
||||
### Commands
|
||||
|
||||
| Command | Description |
|
||||
@@ -27,28 +29,42 @@ go build -o usercheck
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
# List connected users
|
||||
./usercheck list -password "dbpass"
|
||||
# List connected users (uses config.json)
|
||||
./usercheck list
|
||||
|
||||
# Verbose output with last login times
|
||||
./usercheck list -v -password "dbpass"
|
||||
./usercheck list -v
|
||||
|
||||
# Search for a player
|
||||
./usercheck search -name "Hunter" -password "dbpass"
|
||||
./usercheck search -name "Hunter"
|
||||
|
||||
# Show server status
|
||||
./usercheck servers -password "dbpass"
|
||||
./usercheck servers
|
||||
|
||||
# Player login history
|
||||
./usercheck history -name "Hunter" -password "dbpass"
|
||||
./usercheck history -name "Hunter"
|
||||
|
||||
# Use a specific config file
|
||||
./usercheck list -config /path/to/config.json
|
||||
|
||||
# Override database password
|
||||
./usercheck list -password "different_password"
|
||||
```
|
||||
|
||||
### Database Options
|
||||
### Configuration Priority
|
||||
|
||||
| Flag | Env Variable | Default |
|
||||
|------|--------------|---------|
|
||||
| `-host` | `ERUPE_DB_HOST` | localhost |
|
||||
| `-port` | - | 5432 |
|
||||
| `-user` | `ERUPE_DB_USER` | postgres |
|
||||
| `-password` | `ERUPE_DB_PASSWORD` | (required) |
|
||||
| `-dbname` | `ERUPE_DB_NAME` | erupe |
|
||||
1. CLI flags (highest priority)
|
||||
2. Environment variables (`ERUPE_DB_*`)
|
||||
3. `config.json` file
|
||||
4. Default values (lowest priority)
|
||||
|
||||
### Database Flags
|
||||
|
||||
| Flag | Env Variable | Description |
|
||||
|------|--------------|-------------|
|
||||
| `-config` | - | Path to config.json |
|
||||
| `-host` | `ERUPE_DB_HOST` | Database host |
|
||||
| `-port` | - | Database port |
|
||||
| `-user` | `ERUPE_DB_USER` | Database user |
|
||||
| `-password` | `ERUPE_DB_PASSWORD` | Database password |
|
||||
| `-dbname` | `ERUPE_DB_NAME` | Database name |
|
||||
|
||||
@@ -2,43 +2,169 @@ package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
// DBConfig holds database connection configuration.
|
||||
type DBConfig struct {
|
||||
Host string
|
||||
Port int
|
||||
User string
|
||||
Password string
|
||||
DBName string
|
||||
Host string
|
||||
Port int
|
||||
User string
|
||||
Password string
|
||||
DBName string
|
||||
ConfigPath string
|
||||
}
|
||||
|
||||
// ErupeConfig represents the relevant parts of config.json.
|
||||
type ErupeConfig struct {
|
||||
Database struct {
|
||||
Host string `json:"Host"`
|
||||
Port int `json:"Port"`
|
||||
User string `json:"User"`
|
||||
Password string `json:"Password"`
|
||||
Database string `json:"Database"`
|
||||
} `json:"Database"`
|
||||
}
|
||||
|
||||
// loadConfigFile loads database settings from config.json.
|
||||
func loadConfigFile(path string) (*ErupeConfig, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cfg ErupeConfig
|
||||
if err := json.Unmarshal(data, &cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
// findConfigFile searches for config.json in common locations.
|
||||
func findConfigFile() string {
|
||||
// Check paths relative to current directory and up to project root
|
||||
paths := []string{
|
||||
"config.json",
|
||||
"../../config.json", // From tools/usercheck/
|
||||
"../../../config.json",
|
||||
}
|
||||
|
||||
// Also check if we can find it via executable path
|
||||
if exe, err := os.Executable(); err == nil {
|
||||
dir := filepath.Dir(exe)
|
||||
paths = append(paths,
|
||||
filepath.Join(dir, "config.json"),
|
||||
filepath.Join(dir, "../../config.json"),
|
||||
)
|
||||
}
|
||||
|
||||
for _, p := range paths {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// addDBFlags adds common database flags to a FlagSet.
|
||||
func addDBFlags(fs *flag.FlagSet, cfg *DBConfig) {
|
||||
fs.StringVar(&cfg.Host, "host", getEnvOrDefault("ERUPE_DB_HOST", "localhost"), "Database host")
|
||||
fs.IntVar(&cfg.Port, "port", 5432, "Database port")
|
||||
fs.StringVar(&cfg.User, "user", getEnvOrDefault("ERUPE_DB_USER", "postgres"), "Database user")
|
||||
fs.StringVar(&cfg.Password, "password", os.Getenv("ERUPE_DB_PASSWORD"), "Database password")
|
||||
fs.StringVar(&cfg.DBName, "dbname", getEnvOrDefault("ERUPE_DB_NAME", "erupe"), "Database name")
|
||||
fs.StringVar(&cfg.ConfigPath, "config", "", "Path to config.json (auto-detected if not specified)")
|
||||
fs.StringVar(&cfg.Host, "host", "", "Database host (overrides config.json)")
|
||||
fs.IntVar(&cfg.Port, "port", 0, "Database port (overrides config.json)")
|
||||
fs.StringVar(&cfg.User, "user", "", "Database user (overrides config.json)")
|
||||
fs.StringVar(&cfg.Password, "password", "", "Database password (overrides config.json)")
|
||||
fs.StringVar(&cfg.DBName, "dbname", "", "Database name (overrides config.json)")
|
||||
}
|
||||
|
||||
// getEnvOrDefault returns the environment variable value or a default.
|
||||
func getEnvOrDefault(key, defaultValue string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return value
|
||||
// resolveDBConfig resolves the final database configuration.
|
||||
// Priority: CLI flags > environment variables > config.json > defaults
|
||||
func resolveDBConfig(cfg *DBConfig) error {
|
||||
// Try to load from config.json
|
||||
configPath := cfg.ConfigPath
|
||||
if configPath == "" {
|
||||
configPath = findConfigFile()
|
||||
}
|
||||
return defaultValue
|
||||
|
||||
var fileCfg *ErupeConfig
|
||||
if configPath != "" {
|
||||
var err error
|
||||
fileCfg, err = loadConfigFile(configPath)
|
||||
if err != nil {
|
||||
// Only error if user explicitly specified a config path
|
||||
if cfg.ConfigPath != "" {
|
||||
return fmt.Errorf("failed to load config file: %w", err)
|
||||
}
|
||||
// Otherwise just ignore and use defaults/flags
|
||||
}
|
||||
}
|
||||
|
||||
// Apply config.json values as base
|
||||
if fileCfg != nil {
|
||||
if cfg.Host == "" {
|
||||
cfg.Host = fileCfg.Database.Host
|
||||
}
|
||||
if cfg.Port == 0 {
|
||||
cfg.Port = fileCfg.Database.Port
|
||||
}
|
||||
if cfg.User == "" {
|
||||
cfg.User = fileCfg.Database.User
|
||||
}
|
||||
if cfg.Password == "" {
|
||||
cfg.Password = fileCfg.Database.Password
|
||||
}
|
||||
if cfg.DBName == "" {
|
||||
cfg.DBName = fileCfg.Database.Database
|
||||
}
|
||||
}
|
||||
|
||||
// Apply environment variables
|
||||
if cfg.Host == "" {
|
||||
cfg.Host = os.Getenv("ERUPE_DB_HOST")
|
||||
}
|
||||
if cfg.User == "" {
|
||||
cfg.User = os.Getenv("ERUPE_DB_USER")
|
||||
}
|
||||
if cfg.Password == "" {
|
||||
cfg.Password = os.Getenv("ERUPE_DB_PASSWORD")
|
||||
}
|
||||
if cfg.DBName == "" {
|
||||
cfg.DBName = os.Getenv("ERUPE_DB_NAME")
|
||||
}
|
||||
|
||||
// Apply defaults
|
||||
if cfg.Host == "" {
|
||||
cfg.Host = "localhost"
|
||||
}
|
||||
if cfg.Port == 0 {
|
||||
cfg.Port = 5432
|
||||
}
|
||||
if cfg.User == "" {
|
||||
cfg.User = "postgres"
|
||||
}
|
||||
if cfg.DBName == "" {
|
||||
cfg.DBName = "erupe"
|
||||
}
|
||||
|
||||
// Password is required
|
||||
if cfg.Password == "" {
|
||||
return fmt.Errorf("database password is required (set in config.json, use -password flag, or ERUPE_DB_PASSWORD env var)")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// connectDB establishes a connection to the PostgreSQL database.
|
||||
func connectDB(cfg *DBConfig) (*sql.DB, error) {
|
||||
if cfg.Password == "" {
|
||||
return nil, fmt.Errorf("database password is required (use -password flag or ERUPE_DB_PASSWORD env var)")
|
||||
if err := resolveDBConfig(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connStr := fmt.Sprintf(
|
||||
|
||||
@@ -31,12 +31,15 @@ func main() {
|
||||
fmt.Fprintf(os.Stderr, " search Search for a specific connected user by name\n")
|
||||
fmt.Fprintf(os.Stderr, " servers Show server/channel status and player counts\n")
|
||||
fmt.Fprintf(os.Stderr, " history Show recent login history for a player\n")
|
||||
fmt.Fprintf(os.Stderr, "\nDatabase connection options (apply to all commands):\n")
|
||||
fmt.Fprintf(os.Stderr, " -host Database host (default: localhost)\n")
|
||||
fmt.Fprintf(os.Stderr, " -port Database port (default: 5432)\n")
|
||||
fmt.Fprintf(os.Stderr, " -user Database user (default: postgres)\n")
|
||||
fmt.Fprintf(os.Stderr, " -password Database password (required)\n")
|
||||
fmt.Fprintf(os.Stderr, " -dbname Database name (default: erupe)\n")
|
||||
fmt.Fprintf(os.Stderr, "\nDatabase configuration:\n")
|
||||
fmt.Fprintf(os.Stderr, " By default, reads from config.json in the project root.\n")
|
||||
fmt.Fprintf(os.Stderr, " Use flags to override specific settings.\n\n")
|
||||
fmt.Fprintf(os.Stderr, " -config Path to config.json (auto-detected if not specified)\n")
|
||||
fmt.Fprintf(os.Stderr, " -host Database host (overrides config.json)\n")
|
||||
fmt.Fprintf(os.Stderr, " -port Database port (overrides config.json)\n")
|
||||
fmt.Fprintf(os.Stderr, " -user Database user (overrides config.json)\n")
|
||||
fmt.Fprintf(os.Stderr, " -password Database password (overrides config.json)\n")
|
||||
fmt.Fprintf(os.Stderr, " -dbname Database name (overrides config.json)\n")
|
||||
fmt.Fprintf(os.Stderr, "\nUse '%s <command> -h' for more information about a command.\n", os.Args[0])
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user