diff --git a/cmd/sojuctl/main.go b/cmd/sojuctl/main.go index e2ba48a..841dc80 100644 --- a/cmd/sojuctl/main.go +++ b/cmd/sojuctl/main.go @@ -14,8 +14,9 @@ import ( const usage = `usage: sojuctl [-config path] [options...] - create-user Create a new user - help Show this help message + create-user Create a new user + change-password Change password for a user + help Show this help message ` func init() { @@ -72,6 +73,33 @@ func main() { if err := db.CreateUser(&user); err != nil { log.Fatalf("failed to create user: %v", err) } + case "change-password": + username := flag.Arg(1) + if username == "" { + flag.Usage() + os.Exit(1) + } + + fmt.Printf("New password: ") + password, err := terminal.ReadPassword(int(os.Stdin.Fd())) + if err != nil { + log.Fatalf("failed to read new password: %v", err) + } + fmt.Printf("\n") + + hashed, err := bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost) + if err != nil { + log.Fatalf("failed to hash password: %v", err) + } + + user := soju.User{ + Username: username, + Password: string(hashed), + } + if err := db.UpdatePassword(&user); err != nil { + log.Fatalf("failed to update password: %v", err) + } + default: flag.Usage() if cmd != "help" { diff --git a/db.go b/db.go index e5ab4ef..782358b 100644 --- a/db.go +++ b/db.go @@ -132,6 +132,18 @@ func (db *DB) CreateUser(user *User) error { return err } +func (db *DB) UpdatePassword(user *User) error { + db.lock.Lock() + defer db.lock.Unlock() + + password := toStringPtr(user.Password) + _, err := db.db.Exec(`UPDATE User + SET password = ? + WHERE username = ?`, + password, user.Username) + return err +} + func (db *DB) ListNetworks(username string) ([]Network, error) { db.lock.RLock() defer db.lock.RUnlock()