# 18. User Management and Authentication System

**Date:** 2024-04-06
**Status:** Proposed
**Authors:** Product Owner
**Decision Drivers:** Security, User Personalization, Admin Functionality

## Context

The DanceLessonsCoach application currently lacks user management and authentication capabilities. To provide personalized experiences and administrative functions, we need to implement a secure user authentication system with PostgreSQL persistence.

## Decision

We will implement a user management and authentication system with the following characteristics:

### Core Features

1. **User Model**
   - Username-based identification (no email/personal info)
   - Password authentication with secure hashing
   - User profile fields: description and current goal
   - Admin flag for privileged users

2. **Authentication System**
   - JWT-based authentication
   - Secure password hashing (bcrypt)
   - Session management
   - Admin master password for non-persisted admin access

3. **Password Reset Workflow**
   - Admin-assisted password reset (no email/phone required)
   - Allow password reset flag for users
   - Unauthenticated password reset endpoint for flagged users

4. **Integration Points**
   - Greet service personalization based on authenticated user
   - Admin-only endpoints for user management
   - BDD test coverage for all authentication flows
   - CI/CD pipeline updates for new dependencies

### Technical Implementation

#### Database Schema (PostgreSQL)
```sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    created_at TIMESTAMP WITH TIME ZONE,
    updated_at TIMESTAMP WITH TIME ZONE,
    deleted_at TIMESTAMP WITH TIME ZONE,
    username VARCHAR(50) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    description TEXT,
    current_goal TEXT,
    is_admin BOOLEAN DEFAULT FALSE,
    allow_password_reset BOOLEAN DEFAULT FALSE,
    last_login TIMESTAMP WITH TIME ZONE
);
```

#### Technology Stack
- **ORM:** GORM (for PostgreSQL integration) - aligns with existing interface-based design
- **Authentication:** JWT with HS256 signing - stateless, scalable
- **Password Hashing:** bcrypt - industry standard for password storage
- **Validation:** go-playground/validator - consistent with existing validation approach
- **Database:** PostgreSQL (containerized) - production-ready database
- **Configuration:** Viper integration - consistent with existing config management
- **Logging:** Zerolog integration - consistent with existing logging approach
- **Telemetry:** OpenTelemetry support - consistent with existing observability

#### Architecture Alignment

The user management system follows the established DanceLessonsCoach patterns:

1. **Interface-based Design:**
   ```go
   type UserRepository interface {
       CreateUser(user *User) error
       GetUserByUsername(username string) (*User, error)
       // ... other methods
   }
   
   type AuthService interface {
       Authenticate(username, password string) (*User, error)
       GenerateJWT(user *User) (string, error)
       ValidateJWT(token string) (*User, error)
   }
   ```

2. **Context-aware Services:**
   ```go
   func (s *AuthService) Authenticate(ctx context.Context, username, password string) (*User, error) {
       log.Trace().Ctx(ctx).Str("username", username).Msg("Authenticating user")
       // ... authentication logic
   }
   ```

3. **Configuration Integration:**
   ```go
   type AuthConfig struct {
       JWTSecret       string        `mapstructure:"jwt_secret"`
       JWTExpiration   time.Duration `mapstructure:"jwt_expiration"`
       AdminUsername   string        `mapstructure:"admin_username"`
       AdminMasterPassword string    `mapstructure:"admin_master_password"`
   }
   ```

4. **Chi Router Integration:**
   ```go
   func (h *AuthHandler) RegisterRoutes(router chi.Router) {
       router.Post("/register", h.handleRegister)
       router.Post("/login", h.handleLogin)
       // ... other routes
   }
   ```

### Security Considerations

1. **Password Storage:** bcrypt with work factor 12
2. **JWT Security:** 
   - 30-minute expiration for access tokens
   - Secure random signing key
   - HTTPS-only cookies
   - **Secret Rotation:** Multiple valid secrets with retention policy (see Issue #8)
3. **Admin Access:**
   - Master password from environment variable
   - Non-persisted admin user
   - Full access to user management endpoints
   - **Password Reset Control:** Only admins can flag users for reset
4. **Password Reset Security:**
   - **Admin-Only Flagging:** Only authenticated admins can set `allow_password_reset` flag
   - **Flag-Based Access:** Unauthenticated reset only works for admin-flagged users
   - **Automatic Flag Clearing:** Flag is cleared after successful password reset
   - **No Self-Service:** Users cannot flag themselves or others for reset
5. **Rate Limiting:** On authentication endpoints (3 attempts/hour for password reset)
6. **Input Validation:** Strict username validation (alphanumeric, 3-50 chars)

### API Endpoints

#### Public Endpoints
- `POST /api/v1/auth/register` - User registration
- `POST /api/v1/auth/login` - User login
- `POST /api/v1/auth/reset-password` - Password reset (for flagged users)

#### Authenticated Endpoints
- `GET /api/v1/users/me` - Get current user profile
- `PUT /api/v1/users/me` - Update current user profile
- `PUT /api/v1/users/me/password` - Change own password

#### Admin-Only Endpoints
- `GET /api/v1/admin/users` - List all users
- `POST /api/v1/admin/users/{username}/allow-reset` - Allow password reset
- `DELETE /api/v1/admin/users/{username}` - Delete user

### Integration with Existing Services

#### Greet Service Enhancement

The authentication system integrates seamlessly with the existing greet service by leveraging Go's context package:

```go
// Updated greet service with authentication support
func (s *Service) Greet(ctx context.Context, name string) string {
    log.Trace().Ctx(ctx).Str("name", name).Msg("Greet function called")
    
    // Extract authenticated username from context using existing auth package
    if username := auth.GetUsernameFromContext(ctx); username != "" {
        log.Trace().Ctx(ctx).Str("authenticated_user", username).Msg("Using authenticated username")
        return "Hello " + username + "!"
    }
    
    // Fallback to original behavior for backward compatibility
    if name == "" {
        return "Hello world!"
    }
    return "Hello " + name + "!"
}
```

#### Authentication Middleware

The system includes Chi middleware for JWT validation:

```go
func (s *AuthService) Middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
        
        // Extract and validate JWT token
        token := auth.ExtractTokenFromRequest(r)
        if token == "" {
            next.ServeHTTP(w, r)
            return // Continue without authentication
        }
        
        // Validate token and extract user
        if user, err := s.ValidateJWT(ctx, token); err == nil {
            // Add user to context for downstream services
            ctx = auth.SetUserInContext(ctx, user)
            r = r.WithContext(ctx)
        }
        
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}
```

#### Server Integration

The authentication middleware is added to the Chi router stack:

```go
// In server.go
func (s *Server) getAllMiddlewares() []func(http.Handler) http.Handler {
    middlewares := []func(http.Handler) http.Handler{
        middleware.StripSlashes,
        middleware.Recoverer,
        s.authService.Middleware, // Add auth middleware
    }
    
    if s.withOTEL {
        middlewares = append(middlewares, func(next http.Handler) http.Handler {
            return otelhttp.NewHandler(next, "")
        })
    }
    
    return middlewares
}
```

#### Configuration Extension

The existing Config struct is extended with authentication settings:

```go
// In config.go
type AuthConfig struct {
    JWTSecret        string        `mapstructure:"jwt_secret"`
    JWTExpiration    time.Duration `mapstructure:"jwt_expiration"`
    AdminUsername    string        `mapstructure:"admin_username"`
    AdminMasterPassword string     `mapstructure:"admin_master_password"`
}

type DatabaseConfig struct {
    Host     string `mapstructure:"host"`
    Port     int    `mapstructure:"port"`
    User     string `mapstructure:"user"`
    Password string `mapstructure:"password"`
    Name     string `mapstructure:"name"`
    SSLMode  string `mapstructure:"ssl_mode"`
}

// Extended Config struct
type Config struct {
    Server    ServerConfig    `mapstructure:"server"`
    Shutdown  ShutdownConfig  `mapstructure:"shutdown"`
    Logging   LoggingConfig   `mapstructure:"logging"`
    Telemetry TelemetryConfig `mapstructure:"telemetry"`
    API       APIConfig       `mapstructure:"api"`
    Auth      AuthConfig      `mapstructure:"auth"`
    Database  DatabaseConfig  `mapstructure:"database"`
}
```

## Consequences

### Positive

1. **Personalized Experience:** Users see their username in greetings
2. **Admin Capabilities:** Secure administrative functions
3. **Password Recovery:** Admin-assisted workflow without contact info
4. **Security:** Proper authentication and authorization
5. **Extensibility:** Foundation for future user-based features

### Negative

1. **Increased Complexity:** Additional dependencies and configuration
2. **Database Requirement:** PostgreSQL container needed for development
3. **Migration Complexity:** Existing tests need updates
4. **CI/CD Changes:** Pipeline needs adjustment for new dependencies
5. **Performance Impact:** Authentication middleware adds overhead

### Neutral

1. **Learning Curve:** Team needs to learn GORM and JWT
2. **Testing Overhead:** Additional BDD scenarios required
3. **Documentation Needs:** Comprehensive API documentation required

## Alternatives Considered

### Alternative 1: No Authentication
- **Pros:** Simpler, no database needed
- **Cons:** No personalization, no admin functions
- **Rejected:** Doesn't meet product requirements

### Alternative 2: Session-based Auth
- **Pros:** Traditional approach, well-understood
- **Cons:** State management complexity, scaling issues
- **Rejected:** JWT provides better scalability

### Alternative 3: OAuth/OIDC
- **Pros:** Industry standard, delegation to identity providers
- **Cons:** Complex setup, external dependencies
- **Rejected:** Overkill for current requirements

### Alternative 4: Pure SQL (no ORM)
- **Pros:** No ORM overhead, direct control
- **Cons:** More boilerplate, manual query building
- **Rejected:** GORM provides good balance of control and convenience

## Implementation Plan

This implementation builds upon the completed phases and follows the established DanceLessonsCoach patterns.

### Phase 10: User Management Foundation (Next Phase)

**Objective:** Establish database models and basic user management

1. **Add Dependencies:**
   - `github.com/golang-jwt/jwt/v5` for JWT authentication
   - `golang.org/x/crypto` for bcrypt password hashing
   - `gorm.io/gorm` and `gorm.io/driver/postgres` for ORM

2. **Create User Package:**
   - `pkg/user/models.go` - User model and GORM repository
   - `pkg/user/repository.go` - Interface-based repository
   - `pkg/user/service.go` - User management service

3. **Database Setup:**
   - Add PostgreSQL container to `docker-compose.yml`
   - Create database migration scripts
   - Implement GORM database connection

4. **Configuration Extension:**
   - Extend `Config` struct with `AuthConfig` and `DatabaseConfig`
   - Add environment variable bindings with `DLC_` prefix
   - Update `LoadConfig()` function

### Phase 11: Authentication System

**Objective:** Implement secure authentication with JWT

1. **Auth Service:**
   - `pkg/auth/service.go` - JWT generation/validation
   - `pkg/auth/middleware.go` - Chi authentication middleware
   - `pkg/auth/context.go` - Context utilities for user data

2. **Authentication Endpoints:**
   - `POST /api/v1/auth/register` - User registration
   - `POST /api/v1/auth/login` - User login
   - `POST /api/v1/auth/refresh` - Token refresh

3. **Password Security:**
   - Implement bcrypt password hashing (work factor 12)
   - Add password validation rules
   - Implement secure password comparison

4. **Admin Authentication:**
   - Master password configuration
   - Non-persisted admin user
   - Admin middleware for privileged endpoints

### Phase 12: Integration & Personalization

**Objective:** Integrate authentication with existing services

1. **Greet Service Enhancement:**
   - Update `pkg/greet/greet.go` to check authenticated username
   - Maintain backward compatibility
   - Add context-based username extraction

2. **User Profile Endpoints:**
   - `GET /api/v1/users/me` - Get current user profile
   - `PUT /api/v1/users/me` - Update profile (description, goal)
   - `PUT /api/v1/users/me/password` - Change password

3. **Admin Endpoints:**
   - `GET /api/v1/admin/users` - List all users
   - `POST /api/v1/admin/users/{username}/allow-reset` - Allow password reset
   - `DELETE /api/v1/admin/users/{username}` - Delete user

### Phase 13: Password Reset & Testing

**Objective:** Implement password reset workflow and comprehensive testing

1. **Password Reset Workflow:**
   - `POST /api/v1/auth/reset-password` - Unauthenticated reset for flagged users
   - Admin flag management
   - Rate limiting for reset endpoints

2. **BDD Test Scenarios:**
   - User registration and login
   - Personalized greetings for authenticated users
   - Admin password reset workflow
   - Error handling and validation

3. **Unit & Integration Tests:**
   - Password hashing/verification
   - JWT token generation/validation
   - Repository methods
   - Authentication middleware

### Phase 14: CI/CD & Documentation

**Objective:** Update pipeline and create comprehensive documentation

1. **CI/CD Updates:**
   - Add PostgreSQL service to CI environment
   - Update dependency management
   - Add authentication test suite
   - Implement security scanning

2. **Documentation:**
   - Update `AGENTS.md` with new architecture
   - Create user management wiki page
   - Update API documentation with Swagger
   - Add configuration examples

3. **Deployment Preparation:**
   - Create database migration guide
   - Update Docker configuration
   - Add environment variable documentation
   - Create rollback plan

## Alignment with Existing Phases

This implementation builds upon the completed phases:

- **Phase 1-3:** Uses existing Go 1.26.1, Chi router, Zerolog, and interface-based design
- **Phase 5:** Extends Viper configuration management
- **Phase 6:** Integrates with graceful shutdown patterns
- **Phase 7:** Maintains OpenTelemetry compatibility
- **Phase 8:** Follows existing build system patterns
- **Phase 9:** Preserves trace-level logging approach

## Backward Compatibility

The implementation maintains full backward compatibility:

1. **Greet Service:** Falls back to original behavior when no authentication
2. **API Endpoints:** Existing `/api/v1/greet/*` endpoints unchanged
3. **Configuration:** All existing config options preserved
4. **Logging:** Maintains existing Zerolog integration
5. **Telemetry:** OpenTelemetry continues to work unchanged

## Success Metrics

1. **Security:** No authentication bypass vulnerabilities
2. **Performance:** <50ms auth middleware overhead
3. **Reliability:** 99.9% uptime for auth endpoints
4. **Adoption:** 80% of API calls authenticated within 3 months
5. **Satisfaction:** User feedback on personalization features

## Open Questions

1. Should we implement refresh tokens for longer sessions?
2. What should be the maximum session duration?
3. Should we add IP-based rate limiting for auth endpoints?
4. What username characters should be allowed beyond alphanumeric?
5. Should we implement account lockout after failed attempts?

## Future Considerations

1. **Multi-factor Authentication:** For enhanced security
2. **OAuth Integration:** For third-party identity providers
3. **User Activity Logging:** For audit trails
4. **Password Strength Meter:** For better user experience
5. **Account Recovery:** Email/phone-based recovery options
6. **JWT Secret Rotation:** Implement secret persistence and rotation mechanism (Issue #8)

## References

- [GORM Documentation](https://gorm.io/)
- [JWT RFC 7519](https://tools.ietf.org/html/rfc7519)
- [OWASP Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html)
- [bcrypt Password Hashing](https://en.wikipedia.org/wiki/Bcrypt)

**Approved by:** [Product Owner]
**Approval Date:** [To be determined]
**Implementation Target:** Q2 2024