1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- package models
- import (
- "encoding/json"
- "time"
- "gorm.io/gorm"
- "golang.org/x/crypto/bcrypt"
- )
- // User represents a user in the system
- type User struct {
- ID int64 `gorm:"column:rowid;primaryKey;autoIncrement" json:"id"` // Unique identifier
- Username string `json:"username" gorm:"uniqueIndex;not null"` // Username
- Email string `json:"email" gorm:"uniqueIndex;not null"` // User's email address
- Password string `json:"password,omitempty" gorm:"not null"` // Password (hashed)
- Role string `json:"role" gorm:"default:'user'"` // User role
- PreferencesJSON string `json:"-" gorm:"column:preferences;type:text"` // User preferences stored as JSON string
- Preferences UserPreferences `json:"preferences" gorm:"-"` // User preferences (transient field)
- CreatedAt time.Time `json:"createdAt" gorm:"autoCreateTime"` // Creation timestamp
- UpdatedAt time.Time `json:"updatedAt" gorm:"autoUpdateTime"` // Last update timestamp
- DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` // Soft delete support
- }
- // UserPreferences represents user-specific settings
- type UserPreferences struct {
- Theme string `json:"theme"` // User's theme preference
- Notifications bool `json:"notifications"` // Notification preference
- DashboardLayout interface{} `json:"dashboardLayout,omitempty"` // Optional dashboard layout
- }
- // BeforeSave hook runs before saving a User - handles password hashing and preferences serialization
- func (u *User) BeforeSave(tx *gorm.DB) error {
- // Only hash password if it's provided and not already hashed
- if u.Password != "" && len(u.Password) < 60 { // bcrypt hashes are typically 60 characters
- hashedPassword, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
- if err != nil {
- return err
- }
- u.Password = string(hashedPassword)
- }
- // Serialize preferences to JSON
- preferencesData, err := json.Marshal(u.Preferences)
- if err != nil {
- return err
- }
- u.PreferencesJSON = string(preferencesData)
- return nil
- }
- // AfterFind hook deserializes JSON preferences after fetching from database
- func (u *User) AfterFind(tx *gorm.DB) error {
- if u.PreferencesJSON != "" {
- return json.Unmarshal([]byte(u.PreferencesJSON), &u.Preferences)
- }
- return nil
- }
- // CheckPassword verifies if the provided password matches the hashed one
- func (u *User) CheckPassword(password string) bool {
- err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
- return err == nil
- }
- type UserRole string
- const (
- Admin UserRole = "admin"
- Developer UserRole = "developer"
- Viewer UserRole = "viewer"
- )
|