Add ListEvidence method and improve error handling in UploadAttachment

This commit is contained in:
netkas 2025-06-04 13:34:27 -04:00
parent dd71f06434
commit d8354871a4
Signed by: netkas
GPG key ID: 4D8629441B76E4CC
2 changed files with 58 additions and 17 deletions

View file

@ -19,9 +19,6 @@
class UploadAttachment extends RequestHandler class UploadAttachment extends RequestHandler
{ {
// Maximum number of files allowed in the storage directory
private const MAX_FILES = 10000;
/** /**
* @inheritDoc * @inheritDoc
* @throws RequestException * @throws RequestException
@ -87,8 +84,7 @@
// Validate file upload status // Validate file upload status
if (!isset($file['error']) || $file['error'] !== UPLOAD_ERR_OK) if (!isset($file['error']) || $file['error'] !== UPLOAD_ERR_OK)
{ {
$errorMessage = self::getUploadErrorMessage($file['error'] ?? -1); throw new RequestException(self::getUploadErrorMessage($file['error'] ?? -1), 400);
throw new RequestException($errorMessage);
} }
// Validate file exists and is readable // Validate file exists and is readable
@ -103,7 +99,7 @@
// Check for symlinks/hardlinks in tmp_name // Check for symlinks/hardlinks in tmp_name
if (is_link($file['tmp_name'])) if (is_link($file['tmp_name']))
{ {
throw new RequestException('Invalid file upload (symbolic link detected)'); throw new RequestException('Invalid file upload (symbolic link detected)', 400);
} }
// Additional check for path traversal attempts // Additional check for path traversal attempts
@ -119,21 +115,14 @@
{ {
if (!mkdir($storagePath, 0750, true)) if (!mkdir($storagePath, 0750, true))
{ {
throw new RequestException('Storage directory could not be created'); throw new RequestException('Storage directory could not be created', 500);
} }
} }
// Verify storage directory permissions // Verify storage directory permissions
if (!is_writable($storagePath)) if (!is_writable($storagePath))
{ {
throw new RequestException('Storage directory is not writable'); throw new RequestException('Storage directory is not writable', 500);
}
// Limit number of files in storage directory (prevent DoS)
$fileCount = iterator_count(new FilesystemIterator($storagePath, FilesystemIterator::SKIP_DOTS));
if ($fileCount >= self::MAX_FILES)
{
throw new RequestException('Storage limit reached');
} }
// Generate a strong random UUID for the file // Generate a strong random UUID for the file
@ -147,7 +136,7 @@
if (!move_uploaded_file($file['tmp_name'], $tempDestination)) if (!move_uploaded_file($file['tmp_name'], $tempDestination))
{ {
throw new RequestException('Failed to move uploaded file'); throw new RequestException('Failed to move uploaded file', 500);
} }
try try
@ -158,7 +147,7 @@
// Move to final destination // Move to final destination
if (!rename($tempDestination, $destinationPath)) if (!rename($tempDestination, $destinationPath))
{ {
throw new RequestException('Failed to finalize file upload'); throw new RequestException('Failed to finalize file upload', 500);
} }
// Create a record in the database // Create a record in the database

View file

@ -0,0 +1,52 @@
<?php
namespace FederationServer\Methods\Evidence;
use FederationServer\Classes\Configuration;
use FederationServer\Classes\Managers\EvidenceManager;
use FederationServer\Classes\Managers\OperatorManager;
use FederationServer\Classes\RequestHandler;
use FederationServer\Exceptions\DatabaseOperationException;
use FederationServer\Exceptions\RequestException;
use FederationServer\FederationServer;
class ListEvidence extends RequestHandler
{
/**
* @inheritDoc
*/
public static function handleRequest(): void
{
$authenticatedOperator = FederationServer::getAuthenticatedOperator(false);
if(!Configuration::getServerConfiguration()->isPublicEvidence() && $authenticatedOperator === null)
{
throw new RequestException('Unauthorized: You must be authenticated to list evidence', 401);
}
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListEvidenceMaxItems());
$page = (int) (FederationServer::getParameter('page') ?? 1);
if($limit < 1 || $limit > Configuration::getServerConfiguration()->getListEvidenceMaxItems())
{
$limit = Configuration::getServerConfiguration()->getListEvidenceMaxItems();
}
if($page < 1)
{
$page = 1;
}
try
{
$operators = EvidenceManager::getEvidenceRecords($limit, $page);
}
catch (DatabaseOperationException $e)
{
throw new RequestException('Internal Server Error: Unable to retrieve operators', 500, $e);
}
$result = array_map(fn($op) => $op->toArray(), $operators);
self::successResponse($result);
}
}