- Add JWT authentication middleware with token validation - Implement user context extraction methods for user ID, email, and admin status - Create admin middleware to restrict access to admin-only routes - Add convenience method to combine authentication and admin authorization - Update auth middleware to handle token parsing, validation, and context setting - Enhance error handling for various authentication scenarios - Add new JWT service and related dependencies in go.mod
113 lines
2.8 KiB
Go
113 lines
2.8 KiB
Go
package repositories
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"attune-heart-therapy/internal/models"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// userRepository implements the UserRepository interface
|
|
type userRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewUserRepository creates a new instance of UserRepository
|
|
func NewUserRepository(db *gorm.DB) UserRepository {
|
|
return &userRepository{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// Create creates a new user in the database
|
|
func (r *userRepository) Create(user *models.User) error {
|
|
if user == nil {
|
|
return errors.New("user cannot be nil")
|
|
}
|
|
|
|
if err := r.db.Create(user).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
|
return fmt.Errorf("user with email %s already exists", user.Email)
|
|
}
|
|
return fmt.Errorf("failed to create user: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetByID retrieves a user by their ID
|
|
func (r *userRepository) GetByID(id uint) (*models.User, error) {
|
|
if id == 0 {
|
|
return nil, errors.New("invalid user ID")
|
|
}
|
|
|
|
var user models.User
|
|
if err := r.db.First(&user, id).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, fmt.Errorf("user with ID %d not found", id)
|
|
}
|
|
return nil, fmt.Errorf("failed to get user by ID: %w", err)
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
// GetByEmail retrieves a user by their email address
|
|
func (r *userRepository) GetByEmail(email string) (*models.User, error) {
|
|
if email == "" {
|
|
return nil, errors.New("email cannot be empty")
|
|
}
|
|
|
|
var user models.User
|
|
if err := r.db.Where("email = ?", email).First(&user).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, fmt.Errorf("user with email %s not found", email)
|
|
}
|
|
return nil, fmt.Errorf("failed to get user by email: %w", err)
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
// Update updates an existing user in the database
|
|
func (r *userRepository) Update(user *models.User) error {
|
|
if user == nil {
|
|
return errors.New("user cannot be nil")
|
|
}
|
|
|
|
if user.ID == 0 {
|
|
return errors.New("user ID is required for update")
|
|
}
|
|
|
|
// Check if user exists
|
|
var existingUser models.User
|
|
if err := r.db.First(&existingUser, user.ID).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return fmt.Errorf("user with ID %d not found", user.ID)
|
|
}
|
|
return fmt.Errorf("failed to check user existence: %w", err)
|
|
}
|
|
|
|
// Update the user
|
|
if err := r.db.Save(user).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
|
return fmt.Errorf("user with email %s already exists", user.Email)
|
|
}
|
|
return fmt.Errorf("failed to update user: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetActiveUsersCount returns the count of active (non-deleted) users
|
|
func (r *userRepository) GetActiveUsersCount() (int64, error) {
|
|
var count int64
|
|
if err := r.db.Model(&models.User{}).Count(&count).Error; err != nil {
|
|
return 0, fmt.Errorf("failed to get active users count: %w", err)
|
|
}
|
|
|
|
return count, nil
|
|
}
|