174 lines
6.4 KiB
Markdown
174 lines
6.4 KiB
Markdown
# 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
|
|
```php
|
|
// config/fortify.php
|
|
'features' => [
|
|
// Features::registration(), // DISABLED
|
|
Features::resetPasswords(),
|
|
Features::emailVerification(),
|
|
Features::updateProfileInformation(),
|
|
Features::updatePasswords(),
|
|
],
|
|
```
|
|
|
|
### Custom Views Setup
|
|
```php
|
|
// 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
|
|
```php
|
|
// 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
|
|
```env
|
|
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
|