oups
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
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 <subcommand>" 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 <id> [--password <pass>] [--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 <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 <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 <id> --password <pass>")
|
||||
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 <subcommand> [flags]
|
||||
|
||||
Subcommands:
|
||||
add --discord-id <id> --password <pass> [--superadmin]
|
||||
remove --discord-id <id>
|
||||
list
|
||||
reset-totp --discord-id <id>
|
||||
reset-password --discord-id <id> --password <pass>`)
|
||||
}
|
||||
|
||||
func newAdminRepo(sqldb *sql.DB) *db.PanelAdminRepo {
|
||||
return db.NewPanelAdminRepo(sqldb)
|
||||
}
|
||||
Reference in New Issue
Block a user