Refactor error messages in RequestException and improve authentication checks across multiple files
Some checks are pending
CI / release (push) Waiting to run
CI / debug (push) Waiting to run
CI / check-phpunit (push) Waiting to run
CI / check-phpdoc (push) Waiting to run
CI / generate-phpdoc (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / release-documentation (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions

This commit is contained in:
netkas 2025-06-06 15:27:09 -04:00
parent 1eb68dcd8d
commit 885553121d
Signed by: netkas
GPG key ID: 4D8629441B76E4CC
35 changed files with 509 additions and 130 deletions

View file

@ -0,0 +1,341 @@
<?php
namespace FederationServer\Classes\Enums;
enum HttpResponseCode : int
{
/**
* This interim response indicates that the client should continue the request or ignore the response if
* the request is already finished.
*/
case CONTINUE = 100;
/**
* This code is sent in response to an Upgrade request header from the client and indicates the protocol the server is switching to.
*/
case SWITCHING_PROTOCOLS = 101;
/**
* (Deprecated) Used in WebDAV contexts to indicate that a request has been received by the server, but no status was available at the time of the response.
*/
case PROCESSING = 102;
/**
* This status code is primarily intended to be used with the Link header, letting the user agent start preloading resources while the server prepares a response or preconnect to an origin from which the page will need resources.
*/
case EARLY_HINTS = 103;
// --- Successful responses ---
/**
* The request succeeded. The result and meaning of "success" depends on the HTTP method.
*/
case OK = 200;
/**
* The request succeeded, and a new resource was created as a result. Typically sent after POST or some PUT requests.
*/
case CREATED = 201;
/**
* The request has been received but not yet acted upon. Intended for cases where another process or server handles the request, or for batch processing.
*/
case ACCEPTED = 202;
/**
* The returned metadata is not exactly the same as is available from the origin server, but is collected from a local or a third-party copy.
*/
case NON_AUTHORITATIVE_INFORMATION = 203;
/**
* There is no content to send for this request, but the headers are useful. The user agent may update its cached headers for this resource with the new ones.
*/
case NO_CONTENT = 204;
/**
* Tells the user agent to reset the document which sent this request.
*/
case RESET_CONTENT = 205;
/**
* Used in response to a range request when the client has requested a part or parts of a resource.
*/
case PARTIAL_CONTENT = 206;
/**
* (WebDAV) Conveys information about multiple resources, for situations where multiple status codes might be appropriate.
*/
case MULTI_STATUS = 207;
/**
* (WebDAV) Used inside a <dav:propstat> response element to avoid repeatedly enumerating the internal members of multiple bindings to the same collection.
*/
case ALREADY_REPORTED = 208;
/**
* (HTTP Delta encoding) The server has fulfilled a GET request for the resource, and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
*/
case IM_USED = 226;
// --- Redirection messages ---
/**
* The request has more than one possible response and the user agent or user should choose one of them.
*/
case MULTIPLE_CHOICES = 300;
/**
* The URL of the requested resource has been changed permanently. The new URL is given in the response.
*/
case MOVED_PERMANENTLY = 301;
/**
* The URI of requested resource has been changed temporarily. Further changes in the URI might be made in the future.
*/
case FOUND = 302;
/**
* The server sent this response to direct the client to get the requested resource at another URI with a GET request.
*/
case SEE_OTHER = 303;
/**
* Used for caching purposes. It tells the client that the response has not been modified.
*/
case NOT_MODIFIED = 304;
/**
* (Deprecated) Defined in a previous version of the HTTP specification to indicate that a requested response must be accessed by a proxy.
*/
case USE_PROXY = 305;
/**
* This response code is no longer used; but is reserved.
*/
case UNUSED = 306;
/**
* The server sends this response to direct the client to get the requested resource at another URI with the same method that was used in the prior request.
*/
case TEMPORARY_REDIRECT = 307;
/**
* The resource is now permanently located at another URI, specified by the Location response header.
*/
case PERMANENT_REDIRECT = 308;
// --- Client error responses ---
/**
* The server cannot or will not process the request due to something that is perceived to be a client error.
*/
case BAD_REQUEST = 400;
/**
* The client must authenticate itself to get the requested response.
*/
case UNAUTHORIZED = 401;
/**
* The initial purpose of this code was for digital payment systems, however this status code is rarely used and no standard convention exists.
*/
case PAYMENT_REQUIRED = 402;
/**
* The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource.
*/
case FORBIDDEN = 403;
/**
* The server cannot find the requested resource.
*/
case NOT_FOUND = 404;
/**
* The request method is known by the server but is not supported by the target resource.
*/
case METHOD_NOT_ALLOWED = 405;
/**
* The web server, after performing server-driven content negotiation, doesn't find any content that conforms to the criteria given by the user agent.
*/
case NOT_ACCEPTABLE = 406;
/**
* Similar to 401 Unauthorized but authentication is needed to be done by a proxy.
*/
case PROXY_AUTHENTICATION_REQUIRED = 407;
/**
* This response is sent on an idle connection by some servers, even without any previous request by the client.
*/
case REQUEST_TIMEOUT = 408;
/**
* The request conflicts with the current state of the server.
*/
case CONFLICT = 409;
/**
* The requested content has been permanently deleted from server, with no forwarding address.
*/
case GONE = 410;
/**
* Server rejected the request because the Content-Length header field is not defined and the server requires it.
*/
case LENGTH_REQUIRED = 411;
/**
* In conditional requests, the client has indicated preconditions in its headers which the server does not meet.
*/
case PRECONDITION_FAILED = 412;
/**
* The request body is larger than limits defined by server.
*/
case CONTENT_TOO_LARGE = 413;
/**
* The URI requested by the client is longer than the server is willing to interpret.
*/
case URI_TOO_LONG = 414;
/**
* The media format of the requested data is not supported by the server.
*/
case UNSUPPORTED_MEDIA_TYPE = 415;
/**
* The ranges specified by the Range header field in the request cannot be fulfilled.
*/
case RANGE_NOT_SATISFIABLE = 416;
/**
* The expectation indicated by the Expect request header field cannot be met by the server.
*/
case EXPECTATION_FAILED = 417;
/**
* The server refuses the attempt to brew coffee with a teapot.
*/
case IM_A_TEAPOT = 418;
/**
* The request was directed at a server that is not able to produce a response.
*/
case MISDIRECTED_REQUEST = 421;
/**
* (WebDAV) The request was well-formed but was unable to be followed due to semantic errors.
*/
case UNPROCESSABLE_CONTENT = 422;
/**
* (WebDAV) The resource that is being accessed is locked.
*/
case LOCKED = 423;
/**
* (WebDAV) The request failed due to failure of a previous request.
*/
case FAILED_DEPENDENCY = 424;
/**
* Indicates that the server is unwilling to risk processing a request that might be replayed.
*/
case TOO_EARLY = 425;
/**
* The server refuses to perform the request using the current protocol but might be willing to do so after the client upgrades to a different protocol.
*/
case UPGRADE_REQUIRED = 426;
/**
* The origin server requires the request to be conditional.
*/
case PRECONDITION_REQUIRED = 428;
/**
* The user has sent too many requests in a given amount of time (rate limiting).
*/
case TOO_MANY_REQUESTS = 429;
/**
* The server is unwilling to process the request because its header fields are too large.
*/
case REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
/**
* The user agent requested a resource that cannot legally be provided, such as a web page censored by a government.
*/
case UNAVAILABLE_FOR_LEGAL_REASONS = 451;
// --- Server error responses ---
/**
* The server has encountered a situation it does not know how to handle.
*/
case INTERNAL_SERVER_ERROR = 500;
/**
* The request method is not supported by the server and cannot be handled.
*/
case NOT_IMPLEMENTED = 501;
/**
* The server, while working as a gateway to get a response needed to handle the request, got an invalid response.
*/
case BAD_GATEWAY = 502;
/**
* The server is not ready to handle the request. Common causes are a server that is down for maintenance or that is overloaded.
*/
case SERVICE_UNAVAILABLE = 503;
/**
* The server is acting as a gateway and cannot get a response in time.
*/
case GATEWAY_TIMEOUT = 504;
/**
* The HTTP version used in the request is not supported by the server.
*/
case HTTP_VERSION_NOT_SUPPORTED = 505;
/**
* The server has an internal configuration error: during content negotiation, the chosen variant is configured to engage in content negotiation itself.
*/
case VARIANT_ALSO_NEGOTIATES = 506;
/**
* (WebDAV) The method could not be performed on the resource because the server is unable to store the representation needed to successfully complete the request.
*/
case INSUFFICIENT_STORAGE = 507;
/**
* (WebDAV) The server detected an infinite loop while processing the request.
*/
case LOOP_DETECTED = 508;
/**
* The client request declares an HTTP Extension (RFC 2774) that should be used to process the request, but the extension is not supported.
*/
case NOT_EXTENDED = 510;
/**
* Indicates that the client needs to authenticate to gain network access.
*/
case NETWORK_AUTHENTICATION_REQUIRED = 511;
/**
* Converts the enum case to a string suitable for use as an error prefix.
* For example, if the enum case is `NOT_FOUND`, it will return "Not Found".
*
* @return string The name of the enum case formatted as a human-readable string.
*/
public function getErrorPrefix(): string
{
return ucwords(strtolower(str_replace('_', ' ', $this->name)));
}
}

View file

@ -42,7 +42,7 @@
self::$decodedContent = json_decode(self::$inputContent, true); self::$decodedContent = json_decode(self::$inputContent, true);
if (json_last_error() !== JSON_ERROR_NONE) if (json_last_error() !== JSON_ERROR_NONE)
{ {
throw new RequestException('Invalid JSON input: ' . json_last_error_msg(), 400); throw new RequestException(json_last_error_msg(), 400);
} }
} }
@ -172,6 +172,24 @@
*/ */
protected static function throwableResponse(Throwable $e): void protected static function throwableResponse(Throwable $e): void
{ {
$prefixMessage = match($e->getCode())
{
400 => 'Bad Request',
401 => 'Unauthorized',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
409 => 'Conflict',
422 => 'Unprocessable Entity',
429 => 'Too Many Requests',
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout: ',
default => 'Request Error: ',
};
http_response_code($e->getCode() ?: 500); http_response_code($e->getCode() ?: 500);
self::returnHeaders(); self::returnHeaders();
print(json_encode([ print(json_encode([

View file

@ -2,7 +2,35 @@
namespace FederationServer\Exceptions; namespace FederationServer\Exceptions;
class RequestException extends \Exception use Exception;
{ use FederationServer\Classes\Enums\HttpResponseCode;
use Throwable;
class RequestException extends Exception
{
/**
* The HTTP status code for the error.
*
* @param string $message The error message.
* @param int|HttpResponseCode $code The HTTP status code (default is 500 Internal Server Error).
* @param Throwable|null $previous
*/
public function __construct(string $message = "", int|HttpResponseCode $code=HttpResponseCode::INTERNAL_SERVER_ERROR, ?Throwable $previous = null)
{
// Construct with error code '0' always, as it will be set later.
parent::__construct($message, 0, $previous);
// If the code is an integer, convert it to HttpResponseCode if possible.
if(is_int($code))
{
$code = HttpResponseCode::tryFrom($code);
if($code === null)
{
$code = HttpResponseCode::INTERNAL_SERVER_ERROR;
}
}
$this->code = $code->value;
$this->message = sprintf('%s: %s', $code->getErrorPrefix(), $message);
}
} }

View file

@ -25,7 +25,7 @@
// Ensure the authenticated operator has permission to delete operators. // Ensure the authenticated operator has permission to delete operators.
if(!$authenticatedOperator->canManageBlacklist()) if(!$authenticatedOperator->canManageBlacklist())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to delete attachments', 403); throw new RequestException('Insufficient permissions to delete attachments', 403);
} }
if(!preg_match('#^/attachment/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/attachment/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches))
@ -61,7 +61,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to create operator', 500, $e); throw new RequestException('Unable to create operator', 500, $e);
} }
// Respond with the UUID of the newly created operator. // Respond with the UUID of the newly created operator.

View file

@ -54,12 +54,12 @@
{ {
if($authenticatedOperator === null) if($authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to view confidential evidence', 401); throw new RequestException('You must be authenticated to view confidential evidence', 401);
} }
if(!$authenticatedOperator->canManageBlacklist()) if(!$authenticatedOperator->canManageBlacklist())
{ {
throw new RequestException('Unauthorized: Insufficient Permissions to view confidential evidence', 401); throw new RequestException('Insufficient Permissions to view confidential evidence', 401);
} }
} }
} }

View file

@ -152,13 +152,13 @@
{ {
// If database insertion fails, remove the file to maintain consistency // If database insertion fails, remove the file to maintain consistency
@unlink($destinationPath); @unlink($destinationPath);
throw new RequestException('Internal Server Error: Unable to create file attachment record', 500, $e); throw new RequestException('Unable to create file attachment record', 500, $e);
} }
catch (Throwable $e) catch (Throwable $e)
{ {
// Handle any other unexpected errors // Handle any other unexpected errors
@unlink($destinationPath); @unlink($destinationPath);
throw new RequestException('Internal Server Error', 500, $e); throw new RequestException('Unable to upload file attachment to server', 500, $e);
} }
finally finally
{ {

View file

@ -19,7 +19,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: Public audit logs are disabled and no operator is authenticated', 403); throw new RequestException('Public audit logs are disabled and no operator is authenticated', 403);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListAuditLogsMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListAuditLogsMaxItems());
@ -56,7 +56,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve audit logs', 500, $e); throw new RequestException('Unable to retrieve audit logs', 500, $e);
} }
} }

View file

@ -20,18 +20,18 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: Public audit logs are disabled and no operator is authenticated', 403); throw new RequestException('Public audit logs are disabled and no operator is authenticated', 403);
} }
if(!preg_match('#^/audit/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/audit/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Audit UUID is required', 400); throw new RequestException('Audit UUID is required', 400);
} }
$entryUuid = $matches[1]; $entryUuid = $matches[1];
if(!$entryUuid || !Validate::uuid($entryUuid)) if(!$entryUuid || !Validate::uuid($entryUuid))
{ {
throw new RequestException('Bad Request: Invalid Audit UUID', 400); throw new RequestException('Invalid Audit UUID', 400);
} }
try try
@ -46,7 +46,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve audit log', 500, $e); throw new RequestException('Unable to retrieve audit log', 500, $e);
} }
} }
} }

View file

@ -4,7 +4,6 @@
use FederationServer\Classes\Configuration; use FederationServer\Classes\Configuration;
use FederationServer\Classes\Managers\BlacklistManager; use FederationServer\Classes\Managers\BlacklistManager;
use FederationServer\Classes\Managers\EvidenceManager;
use FederationServer\Classes\RequestHandler; use FederationServer\Classes\RequestHandler;
use FederationServer\Exceptions\DatabaseOperationException; use FederationServer\Exceptions\DatabaseOperationException;
use FederationServer\Exceptions\RequestException; use FederationServer\Exceptions\RequestException;
@ -20,7 +19,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(false); $authenticatedOperator = FederationServer::getAuthenticatedOperator(false);
if(!Configuration::getServerConfiguration()->isBlacklistPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isBlacklistPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to list blacklist records', 401); throw new RequestException('You must be authenticated to list blacklist records', 401);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListBlacklistMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListBlacklistMaxItems());
@ -42,7 +41,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve blacklist records', 500, $e); throw new RequestException('Unable to retrieve blacklist records', 500, $e);
} }
self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $blacklistRecords)); self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $blacklistRecords));

View file

@ -19,32 +19,32 @@
$authenticatedOperator = FederationServer::requireAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
if(!$authenticatedOperator->canManageBlacklist()) if(!$authenticatedOperator->canManageBlacklist())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to manage entities', 401); throw new RequestException('Insufficient permissions to manage entities', 401);
} }
if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
$entityUuid = $matches[1]; $entityUuid = $matches[1];
if(!$entityUuid || !Validate::uuid($entityUuid)) if(!$entityUuid || !Validate::uuid($entityUuid))
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
try try
{ {
if(!EntitiesManager::entityExistsByUuid($entityUuid)) if(!EntitiesManager::entityExistsByUuid($entityUuid))
{ {
throw new RequestException('Not Found: Entity does not exist', 404); throw new RequestException('Entity does not exist', 404);
} }
EntitiesManager::deleteEntity($entityUuid); EntitiesManager::deleteEntity($entityUuid);
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to delete entity', 500, $e); throw new RequestException('Unable to delete entity', 500, $e);
} }
self::successResponse(); self::successResponse();

View file

@ -20,18 +20,18 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isEntitiesPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isEntitiesPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to view entity records', 401); throw new RequestException('You must be authenticated to view entity records', 401);
} }
if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
$entityUuid = $matches[1]; $entityUuid = $matches[1];
if(!$entityUuid || !Validate::uuid($entityUuid)) if(!$entityUuid || !Validate::uuid($entityUuid))
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
@ -41,7 +41,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve entity', 500, $e); throw new RequestException('Unable to retrieve entity', 500, $e);
} }
self::successResponse($entityRecord->toArray()); self::successResponse($entityRecord->toArray());

View file

@ -19,7 +19,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isEntitiesPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isEntitiesPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to view entity records', 401); throw new RequestException('You must be authenticated to view entity records', 401);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListEntitiesMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListEntitiesMaxItems());
@ -41,7 +41,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve operators', 500, $e); throw new RequestException('Unable to retrieve operators', 500, $e);
} }
$result = array_map(fn($op) => $op->toArray(), $operators); $result = array_map(fn($op) => $op->toArray(), $operators);

View file

@ -20,18 +20,18 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: Public audit logs are disabled and no operator is authenticated', 403); throw new RequestException('Public audit logs are disabled and no operator is authenticated', 403);
} }
if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})/audit$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})/audit$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
$entityUuid = $matches[1]; $entityUuid = $matches[1];
if(!$entityUuid) if(!$entityUuid)
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListAuditLogsMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListAuditLogsMaxItems());
@ -62,7 +62,7 @@
{ {
if(!EntitiesManager::entityExistsByUuid($entityUuid)) if(!EntitiesManager::entityExistsByUuid($entityUuid))
{ {
throw new RequestException('Not Found: Entity with the specified UUID does not exist', 404); throw new RequestException('Entity with the specified UUID does not exist', 404);
} }
self::successResponse(array_map(fn($log) => $log->toArray(), self::successResponse(array_map(fn($log) => $log->toArray(),
@ -71,7 +71,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve audit logs', 500, $e); throw new RequestException('Unable to retrieve audit logs', 500, $e);
} }
} }
} }

View file

@ -21,7 +21,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isBlacklistPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isBlacklistPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to list blacklist records', 401); throw new RequestException('You must be authenticated to list blacklist records', 401);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListBlacklistMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListBlacklistMaxItems());
@ -39,13 +39,13 @@
if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})/blacklist$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})/blacklist$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
$entityUuid = $matches[1]; $entityUuid = $matches[1];
if(!$entityUuid || !Validate::uuid($entityUuid)) if(!$entityUuid || !Validate::uuid($entityUuid))
{ {
throw new RequestException('Bad Request: a valid entity UUID is required', 400); throw new RequestException('a valid entity UUID is required', 400);
} }
try try
@ -59,7 +59,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve blacklist records from the entity', 500, $e); throw new RequestException('Unable to retrieve blacklist records from the entity', 500, $e);
} }
self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $blacklistRecords)); self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $blacklistRecords));

View file

@ -22,7 +22,7 @@
if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to list evidence', 401); throw new RequestException('You must be authenticated to list evidence', 401);
} }
if($authenticatedOperator !== null) if($authenticatedOperator !== null)
@ -46,13 +46,13 @@
if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})/evidence$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/entities/([a-fA-F0-9\-]{36,})/evidence$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
$entityUuid = $matches[1]; $entityUuid = $matches[1];
if(!$entityUuid) if(!$entityUuid)
{ {
throw new RequestException('Bad Request: Entity UUID is required', 400); throw new RequestException('Entity UUID is required', 400);
} }
try try
@ -60,14 +60,14 @@
$existingEntity = EntitiesManager::getEntityByUuid($entityUuid); $existingEntity = EntitiesManager::getEntityByUuid($entityUuid);
if($existingEntity === null) if($existingEntity === null)
{ {
throw new RequestException('Entity Not Found', 404); throw new RequestException('Entity does not exist', 404);
} }
$evidenceRecords = EvidenceManager::getEvidenceRecords($limit, $page, $includeConfidential); $evidenceRecords = EvidenceManager::getEvidenceRecords($limit, $page, $includeConfidential);
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve evidence', 500, $e); throw new RequestException('Unable to retrieve evidence', 500, $e);
} }
self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $evidenceRecords)); self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $evidenceRecords));

View file

@ -18,7 +18,7 @@
$authenticatedOperator = FederationServer::requireAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
if(!$authenticatedOperator->isClient() && !$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->isClient() && !$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to push entities', 403); throw new RequestException('Insufficient permissions to push entities', 403);
} }
$id = FederationServer::getParameter('id'); $id = FederationServer::getParameter('id');
@ -26,22 +26,22 @@
if(!$id) if(!$id)
{ {
throw new RequestException('Bad Request: Entity ID is required', 400); throw new RequestException('Entity ID is required', 400);
} }
if(strlen($id) > 255) if(strlen($id) > 255)
{ {
throw new RequestException('Bad Request: Entity ID exceeds maximum length of 255 characters', 400); throw new RequestException('Entity ID exceeds maximum length of 255 characters', 400);
} }
if(!is_null($domain) && !filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) if(!is_null($domain) && !filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME))
{ {
throw new RequestException('Bad Request: Invalid domain format', 400); throw new RequestException('Invalid domain format', 400);
} }
if(!is_null($domain) && strlen($domain) > 255) if(!is_null($domain) && strlen($domain) > 255)
{ {
throw new RequestException('Bad Request: Domain exceeds maximum length of 255 characters', 400); throw new RequestException('Domain exceeds maximum length of 255 characters', 400);
} }
try try
@ -57,7 +57,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to register entity', 500, $e); throw new RequestException('Unable to register entity', 500, $e);
} }
self::successResponse($entityUuid); self::successResponse($entityUuid);

View file

@ -19,7 +19,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isEntitiesPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isEntitiesPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to view entity records', 401); throw new RequestException('You must be authenticated to view entity records', 401);
} }
$id = FederationServer::getParameter('id'); $id = FederationServer::getParameter('id');
@ -27,12 +27,12 @@
if(!$id) if(!$id)
{ {
throw new RequestException('Bad Request: Entity ID is required', 400); throw new RequestException('Entity ID is required', 400);
} }
if(!is_null($domain) && !filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)) if(!is_null($domain) && !filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME))
{ {
throw new RequestException('Bad Request: Invalid domain format', 400); throw new RequestException('Invalid domain format', 400);
} }
try try
@ -41,7 +41,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve entity', 500, $e); throw new RequestException('Unable to retrieve entity', 500, $e);
} }
self::successResponse($entity->toArray()); self::successResponse($entity->toArray());

View file

@ -19,7 +19,7 @@
$authenticatedOperator = FederationServer::requireAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
if(!$authenticatedOperator->canManageBlacklist()) if(!$authenticatedOperator->canManageBlacklist())
{ {
throw new RequestException('Forbidden: You do not have permission to delete evidence', 403); throw new RequestException('You do not have permission to delete evidence', 403);
} }
if(!preg_match('#^/evidence/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/evidence/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches))
@ -44,7 +44,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to delete evidence', 500, $e); throw new RequestException('Unable to delete evidence', 500, $e);
} }
self::successResponse(); self::successResponse();

View file

@ -20,7 +20,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to access evidence', 401); throw new RequestException('You must be authenticated to access evidence', 401);
} }
if(!preg_match('#^/evidence/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/evidence/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches))
@ -44,12 +44,12 @@
if($evidenceRecord->isConfidential() && $authenticatedOperator === null) if($evidenceRecord->isConfidential() && $authenticatedOperator === null)
{ {
throw new RequestException('Forbidden: Confidential evidence access is restricted', 403); throw new RequestException('Confidential evidence access is restricted', 403);
} }
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to get evidence', 500, $e); throw new RequestException('Unable to get evidence', 500, $e);
} }
} }
} }

View file

@ -21,7 +21,7 @@
if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to list evidence', 401); throw new RequestException('You must be authenticated to list evidence', 401);
} }
if($authenticatedOperator !== null) if($authenticatedOperator !== null)
@ -48,7 +48,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve evidence', 500, $e); throw new RequestException('Unable to retrieve evidence', 500, $e);
} }
self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $evidenceRecords)); self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $evidenceRecords));

View file

@ -20,25 +20,25 @@
$authenticatedOperator = FederationServer::requireAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
if(!$authenticatedOperator->canManageBlacklist()) if(!$authenticatedOperator->canManageBlacklist())
{ {
throw new RequestException('Forbidden: You do not have permission to create evidence', 403); throw new RequestException('You do not have permission to create evidence', 403);
} }
$entityUuid = FederationServer::getParameter('entity_uuid'); $entityUuid = FederationServer::getParameter('entity_uuid');
if(!$entityUuid || !Validate::uuid($entityUuid)) if(!$entityUuid || !Validate::uuid($entityUuid))
{ {
throw new RequestException('Bad Request: Entity UUID is required and must be valid', 400); throw new RequestException('Entity UUID is required and must be valid', 400);
} }
$textContent = FederationServer::getParameter('text_content'); $textContent = FederationServer::getParameter('text_content');
if(!is_null($textContent) && strlen($textContent) > 65535) if(!is_null($textContent) && strlen($textContent) > 65535)
{ {
throw new RequestException('Bad Request: Text content must not exceed 65535 characters', 400); throw new RequestException('Text content must not exceed 65535 characters', 400);
} }
$note = FederationServer::getParameter('note'); $note = FederationServer::getParameter('note');
if(!is_null($note) && strlen($note) > 65535) if(!is_null($note) && strlen($note) > 65535)
{ {
throw new RequestException('Bad Request: Note must not exceed 65535 characters', 400); throw new RequestException('Note must not exceed 65535 characters', 400);
} }
$confidential = false; $confidential = false;
@ -51,14 +51,14 @@
{ {
if(!EntitiesManager::getEntityByUuid($entityUuid)) if(!EntitiesManager::getEntityByUuid($entityUuid))
{ {
throw new RequestException('Not Found: Entity does not exist', 404); throw new RequestException('Entity does not exist', 404);
} }
self::successResponse(EvidenceManager::addEvidence($entityUuid, $authenticatedOperator->getUuid(), $textContent, $note, $confidential)); self::successResponse(EvidenceManager::addEvidence($entityUuid, $authenticatedOperator->getUuid(), $textContent, $note, $confidential));
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Failed to create evidence', 500, $e); throw new RequestException('Failed to create evidence', 500, $e);
} }
} }
} }

View file

@ -18,17 +18,17 @@
*/ */
public static function handleRequest(): void public static function handleRequest(): void
{ {
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
// Ensure the authenticated operator has permission to create new operators. // Ensure the authenticated operator has permission to create new operators.
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to create operators', 403); throw new RequestException('Insufficient permissions to create operators', 403);
} }
if(!FederationServer::getParameter('name')) if(!FederationServer::getParameter('name'))
{ {
throw new RequestException('Bad Request: Operator name is required', 400); throw new RequestException('Operator name is required', 400);
} }
try try
@ -43,8 +43,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error('Database error while creating operator: ' . $e->getMessage(), $e); throw new RequestException('Unable to create operator', 500, $e);
throw new RequestException('Internal Server Error: Unable to create operator', 500, $e);
} }
// Respond with the UUID of the newly created operator. // Respond with the UUID of the newly created operator.

View file

@ -7,6 +7,7 @@
use FederationServer\Classes\Managers\AuditLogManager; use FederationServer\Classes\Managers\AuditLogManager;
use FederationServer\Classes\Managers\OperatorManager; use FederationServer\Classes\Managers\OperatorManager;
use FederationServer\Classes\RequestHandler; use FederationServer\Classes\RequestHandler;
use FederationServer\Classes\Validate;
use FederationServer\Exceptions\DatabaseOperationException; use FederationServer\Exceptions\DatabaseOperationException;
use FederationServer\Exceptions\RequestException; use FederationServer\Exceptions\RequestException;
use FederationServer\FederationServer; use FederationServer\FederationServer;
@ -18,12 +19,12 @@
*/ */
public static function handleRequest(): void public static function handleRequest(): void
{ {
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
// Ensure the authenticated operator has permission to delete operators. // Ensure the authenticated operator has permission to delete operators.
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to delete operators', 403); throw new RequestException('Insufficient permissions to delete operators', 403);
} }
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/delete$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/delete$#', FederationServer::getPath(), $matches))
@ -32,9 +33,9 @@
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
if(!$operatorUuid) if(!$operatorUuid || !Validate::uuid($operatorUuid))
{ {
throw new RequestException('Operator UUID required', 400); throw new RequestException('a valid Operator UUID required', 400);
} }
try try
@ -55,8 +56,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error('Database error while creating operator: ' . $e->getMessage(), $e); throw new RequestException('Unable to create operator', 500, $e);
throw new RequestException('Internal Server Error: Unable to create operator', 500, $e);
} }
// Respond with the UUID of the newly created operator. // Respond with the UUID of the newly created operator.

View file

@ -7,6 +7,7 @@
use FederationServer\Classes\Managers\AuditLogManager; use FederationServer\Classes\Managers\AuditLogManager;
use FederationServer\Classes\Managers\OperatorManager; use FederationServer\Classes\Managers\OperatorManager;
use FederationServer\Classes\RequestHandler; use FederationServer\Classes\RequestHandler;
use FederationServer\Classes\Validate;
use FederationServer\Exceptions\DatabaseOperationException; use FederationServer\Exceptions\DatabaseOperationException;
use FederationServer\Exceptions\RequestException; use FederationServer\Exceptions\RequestException;
use FederationServer\FederationServer; use FederationServer\FederationServer;
@ -18,23 +19,23 @@
*/ */
public static function handleRequest(): void public static function handleRequest(): void
{ {
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
// Ensure the authenticated operator has permission to delete operators. // Ensure the authenticated operator has permission to delete operators.
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to enable/disable operators', 403); throw new RequestException('Insufficient permissions to enable/disable operators', 403);
} }
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/disable$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/disable$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('Operator UUID is required', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
if(!$operatorUuid) if(!$operatorUuid || !Validate::uuid($operatorUuid))
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('a valid Operator UUID is required', 400);
} }
try try
@ -60,8 +61,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error(sprintf('Database error while disablinf the operator: %s', $e->getMessage()), $e); throw new RequestException('Unable to disable operator', 500, $e);
throw new RequestException('Internal Server Error: Unable to disable operator', 500, $e);
} }
// Respond with the UUID of the newly created operator. // Respond with the UUID of the newly created operator.

View file

@ -7,6 +7,7 @@
use FederationServer\Classes\Managers\AuditLogManager; use FederationServer\Classes\Managers\AuditLogManager;
use FederationServer\Classes\Managers\OperatorManager; use FederationServer\Classes\Managers\OperatorManager;
use FederationServer\Classes\RequestHandler; use FederationServer\Classes\RequestHandler;
use FederationServer\Classes\Validate;
use FederationServer\Exceptions\DatabaseOperationException; use FederationServer\Exceptions\DatabaseOperationException;
use FederationServer\Exceptions\RequestException; use FederationServer\Exceptions\RequestException;
use FederationServer\FederationServer; use FederationServer\FederationServer;
@ -18,23 +19,23 @@
*/ */
public static function handleRequest(): void public static function handleRequest(): void
{ {
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::requireAuthenticatedOperator();
// Ensure the authenticated operator has permission to delete operators. // Ensure the authenticated operator has permission to delete operators.
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to enable/disable operators', 403); throw new RequestException('Insufficient permissions to enable/disable operators', 403);
} }
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/enable$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/enable$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('Operator UUID is required', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
if(!$operatorUuid) if(!$operatorUuid || !Validate::uuid($operatorUuid))
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('a valid operator UUID is required', 400);
} }
try try
@ -60,8 +61,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error(sprintf('Database error while enabling the operator: %s', $e->getMessage()), $e); throw new RequestException('Unable to enable operator', 500, $e);
throw new RequestException('Internal Server Error: Unable to enable operator', 500, $e);
} }
// Respond with the UUID of the newly created operator. // Respond with the UUID of the newly created operator.

View file

@ -17,8 +17,7 @@
*/ */
public static function handleRequest(): void public static function handleRequest(): void
{ {
$authenticatedOperator = FederationServer::getAuthenticatedOperator(false); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Operator UUID required', 405); throw new RequestException('Operator UUID required', 405);
@ -40,8 +39,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error('Database error while getting operator: ' . $e->getMessage(), $e); throw new RequestException('Unable to get operator', 500, $e);
throw new RequestException('Internal Server Error: Unable to get operator', 500, $e);
} }
if($authenticatedOperator?->canManageOperators()) if($authenticatedOperator?->canManageOperators())

View file

@ -12,6 +12,6 @@
*/ */
public static function handleRequest(): void public static function handleRequest(): void
{ {
self::successResponse(FederationServer::getAuthenticatedOperator()->toArray()); self::successResponse(FederationServer::requireAuthenticatedOperator()->toArray());
} }
} }

View file

@ -17,21 +17,21 @@
*/ */
public static function handleRequest(): void public static function handleRequest(): void
{ {
$authenticatedOperator = FederationServer::getAuthenticatedOperator(false); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isAuditLogsPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: Public audit logs are disabled and no operator is authenticated', 403); throw new RequestException('Public audit logs are disabled and no operator is authenticated', 403);
} }
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/audit$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/audit$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('Operator UUID is required', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
if(!$operatorUuid) if(!$operatorUuid)
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('Operator UUID is required', 400);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListAuditLogsMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListAuditLogsMaxItems());
@ -64,7 +64,7 @@
{ {
if(!OperatorManager::operatorExists($operatorUuid)) if(!OperatorManager::operatorExists($operatorUuid))
{ {
throw new RequestException('Not Found: Operator with the specified UUID does not exist', 404); throw new RequestException('Operator with the specified UUID does not exist', 404);
} }
self::successResponse(array_map(fn($log) => $log->toArray(), self::successResponse(array_map(fn($log) => $log->toArray(),
@ -73,7 +73,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve audit logs', 500, $e); throw new RequestException('Unable to retrieve audit logs', 500, $e);
} }
} }
} }

View file

@ -21,7 +21,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(false); $authenticatedOperator = FederationServer::getAuthenticatedOperator(false);
if(!Configuration::getServerConfiguration()->isBlacklistPublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isBlacklistPublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to list blacklist records', 401); throw new RequestException('You must be authenticated to list blacklist records', 401);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListBlacklistMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListBlacklistMaxItems());
@ -39,13 +39,13 @@
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/blacklist$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/blacklist$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('Operator UUID is required', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
if(!$operatorUuid || !Validate::uuid($operatorUuid)) if(!$operatorUuid || !Validate::uuid($operatorUuid))
{ {
throw new RequestException('Bad Request: a valid operator UUID is required', 400); throw new RequestException('a valid operator UUID is required', 400);
} }
try try
@ -59,7 +59,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve blacklist records from the operator', 500, $e); throw new RequestException('Unable to retrieve blacklist records from the operator', 500, $e);
} }
self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $blacklistRecords)); self::successResponse(array_map(fn($evidence) => $evidence->toArray(), $blacklistRecords));

View file

@ -22,7 +22,7 @@
if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null) if(!Configuration::getServerConfiguration()->isEvidencePublic() && $authenticatedOperator === null)
{ {
throw new RequestException('Unauthorized: You must be authenticated to list evidence', 401); throw new RequestException('You must be authenticated to list evidence', 401);
} }
if($authenticatedOperator !== null) if($authenticatedOperator !== null)
@ -46,13 +46,13 @@
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/evidence$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/evidence$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('Operator UUID is required', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
if(!$operatorUuid) if(!$operatorUuid)
{ {
throw new RequestException('Bad Request: Operator UUID is required', 400); throw new RequestException('Operator UUID is required', 400);
} }
try try
@ -66,7 +66,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve evidence', 500, $e); throw new RequestException('Unable to retrieve evidence', 500, $e);
} }
$result = array_map(fn($evidence) => $evidence->toArray(), $evidenceRecords); $result = array_map(fn($evidence) => $evidence->toArray(), $evidenceRecords);

View file

@ -19,7 +19,7 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to list operators', 403); throw new RequestException('Insufficient permissions to list operators', 403);
} }
$limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListOperatorsMaxItems()); $limit = (int) (FederationServer::getParameter('limit') ?? Configuration::getServerConfiguration()->getListOperatorsMaxItems());
@ -41,7 +41,7 @@
} }
catch (DatabaseOperationException $e) catch (DatabaseOperationException $e)
{ {
throw new RequestException('Internal Server Error: Unable to retrieve operators', 500, $e); throw new RequestException('Unable to retrieve operators', 500, $e);
} }
$result = array_map(fn($op) => $op->toArray(), $operators); $result = array_map(fn($op) => $op->toArray(), $operators);

View file

@ -20,12 +20,12 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions manage permissions', 403); throw new RequestException('Insufficient permissions manage permissions', 403);
} }
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/manage_blacklist$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/manage_blacklist$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Missing required parameters', 400); throw new RequestException('Missing required parameters', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
@ -33,7 +33,7 @@
if(!Validate::uuid($operatorUuid)) if(!Validate::uuid($operatorUuid))
{ {
throw new RequestException('Bad Request: Invalid operator UUID', 400); throw new RequestException('Invalid operator UUID', 400);
} }
try try
@ -42,8 +42,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error('Database error while managing operator\'s permissions: ' . $e->getMessage(), $e); throw new RequestException('Unable to manage operator\'s permissions', 500, $e);
throw new RequestException('Internal Server Error: Unable to manage operator\'s permissions', 500, $e);
} }
self::successResponse(); self::successResponse();

View file

@ -20,19 +20,19 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions manage permissions', 403); throw new RequestException('Insufficient permissions manage permissions', 403);
} }
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/manage_client$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/manage_client$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Missing required parameters', 400); throw new RequestException('Missing required parameters', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
$enabled = (bool)filter_var(FederationServer::getParameter('enabled'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); $enabled = (bool)filter_var(FederationServer::getParameter('enabled'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
if(!Validate::uuid($operatorUuid)) if(!Validate::uuid($operatorUuid))
{ {
throw new RequestException('Bad Request: Invalid operator UUID', 400); throw new RequestException('Invalid operator UUID', 400);
} }
try try
@ -41,8 +41,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error('Database error while managing operator\'s permissions: ' . $e->getMessage(), $e); throw new RequestException('Unable to manage operator\'s permissions', 500, $e);
throw new RequestException('Internal Server Error: Unable to manage operator\'s permissions', 500, $e);
} }
self::successResponse(); self::successResponse();

View file

@ -20,12 +20,12 @@
$authenticatedOperator = FederationServer::getAuthenticatedOperator(); $authenticatedOperator = FederationServer::getAuthenticatedOperator();
if(!$authenticatedOperator->canManageOperators()) if(!$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions manage permissions', 403); throw new RequestException('Insufficient permissions manage permissions', 403);
} }
if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/manage_operators$#', FederationServer::getPath(), $matches)) if(!preg_match('#^/operators/([a-fA-F0-9\-]{36,})/manage_operators$#', FederationServer::getPath(), $matches))
{ {
throw new RequestException('Bad Request: Missing required parameters', 400); throw new RequestException('Missing required parameters', 400);
} }
$operatorUuid = $matches[1]; $operatorUuid = $matches[1];
@ -33,7 +33,7 @@
if(!Validate::uuid($operatorUuid)) if(!Validate::uuid($operatorUuid))
{ {
throw new RequestException('Bad Request: Invalid operator UUID', 400); throw new RequestException('Invalid operator UUID', 400);
} }
try try
@ -42,8 +42,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error('Database error while managing operator\'s permissions: ' . $e->getMessage(), $e); throw new RequestException('Unable to manage operator\'s permissions', 500, $e);
throw new RequestException('Internal Server Error: Unable to manage operator\'s permissions', 500, $e);
} }
self::successResponse(); self::successResponse();

View file

@ -25,7 +25,7 @@
// Ensure the authenticated operator has permission to refresh other operators' API keys. // Ensure the authenticated operator has permission to refresh other operators' API keys.
if($operatorUuid !== $authenticatedOperator->getUuid() && !$authenticatedOperator->canManageOperators()) if($operatorUuid !== $authenticatedOperator->getUuid() && !$authenticatedOperator->canManageOperators())
{ {
throw new RequestException('Unauthorized: Insufficient permissions to refresh other operators API keys', 403); throw new RequestException('Insufficient permissions to refresh other operators API keys', 403);
} }
} }
else else
@ -39,8 +39,7 @@
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
Logger::log()->error('Database error while refreshing operator\'s API Key: ' . $e->getMessage(), $e); throw new RequestException('Unable to refresh operator\'s API Key', 500, $e);
throw new RequestException('Internal Server Error: Unable to refresh operator\'s API Key', 500, $e);
} }
// Respond with the UUID of the newly created operator. // Respond with the UUID of the newly created operator.