53 lines
1.7 KiB
Go
53 lines
1.7 KiB
Go
|
|
package models
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"golang.org/x/crypto/bcrypt"
|
||
|
|
"gorm.io/gorm"
|
||
|
|
)
|
||
|
|
|
||
|
|
// User represents a system user
|
||
|
|
type User struct {
|
||
|
|
gorm.Model
|
||
|
|
FirstName string `json:"first_name" gorm:"not null;size:100" validate:"required,min=2,max=100"`
|
||
|
|
LastName string `json:"last_name" gorm:"not null;size:100" validate:"required,min=2,max=100"`
|
||
|
|
Email string `json:"email" gorm:"unique;not null;size:255" validate:"required,email"`
|
||
|
|
Phone string `json:"phone" gorm:"size:20" validate:"omitempty,min=10,max=20"`
|
||
|
|
Location string `json:"location" gorm:"size:255" validate:"omitempty,max=255"`
|
||
|
|
DateOfBirth time.Time `json:"date_of_birth" validate:"omitempty"`
|
||
|
|
PasswordHash string `json:"-" gorm:"not null;size:255"`
|
||
|
|
IsAdmin bool `json:"is_admin" gorm:"default:false"`
|
||
|
|
Bookings []Booking `json:"bookings" gorm:"foreignKey:UserID"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// HashPassword hashes the user's password using bcrypt
|
||
|
|
func (u *User) HashPassword(password string) error {
|
||
|
|
if len(password) < 8 {
|
||
|
|
return errors.New("password must be at least 8 characters long")
|
||
|
|
}
|
||
|
|
|
||
|
|
hashedBytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
u.PasswordHash = string(hashedBytes)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// CheckPassword verifies if the provided password matches the user's hashed password
|
||
|
|
func (u *User) CheckPassword(password string) bool {
|
||
|
|
err := bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(password))
|
||
|
|
return err == nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// BeforeCreate is a GORM hook that runs before creating a user record
|
||
|
|
func (u *User) BeforeCreate(tx *gorm.DB) error {
|
||
|
|
// Ensure email is lowercase for consistency
|
||
|
|
u.Email = strings.ToLower(u.Email)
|
||
|
|
return nil
|
||
|
|
}
|