libra/docs/stories/story-1.2-authentication-ro...

6.4 KiB

Story 1.2: Authentication & Role System

Epic Reference

Epic 1: Core Foundation & Infrastructure

User Story

As an admin, I want a secure authentication system with Admin/Client roles, So that only authorized users can access the platform with appropriate permissions.

Story Context

Existing System Integration

  • Integrates with: Fortify authentication, users table
  • Technology: Laravel Fortify, Livewire Volt
  • Follows pattern: Existing app/Actions/Fortify/ for custom logic
  • Touch points: FortifyServiceProvider, login views, middleware

Acceptance Criteria

Functional Requirements

  • Fortify configured with custom Volt views
  • Login page with bilingual support (Arabic/English)
  • Session timeout after 2 hours of inactivity
  • Rate limiting on login attempts (5 attempts per minute)
  • Admin role with full access to all features
  • Client role with restricted access (own data only)
  • Registration feature DISABLED (admin creates all accounts)

Security Requirements

  • CSRF protection enabled on all forms
  • Password hashing using bcrypt
  • Gates/Policies for authorization checks
  • Secure session configuration
  • Remember me functionality (optional)

Integration Requirements

  • Login redirects to appropriate dashboard:
    • Admin users → /admin/dashboard (to be created in Epic 2)
    • Client users → /dashboard (to be created in Epic 2)
    • For now, redirect to a placeholder route or home page
  • Logout clears session properly and redirects to login page
  • Middleware protects admin-only routes (return 403 for unauthorized)
  • Failed login attempts logged to admin_logs table

Quality Requirements

  • Login form validates inputs properly
  • Error messages are clear and bilingual
  • All test scenarios in "Test Scenarios" section pass
  • No security vulnerabilities

Technical Notes

Fortify Configuration

// config/fortify.php
'features' => [
    // Features::registration(), // DISABLED
    Features::resetPasswords(),
    Features::emailVerification(),
    Features::updateProfileInformation(),
    Features::updatePasswords(),
],

Custom Views Setup

// FortifyServiceProvider boot()
Fortify::loginView(fn () => view('auth.login'));
// No registerView - registration disabled

Role Implementation

  • Use user_type column: 'admin', 'individual', 'company'
  • Admin check: $user->user_type === 'admin'
  • Client check: in_array($user->user_type, ['individual', 'company'])

Gate Definitions

// AuthServiceProvider or AppServiceProvider
Gate::define('admin', fn (User $user) => $user->user_type === 'admin');
Gate::define('client', fn (User $user) => $user->user_type !== 'admin');

Middleware

  • auth - Require authentication
  • can:admin - Require admin role
  • Custom middleware for session timeout if needed

Environment Configuration

SESSION_LIFETIME=120    # 2 hours in minutes
SESSION_EXPIRE_ON_CLOSE=false

Edge Case Behavior

Rate Limiting (5 attempts per minute):

  • After 5 failed attempts, show message: "Too many login attempts. Please try again in 60 seconds."
  • Use bilingual message from translation files
  • Log rate limit events for security monitoring

Session Timeout (2 hours inactivity):

  • When session expires, redirect to login page
  • Show flash message: "Your session has expired. Please log in again."
  • Preserve intended URL for redirect after re-authentication

Deactivated Account Login Attempt:

  • Check status field during authentication
  • If status === 'deactivated', reject login with message: "Your account has been deactivated. Please contact the administrator."

Test Scenarios

Feature Tests (tests/Feature/Auth/)

Login Flow:

  • test_login_page_renders_correctly - Login page displays in default language
  • test_user_can_login_with_valid_credentials - Valid credentials redirect to dashboard
  • test_admin_redirects_to_admin_dashboard - Admin user goes to admin dashboard
  • test_client_redirects_to_client_dashboard - Client user goes to client dashboard
  • test_invalid_credentials_show_error - Wrong password shows bilingual error
  • test_nonexistent_user_shows_error - Unknown email shows generic error (no user enumeration)
  • test_deactivated_user_cannot_login - Deactivated account rejected with message

Rate Limiting:

  • test_rate_limiting_blocks_after_five_attempts - 6th attempt blocked
  • test_rate_limit_message_is_bilingual - Error message respects locale
  • test_rate_limit_resets_after_one_minute - Can retry after cooldown

Session Management:

  • test_logout_clears_session - Logout destroys session data
  • test_remember_me_extends_session - Remember token works (if implemented)

Authorization:

  • test_admin_can_access_admin_routes - Admin passes can:admin middleware
  • test_client_cannot_access_admin_routes - Client gets 403 on admin routes
  • test_unauthenticated_user_redirected_to_login - Guest redirected from protected routes

Unit Tests (tests/Unit/)

Gate Definitions:

  • test_admin_gate_returns_true_for_admin_user - Gate check passes
  • test_admin_gate_returns_false_for_client_user - Gate check fails
  • test_client_gate_returns_true_for_individual_user - Client gate passes
  • test_client_gate_returns_true_for_company_user - Client gate passes

Definition of Done

  • Login page renders correctly in both languages
  • Users can log in with valid credentials
  • Invalid credentials show proper error (bilingual)
  • Deactivated users cannot log in
  • Rate limiting prevents brute force (5 attempts/minute)
  • Session expires after 2 hours inactivity
  • Admin routes protected from clients (403 response)
  • All Feature and Unit tests from "Test Scenarios" section pass
  • Code formatted with Pint

Dependencies

  • Story 1.1: Database schema - creates users table with user_type enum (admin, individual, company), status enum (active, deactivated), and preferred_language enum (ar, en)
  • Story 1.3: Bilingual infrastructure (for login page translations)

Risk Assessment

  • Primary Risk: Security misconfiguration
  • Mitigation: Use Laravel's built-in security features, no custom auth logic
  • Rollback: Restore Fortify defaults

Estimation

Complexity: Medium Estimated Effort: 3-4 hours