# Unified Auth & Permission System - Implementation Guide

**Created:** 2025-11-28  
**Status:** Ready for Implementation

## Overview

This system implements a **hybrid approach** to authentication and permission checking that combines both into a single, convenient method call while maintaining flexibility.

## What Changed?

### Before (Old Method)
```php
public function index() {
    $this->requireAuth();
    $this->checkPermission('employees.view');
    
    // method code...
}
```

**Problems:**
- Two separate calls to remember
- Easy to forget permission check
- 106+ methods had auth but no permissions
- Inconsistent across controllers

### After (New Method)
```php
public function index() {
    $this->requireAuthAndPermission();  // Single call, auto-detects 'employees.view'
    
    // method code...
}
```

**Benefits:**
- ✅ Single method call
- ✅ Automatic permission detection
- ✅ Can't forget permission check
- ✅ Flexible for custom permissions
- ✅ Backward compatible

## How It Works

The `requireAuthAndPermission()` method:

1. **Always requires authentication** (user must be logged in)
2. **Auto-detects the permission** based on:
   - Controller name (e.g., `EmployeeController` → `employees`)
   - Method name (e.g., `index()` → `view`)
   - Builds permission: `employees.view`
3. **Checks if permission exists** in database
4. **Enforces permission** if it exists
5. **Logs warning** if permission doesn't exist (in debug mode)

## Usage Examples

### 1. Automatic Permission (Recommended)
```php
public function index() {
    $this->requireAuthAndPermission();  // Auto: employees.view
}

public function create() {
    $this->requireAuthAndPermission();  // Auto: employees.create
}

public function edit($id) {
    $this->requireAuthAndPermission();  // Auto: employees.edit
}
```

### 2. Custom Action Name
```php
public function directory() {
    $this->requireAuthAndPermission('directory');  // Explicit: employees.directory
}

public function export() {
    $this->requireAuthAndPermission('export');  // Explicit: employees.export
}
```

### 3. Fully Custom Permission
```php
public function specialReport() {
    $this->requireAuthAndPermission('reports.special');  // Custom permission
}

public function adminPanel() {
    $this->requireAuthAndPermission('admin.access');  // Custom permission
}
```

### 4. Auth Only (No Permission)
For methods that should be accessible to ALL authenticated users:
```php
public function profile() {
    $this->requireAuth();  // Auth only, no permission check
}
```

## Method Mapping

The system automatically maps common method names to permission actions:

| Method Name | Maps To | Example Permission |
|-------------|---------|-------------------|
| `index()` | `view` | `employees.view` |
| `show()` | `view` | `employees.view` |
| `create()` | `create` | `employees.create` |
| `store()` | `create` | `employees.create` |
| `edit()` | `edit` | `employees.edit` |
| `update()` | `edit` | `employees.edit` |
| `delete()` | `delete` | `employees.delete` |
| `destroy()` | `delete` | `employees.delete` |
| `trash()` | `delete` | `employees.delete` |
| `restore()` | `delete` | `employees.delete` |

Custom method names use their actual name as the action.

## Migration Process

### Step 1: Preview Changes (Dry Run)
```bash
# See what will change without modifying files
php scripts/migrate_to_unified_auth.php --dry-run
```

### Step 2: Test on Single Controller
```bash
# Migrate one controller to test
php scripts/migrate_to_unified_auth.php --dry-run --controller=Employee
php scripts/migrate_to_unified_auth.php --apply --controller=Employee
```

### Step 3: Migrate All Controllers
```bash
# Apply to all controllers
php scripts/migrate_to_unified_auth.php --apply
```

### Step 4: Generate Missing Permissions
```bash
# See what permissions are missing
php scripts/generate_missing_permissions.php

# Create them in database
php scripts/generate_missing_permissions.php --apply
```

### Step 5: Verify
```bash
# Check for any remaining issues
php scripts/check_permission_consistency.php
php scripts/find_unprotected_routes.php
```

## Generated Permissions

The helper script automatically:

- **Detects missing permissions** from controller usage
- **Determines module** based on controller name
- **Assigns to permission group** based on module
- **Generates descriptions** from action + resource
- **Creates SQL** or applies directly to database

Example generated permissions:
```sql
INSERT INTO permissions (name, description, module, group_id) 
VALUES ('dashboard.view', 'View Dashboard', '', 1);

INSERT INTO permissions (name, description, module, group_id) 
VALUES ('calendar.view', 'View Calendar', 'calendar', 1);

INSERT INTO permissions (name, description, module, group_id) 
VALUES ('messaging.view', 'View Messaging', 'messaging', 3);
```

## Module & Group Mapping

The system automatically determines modules and permission groups:

| Controller Pattern | Module | Group ID | Group Name |
|-------------------|--------|----------|------------|
| Employee*, Payroll*, HR* | `hr` | 7 | HR |
| Customer*, CRM*, Contact* | `crm` | 6 | CRM |
| Account*, Invoice*, Journal* | `accounting` | 5 | Accounting |
| Product*, Stock*, Inventory* | `inventory` | 8 | Inventory |
| WorkOrder*, BOM*, Quality* | `manufacturing` | 9 | Manufacturing |
| Sales*, Delivery*, Shipment* | `sales` | 11 | Sales |
| Purchase*, Supplier*, RFQ* | `purchases` | 10 | Purchases |
| Document*, FileManager* | `documents` | 12 | Documents |
| HelpDesk*, Support* | `helpdesk` | 13 | Help Desk |
| Project* | `projects` | 14 | Projects |
| User*, Role*, Settings* | `admin` | 16 | Settings & System |

## Best Practices

### DO ✅
- Use `requireAuthAndPermission()` for all protected routes
- Let auto-detection handle standard CRUD operations
- Use custom permissions for special actions
- Generate missing permissions after migration
- Test thoroughly after migration

### DON'T ❌
- Don't use `requireAuth()` alone for protected features
- Don't hardcode permission checks in views (use in controller)
- Don't skip permission generation step
- Don't apply migration without dry-run first
- Don't forget to test user roles after adding permissions

## Troubleshooting

### Permission Not Found Warning
```
Warning: Permission 'controller.action' does not exist in database
```

**Solution:** Run `php scripts/generate_missing_permissions.php --apply`

### User Can't Access Feature
1. Check permission exists: `SELECT * FROM permissions WHERE name = 'controller.action'`
2. Check user's role has permission: `SELECT * FROM role_permissions WHERE permission_id = X`
3. Check permission group assignment in roles UI

### Auto-Detection Wrong
Use explicit permission:
```php
$this->requireAuthAndPermission('custom.permission');
```

### Need Auth Only (No Permission)
```php
$this->requireAuth();  // Old method still works
```

## Files Created/Modified

### Core Framework
- `core/Controller.php` - Added `requireAuthAndPermission()` and helper methods

### Migration Tools
- `scripts/migrate_to_unified_auth.php` - Convert controllers to new method
- `scripts/generate_missing_permissions.php` - Create missing permissions
- `scripts/check_permission_consistency.php` - Audit permission usage
- `scripts/find_unprotected_routes.php` - Find unprotected methods

### Documentation
- `UNIFIED_AUTH_GUIDE.md` - This file
- `PERMISSION_AUDIT_SUMMARY.md` - Initial audit results

## Migration Checklist

- [ ] **Backup database and code**
- [ ] Run dry-run migration to preview changes
- [ ] Test migration on single controller
- [ ] Review changes and test functionality
- [ ] Migrate all controllers
- [ ] Generate missing permissions
- [ ] Review generated permissions for correctness
- [ ] Apply permissions to database
- [ ] Test with different user roles
- [ ] Update role assignments if needed
- [ ] Run permission consistency check
- [ ] Monitor logs for permission warnings
- [ ] Update any custom authentication logic
- [ ] Document any special permissions for your team

## Expected Results

After migration:
- **0 methods** with auth but no permission check
- **All permissions** exist in database for used features
- **Single call** for auth + permission in every method
- **Consistent** permission naming across system
- **Flexible** for future changes

## Support

If you encounter issues:
1. Check this guide for solutions
2. Run diagnostic scripts (`check_permission_consistency.php`, etc.)
3. Review generated SQL before applying
4. Test changes in development first

## Timeline Estimate

- Preview & Planning: 30 minutes
- Single Controller Test: 15 minutes
- Full Migration: 1-2 hours
- Permission Generation: 30 minutes
- Testing & Verification: 2-3 hours
- **Total: 4-6 hours**

---

**Ready to start?** Run: `php scripts/migrate_to_unified_auth.php --dry-run`
