73 lines
1.6 KiB
Go
73 lines
1.6 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type User struct {
|
|
ID int `json:"id"`
|
|
Username string `json:"username"`
|
|
PasswordHash string `json:"-"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
type CreateUserRequest struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
type LoginRequest struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
func CreateUser(ctx context.Context, req CreateUserRequest) (*User, error) {
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var user User
|
|
err = Pool.QueryRow(ctx,
|
|
"INSERT INTO users (username, password_hash) VALUES ($1, $2) RETURNING id, username, created_at",
|
|
req.Username, string(hashedPassword),
|
|
).Scan(&user.ID, &user.Username, &user.CreatedAt)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
func GetUserByUsername(ctx context.Context, username string) (*User, error) {
|
|
var user User
|
|
err := Pool.QueryRow(ctx,
|
|
"SELECT id, username, password_hash, created_at FROM users WHERE username = $1",
|
|
username,
|
|
).Scan(&user.ID, &user.Username, &user.PasswordHash, &user.CreatedAt)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
func ValidateUserCredentials(ctx context.Context, username, password string) (*User, error) {
|
|
user, err := GetUserByUsername(ctx, username)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(password))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|