feat: initialize Next.js project with Prisma, authentication, and rankings page
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user