First Commit
This commit is contained in:
Executable
+151
@@ -0,0 +1,151 @@
|
||||
<?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/');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user