# Guard System - Framework OfficeGest

## Visão Geral da Pasta Guard

A pasta `Modules/Common/Guard/` contém o sistema de autenticação e autorização baseado em tokens do framework OfficeGest. Este sistema oferece funcionalidades similares ao Laravel Sanctum, fornecendo autenticação via Personal Access Tokens (PAT) para APIs e tokens de sessão para Single Page Applications (SPAs). O sistema integra-se nativamente com o sistema legado do OfficeGest, oferecendo uma ponte moderna entre autenticação tradicional e baseada em tokens.

## Arquitectura e Estrutura

### Mapeamento de Arquivos e Responsabilidades

```
Modules/Common/Guard/
├── GuardManager.php              → Classe principal de gestão de autenticação
├── GuardServiceProvider.php     → Provider para registo no container DI
├── GuardFacade.php              → Facade para acesso simplificado
├── TokenManager.php             → Gestão de Personal Access Tokens
├── PersonalAccessToken.php      → Modelo de token de acesso pessoal
└── Middleware/
    ├── GuardAuthMiddleware.php        → Middleware de autenticação básica
    ├── GuardThrottleMiddleware.php    → Middleware de rate limiting
    ├── GuardAbilitiesMiddleware.php   → Middleware de verificação de abilities
    └── GuardMiddlewareResolver.php    → Resolver para inicialização de middlewares
```

**Padrões Implementados:**
- **Service Provider Pattern**: Registo automático no container DI
- **Facade Pattern**: Interface estática limpa através de `GuardFacade`
- **Middleware Pattern**: Pipeline de autenticação e autorização
- **Token-based Authentication**: Gestão segura de tokens com abilities/scopes

## Classes e Componentes

### GuardManager

**Localização:** `Modules/Common/Guard/GuardManager.php:27`

Classe principal que orquestra todo o sistema de autenticação baseado em tokens. Actua como ponte entre a validação de tokens e o sistema de autenticação de utilizadores do OfficeGest.

**Propriedades Principais:**
- `$config` - Configuração do sistema Guard
- `$tokenManager` - Gestor de Personal Access Tokens
- `$currentToken` - Token activo na sessão actual
- `$authManager` - Instância do AuthManager para gestão de sessão
- `$userService` - Serviço de utilizadores do sistema legacy

**Métodos de Autenticação:**
- `authenticate()` - Autentica utilizador via token e retorna AuthManager
- `auth()` - Obtém AuthManager actual ou tenta autenticação
- `check()` - Verifica se utilizador está autenticado
- `guest()` - Verifica se utilizador é convidado (não autenticado)
- `user()` - Obtém utilizador autenticado actual

**Métodos de Gestão de Tokens:**
- `createToken($userId, $name, $abilities, $expiresIn)` - Cria Personal Access Token
- `createSpaToken($userId, $name)` - Cria token específico para SPA
- `revokeCurrentToken()` - Revoga token actual
- `revokeAllTokens()` - Revoga todos os tokens do utilizador
- `tokens()` - Lista todos os tokens do utilizador

**Métodos de Autorização:**
- `can($permission)` - Verifica permissão do utilizador
- `tokenCan($ability)` - Verifica ability do token actual
- `tokenCanAny($abilities)` - Verifica se token tem qualquer das abilities

**Métodos de Autenticação Legacy:**
- `attemptLogin($credentials)` - Autentica com username/password
- `loginForSpa($credentials)` - Login para SPA com criação de token
- `logout()` - Termina sessão revogando token

### TokenManager

**Localização:** `Modules/Common/Guard/TokenManager.php` (referenciado em GuardManager)

Gestor especializado para Personal Access Tokens, responsável pela criação, validação e gestão de tokens de acesso.

**Funcionalidades:**
- Criação de tokens com hash SHA-256
- Validação de tokens com verificação de expiração
- Gestão de abilities/scopes por token
- Limpeza automática de tokens expirados
- Actualização de timestamps de último uso

### GuardServiceProvider

**Localização:** `Modules/Common/Guard/GuardServiceProvider.php:13`

Provider responsável pelo registo do sistema Guard no container de Dependency Injection e configuração de middlewares.

**Serviços Registados:**
- `guard.config` - Configuração do sistema
- `guard` - Instância principal do GuardManager
- `guard.token` - TokenManager singleton
- `guard.middleware.auth` - Middleware de autenticação
- `guard.middleware.throttle` - Middleware de rate limiting

**Grupos de Middleware Registados:**
- `guard.api` - Para endpoints de API (auth + throttle + json_response)
- `guard.spa` - Para aplicações SPA (auth + throttle específico)
- `guard.admin` - Para administração (auth + abilities admin)

**Middlewares Globais Opcionais:**
- IP validation - Quando `security.ip_validation` está activo
- Time-based access - Quando `security.time_based_access` está activo
- Token limit - Quando `security.max_tokens_per_user` > 0

## Middlewares Disponíveis

### GuardAuthMiddleware

**Localização:** `Modules/Common/Guard/Middleware/GuardAuthMiddleware.php:11`

Middleware fundamental que verifica a autenticação do utilizador através do sistema Guard.

**Funcionalidade:**
- Chama `Guard::authenticate()` para validar token
- Retorna erro 401 com estrutura JSON padronizada se não autenticado
- Permite prosseguir no pipeline se autenticação for bem-sucedida

**Estrutura de Resposta de Erro:**
```json
{
  "success": false,
  "error": {
    "message": "No valid authentication token provided",
    "code": 401,
    "type": "authentication_error"
  },
  "meta": {
    "timestamp": 1234567890,
    "datetime": "2024-01-01 12:00:00"
  }
}
```

### GuardThrottleMiddleware

**Localização:** `Modules/Common/Guard/Middleware/GuardThrottleMiddleware.php:10`

Middleware avançado de rate limiting com suporte a diferentes tipos de limitação.

**Características:**
- Rate limiting por utilizador (se autenticado) ou IP (se anónimo)
- Configuração diferenciada por tipo (api, spa, auth_attempts)
- Headers informativos sobre limites e estado actual
- Integração com sistema de cache para persistência

**Tipos de Rate Limiting:**
- `api` - 60 requests/minuto (padrão)
- `spa` - 120 requests/minuto (limite mais alto)
- `auth_attempts` - 5 tentativas de login/15 minutos

**Headers de Resposta:**
- `X-RateLimit-Limit` - Limite máximo configurado
- `X-RateLimit-Remaining` - Tentativas restantes
- `X-RateLimit-Reset` - Timestamp para reset do limite
- `Retry-After` - Segundos até próxima tentativa (em caso de limite excedido)

### GuardAbilitiesMiddleware

**Localização:** `Modules/Common/Guard/Middleware/GuardAbilitiesMiddleware.php:10`

Middleware de autorização que verifica abilities/scopes do token actual.

**Funcionalidade:**
- Verifica se utilizador está autenticado
- Valida se token tem abilities requeridas via `tokenCanAny()`
- Suporte a múltiplas abilities (OR logic)
- Respostas detalhadas sobre abilities em falta

**Uso Típico:**
```php
Route::get('/admin/users', [UsersController::class, 'index'])
     ->middleware('guard.abilities:admin,user_management');
```

### GuardMiddlewareResolver

**Localização:** `Modules/Common/Guard/Middleware/GuardMiddlewareResolver.php` (referenciado)

Resolver que gere a inicialização automática dos middlewares, fornecendo acesso às instâncias do GuardManager, configuração e cache quando necessário.

## Facades Disponíveis

### GuardFacade

**Localização:** `Modules/Common/Guard/GuardFacade.php:30`

Facade que oferece acesso estático simplificado ao sistema Guard, integrada com o container de DI.

**Métodos Documentados:**
- `user()` - Obtém utilizador autenticado
- `token()` - Obtém token actual
- `check()` / `guest()` - Estado de autenticação
- `id()` - ID do utilizador actual
- `createToken()` / `createSpaToken()` - Criação de tokens
- `revokeCurrentToken()` / `revokeAllTokens()` - Gestão de tokens
- `tokens()` - Lista tokens do utilizador
- `tokenCan()` / `tokenCanAny()` - Verificação de abilities
- `loginForSpa()` / `logout()` - Gestão de sessão
- `authenticate()` / `attemptLogin()` - Autenticação
- `can()` - Verificação de permissões
- `getTokenManager()` - Acesso ao TokenManager

**Comparação de Uso:**

```php
// Uso directo (tradicional)
$guardManager = app('guard');
$user = $guardManager->user();

// Uso via Facade (recomendado)
use Og\Modules\Common\Guard\GuardFacade as Guard;
$user = Guard::user();

// Verificações comuns
if (Guard::check()) {
    $userId = Guard::id();
    $canManageUsers = Guard::tokenCan('user_management');
}
```

## Configuração

### Arquivo de Configuração

**Localização:** `Modules/Common/Config/guard.php`

Configuração completa do sistema Guard com todas as opções disponíveis.

**Secções Principais:**

#### Personal Access Tokens
```php
'personal_access_tokens' => [
    'table' => 'personal_access_tokens',
    'expires_in' => null,              // null = nunca expira
    'hash_algorithm' => 'sha256',
    'token_length' => 40,
]
```

#### SPA Authentication
```php
'spa' => [
    'expires_in' => 60 * 24,          // 24 horas
    'refresh_threshold' => 60 * 2,     // 2 horas antes da expiração
    'cookie_name' => 'guard_token',
    'cookie_secure' => true,
    'cookie_http_only' => true,
]
```

#### Rate Limiting
```php
'rate_limiting' => [
    'enabled' => true,
    'api' => ['attempts' => 60, 'decay_minutes' => 1],
    'spa' => ['attempts' => 120, 'decay_minutes' => 1],
    'auth_attempts' => ['attempts' => 5, 'decay_minutes' => 15],
]
```

#### Configuração de Utilizadores
```php
'user' => [
    'table' => 'empreg',              // Tabela legacy do OfficeGest
    'id_column' => 'codempr',
    'active_column' => 'web_is_active_c',
    'active_value' => 1,
]
```

## Padrões e Integrações

### Integração com Sistema Legacy

O Guard integra-se nativamente com o sistema de utilizadores legacy do OfficeGest:
- Utiliza tabela `empreg` para dados de utilizadores
- Integra-se com classe `User` existente
- Mantém compatibilidade com sistema de permissões legacy
- Oferece ponte entre autenticação tradicional e baseada em tokens

### Integração com Container DI

Registo automático via `GuardServiceProvider` permite:
- Resolução automática de dependências
- Singletons para performance optimizada
- Suporte completo para testing e mocking
- Configuração flexível via container

### Middleware Pipeline

Sistema de middleware integrado oferece:
- Pipeline configurável de autenticação/autorização
- Grupos de middleware pré-definidos para diferentes cenários
- Middlewares globais opcionais baseados em configuração
- Rate limiting avançado com cache persistente

## Exemplos de Uso Real

### Autenticação Básica para API

```php
// Rota protegida por autenticação básica
Route::middleware('guard.auth')->group(function() {
    Route::get('/api/vendas', [VendasController::class, 'index']);
    Route::post('/api/vendas', [VendasController::class, 'store']);
});

// Verificação dentro do controller
public function index()
{
    if (Guard::guest()) {
        return Response::json(['error' => 'Authentication required'], 401);
    }

    $userId = Guard::id();
    // Lógica do controller
}
```

### Sistema SPA com Autenticação

```php
// Login para SPA
Route::post('/auth/spa-login', function(Request $request) {
    $credentials = $request->only(['username', 'password']);

    $token = Guard::loginForSpa($credentials);

    if (!$token) {
        return Response::json(['error' => 'Invalid credentials'], 401);
    }

    return Response::json([
        'token' => $token->getPlainTextToken(),
        'expires_at' => $token->getExpiresAt(),
        'user' => Guard::user()->toArray()
    ]);
});

// Rotas SPA protegidas
Route::middleware('guard.spa')->group(function() {
    Route::get('/spa/dashboard', [DashboardController::class, 'spa']);
    Route::get('/spa/profile', [ProfileController::class, 'show']);
});
```

### API com Abilities/Scopes

```php
// Criação de token com abilities específicas
$adminToken = Guard::createToken($userId, 'admin-access', [
    'user_management',
    'system_config',
    'reports_advanced'
]);

$readOnlyToken = Guard::createToken($userId, 'readonly-access', [
    'vendas.read',
    'stocks.read'
]);

// Rotas com verificação de abilities
Route::middleware('guard.abilities:admin')->group(function() {
    Route::get('/admin/users', [AdminController::class, 'users']);
    Route::post('/admin/config', [AdminController::class, 'updateConfig']);
});

Route::middleware('guard.abilities:vendas.read,stocks.read')->group(function() {
    Route::get('/api/vendas', [VendasController::class, 'index']);
    Route::get('/api/stocks', [StocksController::class, 'index']);
});
```

### Rate Limiting Avançado

```php
// Diferentes limites para diferentes endpoints
Route::middleware('guard.throttle:api')->group(function() {
    Route::get('/api/public', [PublicController::class, 'index']);
});

Route::middleware('guard.throttle:spa')->group(function() {
    Route::get('/spa/data', [SpaController::class, 'data']);
});

// Verificação programática de rate limits
public function heavyOperation()
{
    $remaining = app('guard.middleware.throttle')->getRemainingAttempts();

    if ($remaining < 5) {
        return Response::json([
            'warning' => 'Approaching rate limit',
            'remaining' => $remaining
        ]);
    }

    // Operação pesada
}
```

### Gestão de Tokens

```php
// Listar tokens do utilizador
public function userTokens()
{
    $tokens = Guard::tokens();

    return Response::json([
        'tokens' => array_map(function($token) {
            return [
                'id' => $token->getId(),
                'name' => $token->getName(),
                'abilities' => $token->getAbilities(),
                'last_used_at' => $token->getLastUsedAt(),
                'expires_at' => $token->getExpiresAt()
            ];
        }, $tokens)
    ]);
}

// Revogar token específico
public function revokeToken(Request $request)
{
    $tokenId = $request->get('token_id');

    if ($tokenId === Guard::token()->getId()) {
        // Revogar token actual
        Guard::revokeCurrentToken();
        return Response::json(['message' => 'Current token revoked']);
    }

    // Revogar outro token do utilizador
    $tokenManager = Guard::getTokenManager();
    $success = $tokenManager->deleteToken($tokenId);

    return Response::json(['success' => $success]);
}

// Logout completo (todos os dispositivos)
public function logoutEverywhere()
{
    Guard::revokeAllTokens();
    return Response::json(['message' => 'Logged out from all devices']);
}
```

## Operações de Segurança e Manutenção

### Limpeza de Tokens Expirados

```php
// Comando de limpeza (pode ser executado via cron)
public function pruneTokens()
{
    $removed = Guard::pruneExpiredTokens();

    return "Removed {$removed} expired tokens";
}

// Agendamento automático
$scheduler->command('guard:prune-tokens')->daily();
```

### Validações de Segurança

**Extração de Tokens:**
- Suporte a Bearer tokens via header Authorization
- Fallback para query parameter configurável
- Suporte a cookies para SPAs com httpOnly e secure flags

**Validações Aplicadas:**
- Hash SHA-256 para todos os tokens armazenados
- Verificação de expiração automática
- Validação de abilities por token
- Rate limiting por utilizador/IP

### Configurações de Segurança Avançadas

```php
// Configurações via environment variables
GUARD_MAX_TOKENS_PER_USER=50        // Limite de tokens por utilizador
GUARD_IP_VALIDATION=true            // Validação de IP
GUARD_TIME_BASED_ACCESS=true        // Controlo de acesso por horário
```

**Funcionalidades de Segurança:**
- **IP Validation**: Restringe acesso a IPs específicos
- **Time-based Access**: Controla acesso por horários
- **Token Limits**: Limita número de tokens por utilizador
- **Automatic Pruning**: Limpeza automática de tokens expirados

O sistema Guard oferece uma solução completa e moderna de autenticação e autorização, mantendo compatibilidade com o sistema legacy do OfficeGest enquanto adiciona funcionalidades avançadas de segurança e gestão de tokens.