package main import ( "context" "database/sql" "fmt" "os" "github.com/leolionad58/ticketbot/internal/db" panelauth "github.com/leolionad58/ticketbot/internal/panel/auth" ) // handleAdminCLI processes "ticketbot admin " and exits. // Returns true if an admin subcommand was handled. func handleAdminCLI(sqldb *sql.DB) bool { if len(os.Args) < 2 || os.Args[1] != "admin" { return false } repo := db.NewPanelAdminRepo(sqldb) ctx := context.Background() if len(os.Args) < 3 { printAdminUsage() os.Exit(1) } switch os.Args[2] { case "add": cliAddAdmin(ctx, repo) case "remove": cliRemoveAdmin(ctx, repo) case "list": cliListAdmins(ctx, repo) case "reset-totp": cliResetTOTP(ctx, repo) case "reset-password": cliResetPassword(ctx, repo) default: fmt.Fprintf(os.Stderr, "Unknown admin subcommand: %s\n", os.Args[2]) printAdminUsage() os.Exit(1) } return true } func cliAddAdmin(ctx context.Context, repo *db.PanelAdminRepo) { args := os.Args[3:] discordID := flagValue(args, "--discord-id") password := flagValue(args, "--password") superadmin := containsFlag(args, "--superadmin") if discordID == "" { fmt.Fprintln(os.Stderr, "Usage: admin add --discord-id [--password ] [--superadmin]") os.Exit(1) } var hash string if password != "" { var err error hash, err = panelauth.HashPassword(password) must(err, "hash password") } a, err := repo.Create(ctx, discordID, "", hash, superadmin) must(err, "create admin") fmt.Printf("Admin added: discord_id=%s id=%d superadmin=%v\n", a.DiscordID, a.ID, a.IsSuperadmin) } func cliRemoveAdmin(ctx context.Context, repo *db.PanelAdminRepo) { discordID := flagValue(os.Args[3:], "--discord-id") if discordID == "" { fmt.Fprintln(os.Stderr, "Usage: admin remove --discord-id ") os.Exit(1) } must(repo.Delete(ctx, discordID), "remove admin") fmt.Printf("Admin removed: %s\n", discordID) } func cliListAdmins(ctx context.Context, repo *db.PanelAdminRepo) { admins, err := repo.List(ctx) must(err, "list admins") if len(admins) == 0 { fmt.Println("No admins configured.") return } fmt.Printf("%-20s %-30s %-12s %-12s\n", "Discord ID", "Username", "Superadmin", "TOTP") for _, a := range admins { fmt.Printf("%-20s %-30s %-12v %-12v\n", a.DiscordID, a.DiscordUsername, a.IsSuperadmin, a.TOTPEnabled) } } func cliResetTOTP(ctx context.Context, repo *db.PanelAdminRepo) { discordID := flagValue(os.Args[3:], "--discord-id") if discordID == "" { fmt.Fprintln(os.Stderr, "Usage: admin reset-totp --discord-id ") os.Exit(1) } a, err := repo.GetByDiscordID(ctx, discordID) must(err, "get admin") if a == nil { fmt.Fprintf(os.Stderr, "Admin not found: %s\n", discordID) os.Exit(1) } must(repo.ResetTOTP(ctx, a.ID), "reset totp") fmt.Printf("TOTP reset for %s — admin must re-setup TOTP on next login.\n", discordID) } func cliResetPassword(ctx context.Context, repo *db.PanelAdminRepo) { args := os.Args[3:] discordID := flagValue(args, "--discord-id") password := flagValue(args, "--password") if discordID == "" || password == "" { fmt.Fprintln(os.Stderr, "Usage: admin reset-password --discord-id --password ") os.Exit(1) } a, err := repo.GetByDiscordID(ctx, discordID) must(err, "get admin") if a == nil { fmt.Fprintf(os.Stderr, "Admin not found: %s\n", discordID) os.Exit(1) } hash, err := panelauth.HashPassword(password) must(err, "hash password") must(repo.UpdatePassword(ctx, a.ID, hash), "update password") fmt.Printf("Password updated for %s\n", discordID) } func flagValue(args []string, flag string) string { for i := 0; i < len(args)-1; i++ { if args[i] == flag { return args[i+1] } } return "" } func containsFlag(args []string, flag string) bool { for _, a := range args { if a == flag { return true } } return false } func printAdminUsage() { fmt.Fprintln(os.Stderr, `Usage: ticketbot admin [flags] Subcommands: add --discord-id --password [--superadmin] remove --discord-id list reset-totp --discord-id reset-password --discord-id --password `) } func newAdminRepo(sqldb *sql.DB) *db.PanelAdminRepo { return db.NewPanelAdminRepo(sqldb) }