diff --git a/lib/Controller/AlbumsController.php b/lib/Controller/AlbumsController.php index 6bda003d..bd7acf30 100644 --- a/lib/Controller/AlbumsController.php +++ b/lib/Controller/AlbumsController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -36,8 +37,12 @@ class AlbumsController extends ApiBase public function albums(int $t = 0): JSONResponse { $user = $this->userSession->getUser(); - if (null === $user || !$this->albumsIsEnabled()) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + if (null === $user) { + return Errors::NotLoggedIn(); + } + + if (!$this->albumsIsEnabled()) { + return Errors::NotEnabled('Albums'); } // Run actual query @@ -73,20 +78,24 @@ class AlbumsController extends ApiBase public function download(string $name = ''): JSONResponse { $user = $this->userSession->getUser(); - if (null === $user || !$this->albumsIsEnabled()) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + if (null === $user) { + return Errors::NotLoggedIn(); + } + + if (!$this->albumsIsEnabled()) { + return Errors::NotEnabled('Albums'); } // Get album $album = $this->timelineQuery->getAlbumIfAllowed($user->getUID(), $name); if (null === $album) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound("album {$name}"); } // Get files $files = $this->timelineQuery->getAlbumFiles((int) $album['album_id']); if (empty($files)) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound("zero files in album {$name}"); } // Get download handle diff --git a/lib/Controller/ApiBase.php b/lib/Controller/ApiBase.php index 4d3206b5..360c1088 100644 --- a/lib/Controller/ApiBase.php +++ b/lib/Controller/ApiBase.php @@ -26,13 +26,13 @@ namespace OCA\Memories\Controller; use OCA\Memories\AppInfo\Application; use OCA\Memories\Db\TimelineQuery; use OCA\Memories\Db\TimelineRoot; +use OCA\Memories\Errors; use OCA\Memories\Exif; use OCA\Memories\Util; use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataDisplayResponse; -use OCP\AppFramework\Http\JSONResponse; use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IRootFolder; @@ -358,7 +358,7 @@ class ApiBase extends Controller } } - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('preview from list'); } /** diff --git a/lib/Controller/ArchiveController.php b/lib/Controller/ArchiveController.php index 8eb9c791..3d65c551 100644 --- a/lib/Controller/ArchiveController.php +++ b/lib/Controller/ArchiveController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\Errors; use OCA\Memories\Exif; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -41,7 +42,7 @@ class ArchiveController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse(['message' => 'Not logged in'], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } $uid = $user->getUID(); $userFolder = $this->rootFolder->getUserFolder($uid); @@ -49,13 +50,13 @@ class ArchiveController extends ApiBase // Check for permissions and get numeric Id $file = $userFolder->getById((int) $id); if (0 === \count($file)) { - return new JSONResponse(['message' => 'No such file'], Http::STATUS_NOT_FOUND); + return Errors::NotFound("file id {$id}"); } $file = $file[0]; // Check if user has permissions if (!$file->isUpdateable()) { - return new JSONResponse(['message' => 'Cannot update this file'], Http::STATUS_FORBIDDEN); + return Errors::ForbiddenFileUpdate($file->getName()); } // Create archive folder in the root of the user's configured timeline diff --git a/lib/Controller/DaysController.php b/lib/Controller/DaysController.php index cedb4910..1cfd31ce 100644 --- a/lib/Controller/DaysController.php +++ b/lib/Controller/DaysController.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; use OCA\Memories\Db\TimelineRoot; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -42,7 +43,7 @@ class DaysController extends ApiBase try { $uid = $this->getUID(); } catch (\Exception $e) { - return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Get the folder to show @@ -51,7 +52,7 @@ class DaysController extends ApiBase try { $root = $this->getRequestRoot(); } catch (\Exception $e) { - return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND); + return Errors::Generic($e); } // Run actual query @@ -120,7 +121,7 @@ class DaysController extends ApiBase try { $root = $this->getRequestRoot(); } catch (\Exception $e) { - return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND); + return Errors::Generic($e); } // Convert to actual dayIds if month view @@ -166,7 +167,7 @@ class DaysController extends ApiBase { $id = $this->request->getParam('body_ids'); if (null === $id) { - return new JSONResponse([], Http::STATUS_BAD_REQUEST); + return Errors::MissingParameter('body_ids'); } return $this->day($id); diff --git a/lib/Controller/DownloadController.php b/lib/Controller/DownloadController.php index 4d82bf6e..8add29a1 100644 --- a/lib/Controller/DownloadController.php +++ b/lib/Controller/DownloadController.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; use bantu\IniGetWrapper\IniGetWrapper; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; use OCP\ISession; @@ -46,7 +47,7 @@ class DownloadController extends ApiBase // Get ids from body $files = $this->request->getParam('files'); if (null === $files || !\is_array($files)) { - return new JSONResponse([], Http::STATUS_BAD_REQUEST); + return Errors::MissingParameter('files'); } // Return id @@ -89,8 +90,9 @@ class DownloadController extends ApiBase $session->remove($key); if (null === $info) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('handle'); } + $name = $info[0].'-'.date('YmdHis'); $fileIds = $info[1]; @@ -101,7 +103,7 @@ class DownloadController extends ApiBase // Check if we have any valid ids if (0 === \count($fileIds)) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('file IDs'); } // Download single file @@ -124,9 +126,7 @@ class DownloadController extends ApiBase { $file = $this->getUserFile($fileid); if (null === $file) { - return new JSONResponse([ - 'message' => 'File not found', - ], Http::STATUS_NOT_FOUND); + return Errors::NotFoundFile($fileid); } // Get the owner's root folder diff --git a/lib/Controller/ImageController.php b/lib/Controller/ImageController.php index ee279e78..6e3c7a4b 100644 --- a/lib/Controller/ImageController.php +++ b/lib/Controller/ImageController.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; use OCA\Memories\AppInfo\Application; +use OCA\Memories\Errors; use OCA\Memories\Exif; use OCP\AppFramework\Http; use OCP\AppFramework\Http\FileDisplayResponse; @@ -49,16 +50,12 @@ class ImageController extends ApiBase string $mode = 'fill' ) { if (-1 === $id || 0 === $x || 0 === $y) { - return new JSONResponse([ - 'message' => 'Invalid parameters', - ], Http::STATUS_BAD_REQUEST); + return Errors::MissingParameter('id, x, y'); } $file = $this->getUserFile($id); if (!$file) { - return new JSONResponse([ - 'message' => 'File not found', - ], Http::STATUS_NOT_FOUND); + return Errors::NotFoundFile($id); } try { @@ -70,9 +67,9 @@ class ImageController extends ApiBase return $response; } catch (\OCP\Files\NotFoundException $e) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('preview'); } catch (\InvalidArgumentException $e) { - return new JSONResponse([], Http::STATUS_BAD_REQUEST); + return Errors::Generic($e); } } @@ -187,7 +184,7 @@ class ImageController extends ApiBase ): JSONResponse { $file = $this->getUserFile((int) $id); if (!$file) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFoundFile($id); } // Get the image info @@ -229,12 +226,12 @@ class ImageController extends ApiBase { $file = $this->getUserFile((int) $id); if (!$file) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFoundFile($id); } // Check if user has permissions if (!$file->isUpdateable()) { - return new JSONResponse([], Http::STATUS_FORBIDDEN); + return Errors::ForbiddenFileUpdate($file->getName()); } // Check for end-to-end encryption @@ -253,7 +250,7 @@ class ImageController extends ApiBase try { Exif::setFileExif($file, $raw); } catch (\Exception $e) { - return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR); + return Errors::Generic($e); } return new JSONResponse([], Http::STATUS_OK); @@ -274,13 +271,13 @@ class ImageController extends ApiBase { $file = $this->getUserFile((int) $id); if (!$file) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFoundFile($id); } // Check if valid image $mimetype = $file->getMimeType(); if (!\in_array($mimetype, Application::IMAGE_MIMES, true)) { - return new JSONResponse([], Http::STATUS_FORBIDDEN); + return Errors::ForbiddenFileUpdate($file->getName()); } /** @var string Blob of image */ diff --git a/lib/Controller/MapController.php b/lib/Controller/MapController.php index 597f49f9..7c311cee 100644 --- a/lib/Controller/MapController.php +++ b/lib/Controller/MapController.php @@ -23,7 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; -use OCP\AppFramework\Http; +use OCA\Memories\Errors; use OCP\AppFramework\Http\JSONResponse; class MapController extends ApiBase @@ -39,7 +39,7 @@ class MapController extends ApiBase try { $root = $this->getRequestRoot(); } catch (\Exception $e) { - return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // Make sure we have bounds and zoom level @@ -47,7 +47,7 @@ class MapController extends ApiBase $bounds = $this->request->getParam('bounds'); $zoomLevel = $this->request->getParam('zoom'); if (!$bounds || !$zoomLevel || !is_numeric($zoomLevel)) { - return new JSONResponse(['message' => 'Invalid parameters'], Http::STATUS_PRECONDITION_FAILED); + return Errors::MissingParameter('bounds or zoom'); } // A tweakable parameter to determine the number of boxes in the map @@ -75,7 +75,7 @@ class MapController extends ApiBase return new JSONResponse($clusters); } catch (\Exception $e) { - return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR); + return Errors::Generic($e); } } } diff --git a/lib/Controller/OtherController.php b/lib/Controller/OtherController.php index bee050c6..0e7f8444 100644 --- a/lib/Controller/OtherController.php +++ b/lib/Controller/OtherController.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; use OCA\Memories\AppInfo\Application; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\StreamResponse; @@ -44,7 +45,7 @@ class OtherController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Make sure not running in read-only mode diff --git a/lib/Controller/PeopleController.php b/lib/Controller/PeopleController.php index d52a9211..7e729177 100644 --- a/lib/Controller/PeopleController.php +++ b/lib/Controller/PeopleController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataDisplayResponse; use OCP\AppFramework\Http\DataResponse; @@ -40,18 +41,18 @@ class PeopleController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check faces enabled for this user if (!$this->recognizeIsEnabled()) { - return new JSONResponse(['message' => 'Recognize app not enabled or not v3+.'], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('Recognize'); } // If this isn't the timeline folder then things aren't going to work $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // Run actual query @@ -75,25 +76,25 @@ class PeopleController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check faces enabled for this user if (!$this->recognizeIsEnabled()) { - return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('Recognize'); } // Get folder to search for $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // Run actual query $detections = $this->timelineQuery->getPeopleRecognizePreview($root, $id); if (null === $detections || 0 === \count($detections)) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('detections'); } return $this->getPreviewResponse($detections, $user, 1.5); @@ -108,18 +109,18 @@ class PeopleController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check if face recognition is installed and enabled for this user if (!$this->facerecognitionIsInstalled()) { - return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('Face Recognition'); } // If this isn't the timeline folder then things aren't going to work $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // If the user has recognition disabled, just returns an empty response. @@ -155,18 +156,18 @@ class PeopleController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check if face recognition is installed and enabled for this user if (!$this->facerecognitionIsInstalled()) { - return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('Face Recognition'); } // Get folder to search for $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // If the user has facerecognition disabled, just returns an empty response. @@ -179,7 +180,7 @@ class PeopleController extends ApiBase $detections = $this->timelineQuery->getFaceRecognitionPreview($root, $currentModel, $id); if (null === $detections || 0 === \count($detections)) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('detections'); } return $this->getPreviewResponse($detections, $user, 1.8); @@ -242,7 +243,7 @@ class PeopleController extends ApiBase // Make sure the preview is valid if (null === $image) { - return new DataResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('preview'); } // Set quality and make progressive diff --git a/lib/Controller/PlacesController.php b/lib/Controller/PlacesController.php index 46174f0f..44ddd4f4 100644 --- a/lib/Controller/PlacesController.php +++ b/lib/Controller/PlacesController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -37,18 +38,18 @@ class PlacesController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check tags enabled for this user if (!$this->placesIsEnabled()) { - return new JSONResponse(['message' => 'Places not enabled'], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('places'); } // If this isn't the timeline folder then things aren't going to work $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // Run actual query @@ -68,24 +69,24 @@ class PlacesController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check tags enabled for this user if (!$this->placesIsEnabled()) { - return new JSONResponse(['message' => 'Places not enabled'], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('places'); } // If this isn't the timeline folder then things aren't going to work $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // Run actual query $list = $this->timelineQuery->getPlacePreviews($id, $root); if (null === $list || 0 === \count($list)) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NotFound('previews'); } shuffle($list); diff --git a/lib/Controller/ShareController.php b/lib/Controller/ShareController.php index 0d51e6ed..74c86bfe 100644 --- a/lib/Controller/ShareController.php +++ b/lib/Controller/ShareController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -40,9 +41,7 @@ class ShareController extends ApiBase { $file = $this->getNodeByIdOrPath($id, $path); if (!$file) { - return new JSONResponse([ - 'message' => 'File not found', - ], Http::STATUS_FORBIDDEN); + return Errors::Forbidden('file'); } /** @var \OCP\Share\IManager $shareManager */ @@ -50,9 +49,7 @@ class ShareController extends ApiBase $shares = $shareManager->getSharesBy($this->getUID(), \OCP\Share\IShare::TYPE_LINK, $file, true, 50, 0); if (empty($shares)) { - return new JSONResponse([ - 'message' => 'No external links found', - ], Http::STATUS_NOT_FOUND); + return Errors::NotFound('external links'); } $links = array_map([$this, 'makeShareResponse'], $shares); @@ -72,9 +69,7 @@ class ShareController extends ApiBase { $file = $this->getNodeByIdOrPath($id, $path); if (!$file) { - return new JSONResponse([ - 'message' => 'You are not allowed to share this file', - ], Http::STATUS_FORBIDDEN); + return Errors::Forbidden('You are not allowed to share this file'); } /** @var \OCP\Share\IManager $shareManager */ @@ -101,9 +96,7 @@ class ShareController extends ApiBase { $uid = $this->getUID(); if (!$uid) { - return new JSONResponse([ - 'message' => 'You are not logged in', - ], Http::STATUS_FORBIDDEN); + return Errors::NotLoggedIn(); } /** @var \OCP\Share\IManager $shareManager */ @@ -112,9 +105,7 @@ class ShareController extends ApiBase $share = $shareManager->getShareById($id); if ($share->getSharedBy() !== $uid) { - return new JSONResponse([ - 'message' => 'You are not the owner of this share', - ], Http::STATUS_FORBIDDEN); + return Errors::Forbidden('You are not the owner of this share'); } $shareManager->deleteShare($share); diff --git a/lib/Controller/TagsController.php b/lib/Controller/TagsController.php index ad244384..a847e3e3 100644 --- a/lib/Controller/TagsController.php +++ b/lib/Controller/TagsController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\Errors; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -37,18 +38,18 @@ class TagsController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check tags enabled for this user if (!$this->tagsIsEnabled()) { - return new JSONResponse(['message' => 'Tags not enabled for user'], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('Tags'); } // If this isn't the timeline folder then things aren't going to work $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // Run actual query @@ -70,18 +71,18 @@ class TagsController extends ApiBase { $user = $this->userSession->getUser(); if (null === $user) { - return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotLoggedIn(); } // Check tags enabled for this user if (!$this->tagsIsEnabled()) { - return new JSONResponse(['message' => 'Tags not enabled for user'], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('Tags'); } // If this isn't the timeline folder then things aren't going to work $root = $this->getRequestRoot(); if ($root->isEmpty()) { - return new JSONResponse([], Http::STATUS_NOT_FOUND); + return Errors::NoRequestRoot(); } // Run actual query @@ -106,20 +107,18 @@ class TagsController extends ApiBase { // Check tags enabled for this user if (!$this->tagsIsEnabled()) { - return new JSONResponse(['message' => 'Tags not enabled for user'], Http::STATUS_PRECONDITION_FAILED); + return Errors::NotEnabled('Tags'); } // Check the user is allowed to edit the file $file = $this->getUserFile($id); if (null === $file) { - return new JSONResponse([ - 'message' => 'File not found', - ], Http::STATUS_NOT_FOUND); + return Errors::NotFoundFile($id); } // Check the user is allowed to edit the file if (!$file->isUpdateable() || !($file->getPermissions() & \OCP\Constants::PERMISSION_UPDATE)) { - return new JSONResponse(['message' => 'Cannot update this file'], Http::STATUS_FORBIDDEN); + return Errors::ForbiddenFileUpdate($file->getName()); } // Get mapper from tags to objects diff --git a/lib/Controller/VideoController.php b/lib/Controller/VideoController.php index 44872962..01a08d13 100644 --- a/lib/Controller/VideoController.php +++ b/lib/Controller/VideoController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace OCA\Memories\Controller; +use OCA\Memories\Errors; use OCA\Memories\Exif; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataDisplayResponse; @@ -44,39 +45,35 @@ class VideoController extends ApiBase { // Make sure not running in read-only mode if (false !== $this->config->getSystemValue('memories.vod.disable', 'UNSET')) { - return new JSONResponse(['message' => 'Transcoding disabled'], Http::STATUS_FORBIDDEN); + return Errors::Forbidden('Transcoding disabled'); } // Check client identifier is 8 characters or more if (\strlen($client) < 8) { - return new JSONResponse(['message' => 'Invalid client identifier'], Http::STATUS_BAD_REQUEST); + return Errors::MissingParameter('client (invalid)'); } // Get file $file = $this->getUserFile($fileid); - if (!$file) { - return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND); - } - - if (!$file->isReadable()) { - return new JSONResponse(['message' => 'File not readable'], Http::STATUS_FORBIDDEN); + if (!$file || !$file->isReadable()) { + return Errors::NotFoundFile($fileid); } // Local files only for now if (!$file->getStorage()->isLocal()) { - return new JSONResponse(['message' => 'External storage not supported'], Http::STATUS_FORBIDDEN); + return Errors::Forbidden('External storage not supported'); } // Get file path $path = $file->getStorage()->getLocalFile($file->getInternalPath()); if (!$path || !file_exists($path)) { - return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND); + return Errors::NotFound('local file path'); } // Check if file starts with temp dir $tmpDir = sys_get_temp_dir(); if (0 === strpos($path, $tmpDir)) { - return new JSONResponse(['message' => 'File is in temp dir!'], Http::STATUS_NOT_FOUND); + return Errors::Forbidden('files in temp directory not supported'); } // Request and check data was received @@ -93,7 +90,7 @@ class VideoController extends ApiBase $msg = 'Transcode failed: '.$e->getMessage(); $this->logger->error($msg, ['app' => 'memories']); - return new JSONResponse(['message' => $msg], Http::STATUS_INTERNAL_SERVER_ERROR); + return Errors::Generic($e); } // The response was already streamed, so we have nothing to do here @@ -117,12 +114,12 @@ class VideoController extends ApiBase ) { $file = $this->getUserFile($fileid); if (null === $file) { - return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND); + return Errors::NotFoundFile($fileid); } // Check file liveid if (!$liveid) { - return new JSONResponse(['message' => 'Live ID not provided'], Http::STATUS_BAD_REQUEST); + return Errors::MissingParameter('liveid'); } // Response data @@ -144,13 +141,13 @@ class VideoController extends ApiBase try { // Get trailer $blob = Exif::getBinaryExifProp($path, '-trailer'); } catch (\Exception $e) { - return new JSONResponse(['message' => 'Trailer not found'], Http::STATUS_NOT_FOUND); + return Errors::NotFound('file trailer'); } } elseif ('self__embeddedvideo' === $liveid) { try { // Get embedded video file $blob = Exif::getBinaryExifProp($path, '-EmbeddedVideoFile'); } catch (\Exception $e) { - return new JSONResponse(['message' => 'Embedded video not found'], Http::STATUS_NOT_FOUND); + return Errors::NotFound('embedded video'); } } elseif (str_starts_with($liveid, 'self__traileroffset=')) { // Remove prefix @@ -165,14 +162,14 @@ class VideoController extends ApiBase // Get stored video file (Apple MOV) $lp = $this->timelineQuery->getLivePhoto($fileid); if (!$lp || $lp['liveid'] !== $liveid) { - return new JSONResponse(['message' => 'Live ID not found'], Http::STATUS_NOT_FOUND); + return Errors::NotFound('live video entry'); } // Get and return file $liveFileId = (int) $lp['fileid']; $files = $this->rootFolder->getById($liveFileId); if (0 === \count($files)) { - return new JSONResponse(['message' => 'Live file not found'], Http::STATUS_NOT_FOUND); + return Errors::NotFound('live video file'); } $liveFile = $files[0]; @@ -191,7 +188,7 @@ class VideoController extends ApiBase // Data not found if (!$blob) { - return new JSONResponse(['message' => 'Live file not found'], Http::STATUS_NOT_FOUND); + return Errors::NotFound('live video data'); } // Transcode video if allowed diff --git a/lib/Errors.php b/lib/Errors.php new file mode 100644 index 00000000..7ff23783 --- /dev/null +++ b/lib/Errors.php @@ -0,0 +1,74 @@ + $e->getMessage(), + ], $status); + } + + public static function NotLoggedIn(): Http\Response + { + return new DataResponse([ + 'message' => 'User not logged in', + ], Http::STATUS_PRECONDITION_FAILED); + } + + public static function NotEnabled(string $app): Http\Response + { + return new DataResponse([ + 'message' => "{$app} app not enabled or not v3+.", + ], Http::STATUS_PRECONDITION_FAILED); + } + + public static function NoRequestRoot(): Http\Response + { + return new DataResponse([ + 'message' => 'Request root could not be determined', + ], Http::STATUS_NOT_FOUND); + } + + public static function NotFound(string $ctx): Http\Response + { + return new DataResponse([ + 'message' => "Not found ({$ctx})", + ], Http::STATUS_NOT_FOUND); + } + + public static function NotFoundFile($identifier): Http\Response + { + return new DataResponse([ + 'message' => "File not found ({$identifier})", + ], Http::STATUS_NOT_FOUND); + } + + public static function Forbidden(string $ctx): Http\Response + { + return new DataResponse([ + 'message' => "Forbidden ({$ctx})", + ], Http::STATUS_FORBIDDEN); + } + + public static function ForbiddenFileUpdate(string $name): Http\Response + { + return new DataResponse([ + 'message' => "Forbidden ({$name} cannot be updated)", + ], Http::STATUS_FORBIDDEN); + } + + public static function MissingParameter(string $name): Http\Response + { + return new DataResponse([ + 'message' => "Missing parameter ({$name})", + ], Http::STATUS_BAD_REQUEST); + } +}