93 lines
2.9 KiB
PHP
93 lines
2.9 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace MintyPHP\Support;
|
||
|
|
|
||
|
|
use MintyPHP\Router;
|
||
|
|
use MintyPHP\Service\PermissionService;
|
||
|
|
use MintyPHP\Service\TenantService;
|
||
|
|
use MintyPHP\Service\AuthService;
|
||
|
|
use MintyPHP\Http\Request;
|
||
|
|
|
||
|
|
class Guard
|
||
|
|
{
|
||
|
|
private const TENANT_REFRESH_INTERVAL = 60;
|
||
|
|
|
||
|
|
public static function requireLogin(string $redirect = 'login'): void
|
||
|
|
{
|
||
|
|
if (!isset($_SESSION['user'])) {
|
||
|
|
Flash::error('Login required', 'login', 'login_required');
|
||
|
|
Router::redirect($redirect);
|
||
|
|
}
|
||
|
|
self::refreshTenantContext();
|
||
|
|
if (!empty($_SESSION['no_active_tenant'])) {
|
||
|
|
AuthService::logout();
|
||
|
|
Flash::error('No active tenant assigned', 'login', 'no_active_tenant');
|
||
|
|
Router::redirect($redirect);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static function validateCurrentTenant(): void
|
||
|
|
{
|
||
|
|
$currentTenant = $_SESSION['current_tenant'] ?? null;
|
||
|
|
if (!$currentTenant || empty($currentTenant['id'])) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$tenantId = (int) $currentTenant['id'];
|
||
|
|
$tenant = TenantService::findById($tenantId);
|
||
|
|
if ($tenant) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Current tenant was deleted, refresh session data
|
||
|
|
$userId = (int) ($_SESSION['user']['id'] ?? 0);
|
||
|
|
if ($userId > 0) {
|
||
|
|
AuthService::loadTenantDataIntoSession($userId);
|
||
|
|
} else {
|
||
|
|
unset($_SESSION['current_tenant']);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static function refreshTenantContext(): void
|
||
|
|
{
|
||
|
|
$userId = (int) ($_SESSION['user']['id'] ?? 0);
|
||
|
|
if ($userId <= 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
$last = (int) ($_SESSION['tenant_context_refreshed_at'] ?? 0);
|
||
|
|
$now = time();
|
||
|
|
if ($last > 0 && ($now - $last) < self::TENANT_REFRESH_INTERVAL) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
AuthService::loadTenantDataIntoSession($userId);
|
||
|
|
$_SESSION['tenant_context_refreshed_at'] = $now;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function requirePermission(string $permissionKey, string $redirect = 'admin'): void
|
||
|
|
{
|
||
|
|
self::requireLogin();
|
||
|
|
self::validateCurrentTenant();
|
||
|
|
$userId = (int) ($_SESSION['user']['id'] ?? 0);
|
||
|
|
if (!$userId || !PermissionService::userHas($userId, $permissionKey)) {
|
||
|
|
Flash::error('Permission denied', $redirect, 'permission_denied');
|
||
|
|
Router::redirect($redirect);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static function requirePermissionOrForbidden(string $permissionKey): void
|
||
|
|
{
|
||
|
|
self::requireLogin();
|
||
|
|
self::validateCurrentTenant();
|
||
|
|
$userId = (int) ($_SESSION['user']['id'] ?? 0);
|
||
|
|
if (!$userId || !PermissionService::userHas($userId, $permissionKey)) {
|
||
|
|
if (Request::wantsJson()) {
|
||
|
|
http_response_code(403);
|
||
|
|
header('Content-Type: application/json; charset=utf-8');
|
||
|
|
echo json_encode(['error' => 'forbidden']);
|
||
|
|
exit;
|
||
|
|
}
|
||
|
|
Router::redirect('error/forbidden');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|