package models import ( "database/sql" "github.com/pkg/errors" "golang.org/x/crypto/bcrypt" ) type User struct { id int // Integer ID (index primary key) Username string // Username (unique) Created_at int64 // Epoch timestamp when the user was added to the database Bio string // Short byline set by the user } func (u User) ID() int { return u.id } // Uses bcrypt to set the users Password_hash from the given password func (user *User) SetPassword( tx *sql.Tx, password string, ) error { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return errors.Wrap(err, "bcrypt.GenerateFromPassword") } newPassword := string(hashedPassword) query := `UPDATE users SET password_hash = ? WHERE id = ?` _, err = tx.Exec(query, newPassword, user.id) if err != nil { return errors.Wrap(err, "tx.Exec") } return nil } // Uses bcrypt to check if the given password matches the users Password_hash func (user *User) CheckPassword(tx *sql.Tx, password string) error { query := `SELECT password_hash FROM users WHERE id = ? LIMIT 1` row := tx.QueryRow(query, user.id) var hashedPassword string err := row.Scan(&hashedPassword) if err != nil { return errors.Wrap(err, "row.Scan") } err = bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password)) if err != nil { return errors.Wrap(err, "Username or password incorrect") } return nil } // Change the user's username func (user *User) ChangeUsername(tx *sql.Tx, newUsername string) error { query := `UPDATE users SET username = ? WHERE id = ?` _, err := tx.Exec(query, newUsername, user.id) if err != nil { return errors.Wrap(err, "tx.Exec") } return nil } // Change the user's bio func (user *User) ChangeBio(tx *sql.Tx, newBio string) error { query := `UPDATE users SET bio = ? WHERE id = ?` _, err := tx.Exec(query, newBio, user.id) if err != nil { return errors.Wrap(err, "tx.Exec") } return nil }