✨ 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>
This commit is contained in:
69
pkg/user/user.go
Normal file
69
pkg/user/user.go
Normal file
@@ -0,0 +1,69 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user