You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.0 KiB
72 lines
2.0 KiB
<?php |
|
|
|
namespace App\Http\Middleware; |
|
|
|
use App\Services\AuditLogService; |
|
use Closure; |
|
use Illuminate\Http\Request; |
|
use Symfony\Component\HttpFoundation\Response; |
|
|
|
class WebAuditMiddleware |
|
{ |
|
private const MUTATING = ['POST', 'PUT', 'PATCH', 'DELETE']; |
|
|
|
public function __construct( |
|
private readonly AuditLogService $audit |
|
) { |
|
} |
|
|
|
public function handle(Request $request, Closure $next): Response |
|
{ |
|
$actorUsername = $request->session()->get('ldap_username'); |
|
|
|
$response = $next($request); |
|
|
|
if (! in_array($request->method(), self::MUTATING, true)) { |
|
return $response; |
|
} |
|
|
|
if ($actorUsername === null && ! $request->session()->get('ldap_authenticated')) { |
|
return $response; |
|
} |
|
|
|
if ($request->attributes->get('audit_skip')) { |
|
return $response; |
|
} |
|
|
|
if ($request->attributes->get('audit_logged')) { |
|
return $response; |
|
} |
|
|
|
$routeName = $request->route()?->getName(); |
|
if ($routeName === null) { |
|
return $response; |
|
} |
|
|
|
if ($response->getStatusCode() >= 400) { |
|
return $response; |
|
} |
|
|
|
$this->audit->log( |
|
action: $this->audit->crudActionFromRoute($request), |
|
actorType: 'web', |
|
actorUsername: is_string($actorUsername) ? $actorUsername : null, |
|
resource: $this->audit->resourceFromRequest($request), |
|
request: $request, |
|
metadata: $this->audit->enrichMetadata( |
|
$request, |
|
array_merge( |
|
[ |
|
'route' => $routeName, |
|
'http_method' => $request->method(), |
|
'crud' => $this->audit->crudVerb($request->method()), |
|
'status' => $response->getStatusCode(), |
|
], |
|
$request->attributes->get('audit_metadata', []) |
|
) |
|
) |
|
); |
|
|
|
return $response; |
|
} |
|
}
|
|
|