# Security

## 11.1 Authentication

### Authentication Methods
The system implements multiple authentication methods to ensure secure access:

- **Session Authentication**: Laravel session-based authentication
- **Token Authentication**: Laravel Sanctum for API access
- **Remember Tokens**: Persistent login functionality
- **Password Hashing**: bcrypt password hashing

### Authentication Implementation
```php
// User authentication with Sanctum
class AuthenticatedSessionController extends Controller
{
    public function store(LoginRequest $request)
    {
        $request->authenticate();
        $request->session()->regenerate();
        
        // Create API token for authenticated user
        $token = $request->user()->createToken('api-token');
        
        return redirect()->intended(route('dashboard'));
    }
    
    public function destroy(Request $request)
    {
        Auth::guard('web')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();
        
        return redirect('/');
    }
}
```

### Password Security
```php
// Password validation and hashing
class User extends Authenticatable
{
    protected $hidden = ['password', 'remember_token'];
    
    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];
    
    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = Hash::make($value);
    }
}
```

## 11.2 Authorization

### Role-Based Access Control (RBAC)
The system implements a comprehensive RBAC system with roles and permissions:

```php
// Role and Permission models
class Role extends Model
{
    public function users() { return $this->belongsToMany(User::class); }
    public function permissions() { return $this->belongsToMany(Permission::class); }
}

class Permission extends Model
{
    public function roles() { return $this->belongsToMany(Role::class); }
}

// User role and permission checks
class User extends Authenticatable
{
    public function hasRole($role)
    {
        return $this->roles()->where('name', $role)->exists();
    }
    
    public function hasPermission($permission)
    {
        return $this->getAllPermissions()->contains('name', $permission);
    }
    
    public function getAllPermissions()
    {
        return $this->roles->flatMap->permissions->unique('id');
    }
}
```

### Permission Middleware
```php
// Permission-based middleware
class PermissionMiddleware
{
    public function handle($request, Closure $next, $permission)
    {
        if (!auth()->user()->hasPermission($permission)) {
            abort(403, 'Insufficient permissions');
        }
        
        return $next($request);
    }
}

// Route protection
Route::middleware(['auth', 'permission:tournaments.create'])->group(function () {
    Route::get('tournaments/create', [TournamentAdminController::class, 'create']);
    Route::post('tournaments', [TournamentAdminController::class, 'store']);
});
```

### Data Scoping
```php
// Data access control based on user roles
class DataScopingService
{
    public function scopeTournaments(Builder $query, User $user): Builder
    {
        $userRoles = $user->roles()->pluck('name')->toArray();

        // Admins can see all tournaments
        if (in_array('admin', $userRoles) || in_array('super_admin', $userRoles)) {
            return $query;
        }

        // Organizers can see tournaments they manage
        if (in_array('organizer', $userRoles)) {
            return $query->where('organizer_id', $user->id);
        }

        // Players can see tournaments they're participating in
        if (in_array('player', $userRoles)) {
            $player = Player::where('user_id', $user->id)->first();
            if ($player) {
                return $query->whereHas('teams.players', function($q) use ($player) {
                    $q->where('player_id', $player->id);
                });
            }
        }

        return $query->where('id', 0);
    }
}
```

## 11.3 Data Protection

### Input Validation
```php
// Form request validation
class TournamentRequest extends FormRequest
{
    public function rules()
    {
        return [
            'name' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'start_date' => 'required|date|after:today',
            'end_date' => 'required|date|after:start_date',
            'max_participants' => 'required|integer|min:2|max:1000',
            'entry_fee' => 'nullable|numeric|min:0',
            'banner_image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        ];
    }
    
    public function messages()
    {
        return [
            'name.required' => 'Tournament name is required',
            'start_date.after' => 'Start date must be in the future',
            'end_date.after' => 'End date must be after start date',
        ];
    }
}
```

### Output Encoding
```php
// XSS prevention through output encoding
class TournamentController extends Controller
{
    public function show(Tournament $tournament)
    {
        return Inertia::render('Tournament/Show', [
            'tournament' => [
                'id' => $tournament->id,
                'name' => e($tournament->name), // HTML encoding
                'description' => e($tournament->description),
                'start_date' => $tournament->start_date,
                'end_date' => $tournament->end_date,
            ]
        ]);
    }
}
```

### SQL Injection Prevention
```php
// Parameterized queries with Eloquent
class Tournament extends Model
{
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }
    
    public function scopeByOrganizer($query, $organizerId)
    {
        return $query->where('organizer_id', $organizerId);
    }
}

// Safe query execution
$tournaments = Tournament::active()
    ->byOrganizer($userId)
    ->where('start_date', '>=', now())
    ->get();
```

## 11.4 Input Validation

### Server-Side Validation
```php
// Comprehensive input validation
class PlayerRequest extends FormRequest
{
    public function rules()
    {
        return [
            'name' => 'required|string|max:255',
            'email' => 'required|email|unique:players,email',
            'phone' => 'required|string|regex:/^\+?[\d\s-()]+$/',
            'date_of_birth' => 'required|date|before:today',
            'nationality' => 'required|string|max:100',
            'jersey_number' => 'required|integer|min:1|max:99',
            'position' => 'required|string|in:goalkeeper,defender,midfielder,forward',
            'height' => 'nullable|integer|min:100|max:250',
            'weight' => 'nullable|integer|min:30|max:200',
            'profile_image' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
            'id_front_image' => 'required|image|mimes:jpeg,png,jpg|max:2048',
            'id_back_image' => 'required|image|mimes:jpeg,png,jpg|max:2048',
        ];
    }
}
```

### Client-Side Validation
```typescript
// React form validation
const useFormValidation = (initialValues: Record<string, any>) => {
  const [values, setValues] = useState(initialValues);
  const [errors, setErrors] = useState<Record<string, string>>({});

  const validate = (field: string, value: any): string | undefined => {
    switch (field) {
      case 'email':
        if (value && !/\S+@\S+\.\S+/.test(value)) {
          return 'Email is invalid';
        }
        break;
      case 'phone':
        if (value && !/^\+?[\d\s-()]+$/.test(value)) {
          return 'Phone number is invalid';
        }
        break;
      case 'password':
        if (value && value.length < 8) {
          return 'Password must be at least 8 characters';
        }
        break;
      case 'jersey_number':
        if (value && (value < 1 || value > 99)) {
          return 'Jersey number must be between 1 and 99';
        }
        break;
    }
    return undefined;
  };

  const handleChange = (field: string, value: any) => {
    setValues(prev => ({ ...prev, [field]: value }));
    const error = validate(field, value);
    setErrors(prev => ({ ...prev, [field]: error }));
  };

  return { values, errors, handleChange, isValid: Object.values(errors).every(error => !error) };
};
```

## 11.5 File Upload Security

### File Upload Validation
```php
// Secure file upload handling
class FileUploadController extends Controller
{
    public function upload(Request $request)
    {
        $request->validate([
            'file' => 'required|file|mimes:jpeg,png,jpg,pdf|max:2048',
            'type' => 'required|in:profile,id_front,id_back,document'
        ]);

        $file = $request->file('file');
        $filename = time() . '_' . Str::random(10) . '.' . $file->getClientOriginalExtension();
        
        // Store in secure location
        $path = $file->storeAs('uploads/' . $request->type, $filename, 'private');
        
        // Generate secure URL
        $url = Storage::url($path);
        
        return response()->json([
            'success' => true,
            'filename' => $filename,
            'path' => $path,
            'url' => $url
        ]);
    }
}
```

### File Type Validation
```php
// MIME type validation
class FileValidator
{
    public static function validateImage($file)
    {
        $allowedMimes = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif'];
        $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
        
        $mimeType = $file->getMimeType();
        $extension = $file->getClientOriginalExtension();
        
        return in_array($mimeType, $allowedMimes) && 
               in_array(strtolower($extension), $allowedExtensions);
    }
    
    public static function validateDocument($file)
    {
        $allowedMimes = ['application/pdf', 'image/jpeg', 'image/png'];
        $allowedExtensions = ['pdf', 'jpg', 'jpeg', 'png'];
        
        $mimeType = $file->getMimeType();
        $extension = $file->getClientOriginalExtension();
        
        return in_array($mimeType, $allowedMimes) && 
               in_array(strtolower($extension), $allowedExtensions);
    }
}
```

### Secure File Storage
```php
// Secure file storage configuration
class FileStorageService
{
    public function storeFile($file, $directory, $filename = null)
    {
        $filename = $filename ?: time() . '_' . Str::random(10) . '.' . $file->getClientOriginalExtension();
        
        // Store in private directory
        $path = $file->storeAs('private/' . $directory, $filename);
        
        // Set appropriate permissions
        Storage::setVisibility($path, 'private');
        
        return $path;
    }
    
    public function getSecureUrl($path)
    {
        // Generate temporary signed URL
        return Storage::temporaryUrl($path, now()->addMinutes(60));
    }
}
```

## 11.6 API Security

### API Authentication
```php
// API token authentication
class ApiController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:sanctum');
    }
    
    public function index(Request $request)
    {
        $user = $request->user();
        
        // Check API permissions
        if (!$user->hasPermission('api.access')) {
            return response()->json(['error' => 'Insufficient permissions'], 403);
        }
        
        return response()->json(['data' => $this->getData($user)]);
    }
}
```

### Rate Limiting
```php
// API rate limiting
Route::middleware(['auth:sanctum', 'throttle:api'])->group(function () {
    Route::get('/api/tournaments', [TournamentController::class, 'index']);
    Route::post('/api/tournaments', [TournamentController::class, 'store']);
});

// Custom rate limiting
class ApiRateLimiter
{
    public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes = 1)
    {
        $key = $this->resolveRequestSignature($request);
        
        if (RateLimiter::tooManyAttempts($key, $maxAttempts)) {
            return response()->json([
                'error' => 'Too many requests',
                'retry_after' => RateLimiter::availableIn($key)
            ], 429);
        }
        
        RateLimiter::hit($key, $decayMinutes * 60);
        
        return $next($request);
    }
}
```

### CORS Configuration
```php
// CORS configuration
class CorsMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        
        $response->headers->set('Access-Control-Allow-Origin', config('app.frontend_url'));
        $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
        $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
        $response->headers->set('Access-Control-Allow-Credentials', 'true');
        
        return $response;
    }
}
```

### API Response Security
```php
// Secure API responses
class SecureApiResponse
{
    public static function success($data = null, $message = 'Success', $status = 200)
    {
        return response()->json([
            'success' => true,
            'message' => $message,
            'data' => $data,
            'timestamp' => now()->toISOString()
        ], $status);
    }
    
    public static function error($message = 'Error', $status = 400, $errors = null)
    {
        return response()->json([
            'success' => false,
            'message' => $message,
            'errors' => $errors,
            'timestamp' => now()->toISOString()
        ], $status);
    }
}
```

---

## Security Best Practices

### General Security Measures
- **HTTPS Enforcement**: All communications encrypted
- **Session Security**: Secure session configuration
- **CSRF Protection**: Cross-site request forgery protection
- **XSS Prevention**: Input sanitization and output encoding
- **SQL Injection Prevention**: Parameterized queries
- **File Upload Security**: Type validation and secure storage

### Authentication Security
- **Strong Passwords**: Minimum password requirements
- **Account Lockout**: Brute force protection
- **Session Management**: Secure session handling
- **Token Security**: Secure API token management

### Data Protection
- **Data Encryption**: Sensitive data encryption
- **Access Control**: Role-based access control
- **Audit Logging**: Security event logging
- **Data Backup**: Secure data backup procedures

---

## Next Steps

- [Database](12_Database.md) - Database security and configuration
- [Configuration](13_Configuration.md) - Security configuration
- [Deployment](14_Deployment.md) - Production security setup
- [User Guide](17_User_Guide.md) - User security guidelines
