diff --git a/src/admintools/admintools.go b/src/admintools/admintools.go new file mode 100644 index 0000000..8c6617d --- /dev/null +++ b/src/admintools/admintools.go @@ -0,0 +1,62 @@ +package admintools + +import ( + "context" + "errors" + "fmt" + "os" + + "git.handmade.network/hmn/hmn/src/auth" + "git.handmade.network/hmn/hmn/src/db" + "git.handmade.network/hmn/hmn/src/website" + "github.com/jackc/pgx/v4" + "github.com/spf13/cobra" +) + +func init() { + setPasswordCommand := &cobra.Command{ + Use: "setpassword [username] [new password]", + Short: "Replace a user's password", + Run: func(cmd *cobra.Command, args []string) { + if len(args) < 2 { + fmt.Printf("You must provide a username and a password.\n\n") + cmd.Usage() + os.Exit(1) + } + + username := args[0] + password := args[1] + + ctx := context.Background() + conn := db.NewConnPool(1, 1) + defer conn.Close() + + row := conn.QueryRow(ctx, "SELECT id, username FROM auth_user WHERE lower(username) = lower($1)", username) + var id int + var canonicalUsername string + err := row.Scan(&id, &canonicalUsername) + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + fmt.Printf("User '%s' not found\n", username) + os.Exit(1) + } else { + panic(err) + } + } + + hashedPassword, err := auth.HashPassword(password) + if err != nil { + panic(err) + } + + err = auth.UpdatePassword(ctx, conn, canonicalUsername, hashedPassword) + if err != nil { + panic(err) + } + + fmt.Printf("Successfully updated password for '%s'\n", canonicalUsername) + }, + } + + website.WebsiteCommand.AddCommand(setPasswordCommand) +} diff --git a/src/main.go b/src/main.go index d31f375..e3ccc3b 100644 --- a/src/main.go +++ b/src/main.go @@ -1,6 +1,7 @@ package main import ( + _ "git.handmade.network/hmn/hmn/src/admintools" _ "git.handmade.network/hmn/hmn/src/buildscss" _ "git.handmade.network/hmn/hmn/src/migration" "git.handmade.network/hmn/hmn/src/website"