99 lines
2.5 KiB
Go
99 lines
2.5 KiB
Go
package userstore
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.keks.cloud/kekskurse/miniauth/pkg/utils"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type User struct {
|
|
Username string
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
func (s Store) UserWrite(username, password string) (int64, error) {
|
|
query := "INSERT INTO users (username, password) VALUES (?, ?);"
|
|
log := s.log.With().Str("func", "UserWrite").Str("query", query).Str("username", username).Logger()
|
|
|
|
pwHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return 0, utils.WrapError(ErrCantEncryptPassword, err, log)
|
|
}
|
|
|
|
res, err := s.db.Exec(query, username, string(pwHash))
|
|
if err != nil {
|
|
return 0, utils.WrapError(ErrCantExecuteQuery, err, log)
|
|
}
|
|
|
|
id, err := res.LastInsertId()
|
|
if err != nil {
|
|
return 0, utils.WrapError(ErrCantExecuteQuery, err, log)
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
func (s Store) UserCheckPassword(username, password string) (User, error) {
|
|
query := fmt.Sprintf("SELECT %v FROM users WHERE username = ?", s.userGetFields())
|
|
log := s.log.With().Str("func", "UserLogin").Str("username", username).Str("query", query).Logger()
|
|
|
|
var pwHash string
|
|
row := s.db.QueryRow(query, username)
|
|
user, pwHash, err := s.userScan(row)
|
|
if err != nil {
|
|
return User{}, utils.WrapError(ErrCantExecuteQuery, err, log)
|
|
}
|
|
|
|
err = bcrypt.CompareHashAndPassword([]byte(pwHash), []byte(password))
|
|
if err != nil {
|
|
return User{}, utils.WrapError(ErrPasswordDontMatch, err, log)
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
func (s Store) userGetFields() string {
|
|
return "username, password, created_at, updated_at"
|
|
}
|
|
|
|
func (s Store) userScan(row *sql.Row) (User, string, error) {
|
|
u := User{}
|
|
var pwHash string
|
|
err := row.Scan(&u.Username, &pwHash, &u.CreatedAt, &u.UpdatedAt)
|
|
if err != nil {
|
|
return User{}, "", err
|
|
}
|
|
return u, pwHash, nil
|
|
}
|
|
|
|
func (s Store) UserExists(username string) (bool, error) {
|
|
query := "SELECT COUNT(*) FROM users WHERE username = ?"
|
|
log := s.log.With().Str("func", "UserExists").Str("query", query).Str("username", username).Logger()
|
|
|
|
var count int
|
|
err := s.db.QueryRow(query, username).Scan(&count)
|
|
if err != nil {
|
|
return true, utils.WrapError(ErrCantExecuteQuery, err, log)
|
|
}
|
|
|
|
if count == 0 {
|
|
return false, nil
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
func (s Store) UserDelete(username string) error {
|
|
query := "DELETE FROM users WHERE username = ?"
|
|
log := s.log.With().Str("func", "UserExists").Str("query", query).Str("username", username).Logger()
|
|
|
|
_, err := s.db.Exec(query, username)
|
|
if err != nil {
|
|
return utils.WrapError(ErrCantExecuteQuery, err, log)
|
|
}
|
|
|
|
return nil
|
|
}
|