Files
dance-lessons-coach/pkg/user/user.go
Gabriel Radureau 52a4ce4139 feat: implement user authentication system with JWT and PostgreSQL
Added comprehensive user management system:
- User registration with validation (3-50 char username, 6+ char password)
- JWT-based authentication with bcrypt password hashing
- Admin authentication with master password
- Password reset workflow with admin flagging
- PostgreSQL repository implementation
- SQLite repository for testing
- Unified authentication service interface

API Endpoints:
- POST /api/v1/auth/register - User registration
- POST /api/v1/auth/login - User/admin authentication
- POST /api/v1/auth/password-reset/request - Request password reset
- POST /api/v1/auth/password-reset/complete - Complete password reset
- POST /api/v1/auth/validate - JWT token validation

Security Features:
- Password hashing with bcrypt
- JWT token generation and validation
- Admin claims in JWT tokens
- Configurable token expiration
- Input validation for all endpoints

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-04-09 00:25:43 +02:00

70 lines
2.8 KiB
Go

package user
import (
"context"
"time"
)
// User represents a user in the system
type User struct {
ID uint `json:"id" gorm:"primaryKey"`
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
DeletedAt *time.Time `json:"deleted_at,omitempty" gorm:"index"`
Username string `json:"username" gorm:"unique;not null" validate:"required,min=3,max=50"`
PasswordHash string `json:"-" gorm:"not null"`
Description *string `json:"description,omitempty"`
CurrentGoal *string `json:"current_goal,omitempty"`
IsAdmin bool `json:"is_admin" gorm:"default:false"`
AllowPasswordReset bool `json:"allow_password_reset" gorm:"default:false"`
LastLogin *time.Time `json:"last_login,omitempty"`
}
// UserRepository defines the interface for user persistence
type UserRepository interface {
CreateUser(ctx context.Context, user *User) error
GetUserByUsername(ctx context.Context, username string) (*User, error)
GetUserByID(ctx context.Context, id uint) (*User, error)
UpdateUser(ctx context.Context, user *User) error
DeleteUser(ctx context.Context, id uint) error
AllowPasswordReset(ctx context.Context, username string) error
CompletePasswordReset(ctx context.Context, username, newPassword string) error
UserExists(ctx context.Context, username string) (bool, error)
CheckDatabaseHealth(ctx context.Context) error
}
// AuthService defines interface for authentication operations
type AuthService interface {
Authenticate(ctx context.Context, username, password string) (*User, error)
GenerateJWT(ctx context.Context, user *User) (string, error)
ValidateJWT(ctx context.Context, token string) (*User, error)
AdminAuthenticate(ctx context.Context, masterPassword string) (*User, error)
}
// UserManager defines interface for user management operations
type UserManager interface {
UserExists(ctx context.Context, username string) (bool, error)
CreateUser(ctx context.Context, user *User) error
}
// PasswordService defines interface for password operations
type PasswordService interface {
HashPassword(ctx context.Context, password string) (string, error)
RequestPasswordReset(ctx context.Context, username string) error
CompletePasswordReset(ctx context.Context, username, newPassword string) error
}
// UserService composes all user-related interfaces using Go's interface composition
// This is cleaner than aggregation and better for testing
type UserService interface {
AuthService
UserManager
PasswordService
}
// PasswordResetService defines the interface for password reset workflow
type PasswordResetService interface {
RequestPasswordReset(ctx context.Context, username string) error
CompletePasswordReset(ctx context.Context, username, newPassword string) error
}