# Authentication, Authorization, and Accounting (AAA) Design ## Overview Implement a comprehensive AAA system for EuchreCamp with user authentication, role-based authorization, and activity logging. ## Authentication (Who are you?) ### User Model ```ruby # Database Schema table :users do primary_key :id foreign_key :player_id, :players # Links to existing player record column :email, String, null: false, unique: true column :password_digest, String, null: false column :confirmed, Boolean, default: false column :confirmation_token, String column :confirmation_sent_at, DateTime column :reset_password_token, String column :reset_password_sent_at, DateTime column :failed_login_attempts, Integer, default: 0 column :locked_until, DateTime column :last_login_at, DateTime column :last_login_ip, String column :created_at, DateTime, null: false column :updated_at, DateTime, null: false end # Indexes add_index :users, :email, unique: true add_index :users, :confirmation_token add_index :users, :reset_password_token ``` ### Authentication Flow 1. User enters email and password 2. System verifies email exists and account is not locked 3. BCrypt verifies password hash 4. If successful: - Update `last_login_at` and `last_login_ip` - Reset `failed_login_attempts` - Create session/token 5. If failed: - Increment `failed_login_attempts` - Lock account after 5 failed attempts (15 minutes) ### Session Management - Use signed cookies for session storage - Session expires after 30 days of inactivity - Session invalidation on password change - Concurrent session limits (optional) ### Password Requirements - Minimum 8 characters - At least one uppercase letter - At least one lowercase letter - At least one number - At least one special character ### Registration Flow 1. User registers with email and password 2. System creates user record with `confirmed: false` 3. Send confirmation email with unique token 4. User clicks link to confirm account 5. Account activated and ready for login ### Password Reset Flow 1. User requests password reset 2. System generates unique token (expires in 1 hour) 3. Send reset email with token link 4. User enters new password 5. System validates and updates password hash 6. Invalidate all existing sessions ## Authorization (What can you do?) ### Role-Based Access Control (RBAC) #### Roles ```ruby ROLES = { player: 0, # Default user - can view rankings, own profile tournament_admin: 1, # Can manage specific tournaments club_admin: 2, # Superuser - full access system_admin: 3 # Technical admin access } ``` #### Permission Matrix | Permission | Player | Tournament Admin | Club Admin | System Admin | |------------|--------|------------------|------------|--------------| | View rankings | ✅ | ✅ | ✅ | ✅ | | View own profile | ✅ | ✅ | ✅ | ✅ | | Edit own profile | ✅ | ✅ | ✅ | ✅ | | View other profiles | ✅ | ✅ | ✅ | ✅ | | Record own matches | ✅ | ✅ | ✅ | ✅ | | Create tournaments | ❌ | ✅ | ✅ | ✅ | | Manage own tournaments | ❌ | ✅ | ✅ | ✅ | | Manage all tournaments | ❌ | ❌ | ✅ | ✅ | | Manage all players | ❌ | ❌ | ✅ | ✅ | | Club settings | ❌ | ❌ | ✅ | ✅ | | System settings | ❌ | ❌ | ❌ | ✅ | ### Implementation ```ruby module EuchreCamp module Auth class Authorization def self.can?(user, action, resource = nil) case action when :view_rankings true # All users can view rankings when :edit_profile resource.nil? || resource.id == user.player_id when :create_tournament user.club_admin? || user.system_admin? when :manage_tournament user.club_admin? || user.system_admin? || (user.tournament_admin? && resource.admin_id == user.player_id) when :manage_players user.club_admin? || user.system_admin? else false end end end end end ``` ### Middleware - Authentication middleware checks for valid session - Authorization middleware verifies permissions - Redirect unauthenticated users to login - Show 403 Forbidden for unauthorized actions ## Accounting (What did you do?) ### Activity Logging ```ruby table :activity_logs do primary_key :id foreign_key :user_id, :users column :action, String, null: false # e.g., 'login', 'create_tournament', 'record_match' column :resource_type, String # e.g., 'tournament', 'match', 'player' column :resource_id, Integer column :ip_address, String column :user_agent, String column :details, JSON # Additional context column :created_at, DateTime, null: false end add_index :activity_logs, [:user_id, :created_at] add_index :activity_logs, [:resource_type, :resource_id] ``` ### Tracked Events - Authentication events (login, logout, password change) - Tournament management (create, update, delete, schedule) - Match recording (create, update, delete) - Player management (create, update) - Settings changes ### Audit Reports - User activity timeline - Tournament lifecycle audit - Match result verification log - System changes overview ## Implementation Plan ### Phase 1: Authentication (Week 1-2) - [ ] Create users table and model - [ ] Implement BCrypt password hashing - [ ] Build login/logout actions - [ ] Create registration flow - [ ] Add session management - [ ] Password reset functionality ### Phase 2: Authorization (Week 2-3) - [ ] Define roles and permissions - [ ] Implement RBAC middleware - [ ] Add role assignment UI (for club admins) - [ ] Protect routes based on roles - [ ] Add permission checks to actions ### Phase 3: Accounting (Week 3-4) - [ ] Create activity logging system - [ ] Track key events - [ ] Build audit reports UI - [ ] Add activity feed to dashboard ### Phase 4: Security Hardening (Week 4-5) - [ ] Rate limiting on login attempts - [ ] IP-based lockout - [ ] Secure cookie settings - [ ] CSRF protection - [ ] Security headers - [ ] Session fixation prevention ## Security Considerations ### Password Security - Use BCrypt with cost factor 12+ - Never store plaintext passwords - Enforce strong password policy - Rate limit password attempts ### Session Security - Use signed, encrypted cookies - Regenerate session ID on privilege escalation - Set appropriate expiration times - Invalidate on password change ### Access Control - Principle of least privilege - Defense in depth - Fail securely (deny by default) - Log all access attempts ### Data Protection - Encrypt sensitive data at rest - Secure transmission (HTTPS only) - Regular security audits - Compliance with privacy regulations ## API Endpoints ### Authentication ``` POST /auth/login # Login with email/password POST /auth/logout # Logout current session POST /auth/register # Create new account POST /auth/confirm # Confirm email address POST /auth/forgot # Request password reset POST /auth/reset # Reset password with token ``` ### Users ``` GET /users/me # Get current user profile PATCH /users/me # Update own profile GET /users/:id # Get user profile (public) ``` ### Admin ``` GET /admin/users # List users (club admin only) PATCH /admin/users/:id # Update user roles (club admin only) GET /admin/activity # View audit logs (club admin only) ``` ## Testing Strategy ### Unit Tests - Password hashing verification - Permission calculations - Session management - Activity logging ### Integration Tests - Login/logout flow - Registration process - Password reset - Role-based access ### Security Tests - SQL injection prevention - XSS prevention - CSRF protection - Rate limiting - Session security ## Migration Steps 1. Create users table and related migrations 2. Add foreign key from users to players 3. Migrate existing player data to users (optional) 4. Update navigation to show login/logout links 5. Add authentication checks to existing actions 6. Implement role assignment for existing admins 7. Set up activity logging for new features