151 lines
4.2 KiB
PHP
Executable File
151 lines
4.2 KiB
PHP
Executable File
<?php
|
|
|
|
/**
|
|
* SysCMS - Content Management System
|
|
*
|
|
* Copyright (c) 2025 Marco Costa
|
|
* All rights reserved.
|
|
*
|
|
* Author: Marco Costa
|
|
* Email: contato@syspanel.com.br
|
|
* Project: SysCMS
|
|
*
|
|
* This software is licensed, not sold.
|
|
* Permission is granted to use this software
|
|
* subject to the terms of the SysCMS Commercial License.
|
|
*
|
|
* Redistribution, sublicensing, resale, or
|
|
* disclosure of this software, in whole or in part,
|
|
* is strictly prohibited without prior written permission.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
|
*/
|
|
|
|
namespace App\Middlewares;
|
|
|
|
use Closure;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
|
|
class PermissionMiddleware
|
|
{
|
|
/**
|
|
* Handle an incoming request.
|
|
*
|
|
* @param Request $request
|
|
* @param Closure $next
|
|
* @param string $permission
|
|
* @return mixed
|
|
*/
|
|
public function handle(Request $request, Closure $next, string $permission)
|
|
{
|
|
$user = $this->getCurrentUser();
|
|
|
|
if (!$user) {
|
|
return $this->unauthorizedResponse($request);
|
|
}
|
|
|
|
// Check if user has the required permission
|
|
if (!$this->userHasPermission($user, $permission)) {
|
|
return $this->forbiddenResponse($request, $permission);
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
/**
|
|
* Get current authenticated user.
|
|
*
|
|
* @return \Modules\Auth\Models\User|null
|
|
*/
|
|
protected function getCurrentUser(): ?\Modules\Auth\Models\User
|
|
{
|
|
if (!isset($_SESSION['user_id'])) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return \Modules\Auth\Models\User::find($_SESSION['user_id']);
|
|
} catch (\Exception $e) {
|
|
error_log("Error loading user: " . $e->getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if user has the required permission.
|
|
*
|
|
* @param \Modules\Auth\Models\User $user
|
|
* @param string $permission
|
|
* @return bool
|
|
*/
|
|
protected function userHasPermission(\Modules\Auth\Models\User $user, string $permission): bool
|
|
{
|
|
return $user->hasPermission($permission);
|
|
}
|
|
|
|
/**
|
|
* Create unauthorized response.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
protected function unauthorizedResponse(Request $request): Response
|
|
{
|
|
if ($this->expectsJson($request)) {
|
|
return new JsonResponse([
|
|
'success' => false,
|
|
'message' => __('auth.unauthenticated'),
|
|
'timestamp' => time()
|
|
], 401);
|
|
}
|
|
|
|
return new Response('', 302, [
|
|
'Location' => url('/login')
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Create forbidden response.
|
|
*
|
|
* @param Request $request
|
|
* @param string $permission
|
|
* @return Response
|
|
*/
|
|
protected function forbiddenResponse(Request $request, string $permission): Response
|
|
{
|
|
$message = __('auth.permission_denied', ['permission' => $permission]);
|
|
|
|
if ($this->expectsJson($request)) {
|
|
return new JsonResponse([
|
|
'success' => false,
|
|
'message' => $message,
|
|
'permission' => $permission,
|
|
'timestamp' => time()
|
|
], 403);
|
|
}
|
|
|
|
// For web requests, show error page
|
|
try {
|
|
$view = new \Kernel\View();
|
|
// We can pass the message to the view if we update the template
|
|
return new Response($view->render('errors/403.twig'), 403);
|
|
} catch (\Throwable $e) {
|
|
return new Response($message, 403);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if request expects JSON response.
|
|
*
|
|
* @param Request $request
|
|
* @return bool
|
|
*/
|
|
protected function expectsJson(Request $request): bool
|
|
{
|
|
return $request->headers->get('Accept') === 'application/json' ||
|
|
$request->headers->get('Content-Type') === 'application/json' ||
|
|
str_contains($request->getPathInfo(), '/api/');
|
|
}
|
|
} |