refactor: add errors class

Signed-off-by: Varun Patil <varunpatil@ucla.edu>
pull/504/head
Varun Patil 2023-03-18 10:52:04 -07:00
parent 00e51ef8d4
commit 5f9a299af4
14 changed files with 179 additions and 107 deletions

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
@ -36,8 +37,12 @@ class AlbumsController extends ApiBase
public function albums(int $t = 0): JSONResponse public function albums(int $t = 0): JSONResponse
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user || !$this->albumsIsEnabled()) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
}
if (!$this->albumsIsEnabled()) {
return Errors::NotEnabled('Albums');
} }
// Run actual query // Run actual query
@ -73,20 +78,24 @@ class AlbumsController extends ApiBase
public function download(string $name = ''): JSONResponse public function download(string $name = ''): JSONResponse
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user || !$this->albumsIsEnabled()) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
}
if (!$this->albumsIsEnabled()) {
return Errors::NotEnabled('Albums');
} }
// Get album // Get album
$album = $this->timelineQuery->getAlbumIfAllowed($user->getUID(), $name); $album = $this->timelineQuery->getAlbumIfAllowed($user->getUID(), $name);
if (null === $album) { if (null === $album) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound("album {$name}");
} }
// Get files // Get files
$files = $this->timelineQuery->getAlbumFiles((int) $album['album_id']); $files = $this->timelineQuery->getAlbumFiles((int) $album['album_id']);
if (empty($files)) { if (empty($files)) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound("zero files in album {$name}");
} }
// Get download handle // Get download handle

View File

@ -26,13 +26,13 @@ namespace OCA\Memories\Controller;
use OCA\Memories\AppInfo\Application; use OCA\Memories\AppInfo\Application;
use OCA\Memories\Db\TimelineQuery; use OCA\Memories\Db\TimelineQuery;
use OCA\Memories\Db\TimelineRoot; use OCA\Memories\Db\TimelineRoot;
use OCA\Memories\Errors;
use OCA\Memories\Exif; use OCA\Memories\Exif;
use OCA\Memories\Util; use OCA\Memories\Util;
use OCP\App\IAppManager; use OCP\App\IAppManager;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataDisplayResponse; use OCP\AppFramework\Http\DataDisplayResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Files\File; use OCP\Files\File;
use OCP\Files\Folder; use OCP\Files\Folder;
use OCP\Files\IRootFolder; 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');
} }
/** /**

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Errors;
use OCA\Memories\Exif; use OCA\Memories\Exif;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
@ -41,7 +42,7 @@ class ArchiveController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse(['message' => 'Not logged in'], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
$uid = $user->getUID(); $uid = $user->getUID();
$userFolder = $this->rootFolder->getUserFolder($uid); $userFolder = $this->rootFolder->getUserFolder($uid);
@ -49,13 +50,13 @@ class ArchiveController extends ApiBase
// Check for permissions and get numeric Id // Check for permissions and get numeric Id
$file = $userFolder->getById((int) $id); $file = $userFolder->getById((int) $id);
if (0 === \count($file)) { if (0 === \count($file)) {
return new JSONResponse(['message' => 'No such file'], Http::STATUS_NOT_FOUND); return Errors::NotFound("file id {$id}");
} }
$file = $file[0]; $file = $file[0];
// Check if user has permissions // Check if user has permissions
if (!$file->isUpdateable()) { 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 // Create archive folder in the root of the user's configured timeline

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Db\TimelineRoot; use OCA\Memories\Db\TimelineRoot;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
@ -42,7 +43,7 @@ class DaysController extends ApiBase
try { try {
$uid = $this->getUID(); $uid = $this->getUID();
} catch (\Exception $e) { } catch (\Exception $e) {
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Get the folder to show // Get the folder to show
@ -51,7 +52,7 @@ class DaysController extends ApiBase
try { try {
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
} catch (\Exception $e) { } catch (\Exception $e) {
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND); return Errors::Generic($e);
} }
// Run actual query // Run actual query
@ -120,7 +121,7 @@ class DaysController extends ApiBase
try { try {
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
} catch (\Exception $e) { } catch (\Exception $e) {
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND); return Errors::Generic($e);
} }
// Convert to actual dayIds if month view // Convert to actual dayIds if month view
@ -166,7 +167,7 @@ class DaysController extends ApiBase
{ {
$id = $this->request->getParam('body_ids'); $id = $this->request->getParam('body_ids');
if (null === $id) { if (null === $id) {
return new JSONResponse([], Http::STATUS_BAD_REQUEST); return Errors::MissingParameter('body_ids');
} }
return $this->day($id); return $this->day($id);

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use bantu\IniGetWrapper\IniGetWrapper; use bantu\IniGetWrapper\IniGetWrapper;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\ISession; use OCP\ISession;
@ -46,7 +47,7 @@ class DownloadController extends ApiBase
// Get ids from body // Get ids from body
$files = $this->request->getParam('files'); $files = $this->request->getParam('files');
if (null === $files || !\is_array($files)) { if (null === $files || !\is_array($files)) {
return new JSONResponse([], Http::STATUS_BAD_REQUEST); return Errors::MissingParameter('files');
} }
// Return id // Return id
@ -89,8 +90,9 @@ class DownloadController extends ApiBase
$session->remove($key); $session->remove($key);
if (null === $info) { if (null === $info) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound('handle');
} }
$name = $info[0].'-'.date('YmdHis'); $name = $info[0].'-'.date('YmdHis');
$fileIds = $info[1]; $fileIds = $info[1];
@ -101,7 +103,7 @@ class DownloadController extends ApiBase
// Check if we have any valid ids // Check if we have any valid ids
if (0 === \count($fileIds)) { if (0 === \count($fileIds)) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound('file IDs');
} }
// Download single file // Download single file
@ -124,9 +126,7 @@ class DownloadController extends ApiBase
{ {
$file = $this->getUserFile($fileid); $file = $this->getUserFile($fileid);
if (null === $file) { if (null === $file) {
return new JSONResponse([ return Errors::NotFoundFile($fileid);
'message' => 'File not found',
], Http::STATUS_NOT_FOUND);
} }
// Get the owner's root folder // Get the owner's root folder

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\AppInfo\Application; use OCA\Memories\AppInfo\Application;
use OCA\Memories\Errors;
use OCA\Memories\Exif; use OCA\Memories\Exif;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\FileDisplayResponse; use OCP\AppFramework\Http\FileDisplayResponse;
@ -49,16 +50,12 @@ class ImageController extends ApiBase
string $mode = 'fill' string $mode = 'fill'
) { ) {
if (-1 === $id || 0 === $x || 0 === $y) { if (-1 === $id || 0 === $x || 0 === $y) {
return new JSONResponse([ return Errors::MissingParameter('id, x, y');
'message' => 'Invalid parameters',
], Http::STATUS_BAD_REQUEST);
} }
$file = $this->getUserFile($id); $file = $this->getUserFile($id);
if (!$file) { if (!$file) {
return new JSONResponse([ return Errors::NotFoundFile($id);
'message' => 'File not found',
], Http::STATUS_NOT_FOUND);
} }
try { try {
@ -70,9 +67,9 @@ class ImageController extends ApiBase
return $response; return $response;
} catch (\OCP\Files\NotFoundException $e) { } catch (\OCP\Files\NotFoundException $e) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound('preview');
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
return new JSONResponse([], Http::STATUS_BAD_REQUEST); return Errors::Generic($e);
} }
} }
@ -187,7 +184,7 @@ class ImageController extends ApiBase
): JSONResponse { ): JSONResponse {
$file = $this->getUserFile((int) $id); $file = $this->getUserFile((int) $id);
if (!$file) { if (!$file) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFoundFile($id);
} }
// Get the image info // Get the image info
@ -229,12 +226,12 @@ class ImageController extends ApiBase
{ {
$file = $this->getUserFile((int) $id); $file = $this->getUserFile((int) $id);
if (!$file) { if (!$file) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFoundFile($id);
} }
// Check if user has permissions // Check if user has permissions
if (!$file->isUpdateable()) { if (!$file->isUpdateable()) {
return new JSONResponse([], Http::STATUS_FORBIDDEN); return Errors::ForbiddenFileUpdate($file->getName());
} }
// Check for end-to-end encryption // Check for end-to-end encryption
@ -253,7 +250,7 @@ class ImageController extends ApiBase
try { try {
Exif::setFileExif($file, $raw); Exif::setFileExif($file, $raw);
} catch (\Exception $e) { } catch (\Exception $e) {
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR); return Errors::Generic($e);
} }
return new JSONResponse([], Http::STATUS_OK); return new JSONResponse([], Http::STATUS_OK);
@ -274,13 +271,13 @@ class ImageController extends ApiBase
{ {
$file = $this->getUserFile((int) $id); $file = $this->getUserFile((int) $id);
if (!$file) { if (!$file) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFoundFile($id);
} }
// Check if valid image // Check if valid image
$mimetype = $file->getMimeType(); $mimetype = $file->getMimeType();
if (!\in_array($mimetype, Application::IMAGE_MIMES, true)) { if (!\in_array($mimetype, Application::IMAGE_MIMES, true)) {
return new JSONResponse([], Http::STATUS_FORBIDDEN); return Errors::ForbiddenFileUpdate($file->getName());
} }
/** @var string Blob of image */ /** @var string Blob of image */

View File

@ -23,7 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCP\AppFramework\Http; use OCA\Memories\Errors;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
class MapController extends ApiBase class MapController extends ApiBase
@ -39,7 +39,7 @@ class MapController extends ApiBase
try { try {
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
} catch (\Exception $e) { } catch (\Exception $e) {
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// Make sure we have bounds and zoom level // Make sure we have bounds and zoom level
@ -47,7 +47,7 @@ class MapController extends ApiBase
$bounds = $this->request->getParam('bounds'); $bounds = $this->request->getParam('bounds');
$zoomLevel = $this->request->getParam('zoom'); $zoomLevel = $this->request->getParam('zoom');
if (!$bounds || !$zoomLevel || !is_numeric($zoomLevel)) { 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 // A tweakable parameter to determine the number of boxes in the map
@ -75,7 +75,7 @@ class MapController extends ApiBase
return new JSONResponse($clusters); return new JSONResponse($clusters);
} catch (\Exception $e) { } catch (\Exception $e) {
return new JSONResponse(['message' => $e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR); return Errors::Generic($e);
} }
} }
} }

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\AppInfo\Application; use OCA\Memories\AppInfo\Application;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\StreamResponse; use OCP\AppFramework\Http\StreamResponse;
@ -44,7 +45,7 @@ class OtherController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Make sure not running in read-only mode // Make sure not running in read-only mode

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataDisplayResponse; use OCP\AppFramework\Http\DataDisplayResponse;
use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataResponse;
@ -40,18 +41,18 @@ class PeopleController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check faces enabled for this user // Check faces enabled for this user
if (!$this->recognizeIsEnabled()) { 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 // If this isn't the timeline folder then things aren't going to work
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// Run actual query // Run actual query
@ -75,25 +76,25 @@ class PeopleController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check faces enabled for this user // Check faces enabled for this user
if (!$this->recognizeIsEnabled()) { if (!$this->recognizeIsEnabled()) {
return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotEnabled('Recognize');
} }
// Get folder to search for // Get folder to search for
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// Run actual query // Run actual query
$detections = $this->timelineQuery->getPeopleRecognizePreview($root, $id); $detections = $this->timelineQuery->getPeopleRecognizePreview($root, $id);
if (null === $detections || 0 === \count($detections)) { if (null === $detections || 0 === \count($detections)) {
return new DataResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound('detections');
} }
return $this->getPreviewResponse($detections, $user, 1.5); return $this->getPreviewResponse($detections, $user, 1.5);
@ -108,18 +109,18 @@ class PeopleController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check if face recognition is installed and enabled for this user // Check if face recognition is installed and enabled for this user
if (!$this->facerecognitionIsInstalled()) { 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 // If this isn't the timeline folder then things aren't going to work
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// If the user has recognition disabled, just returns an empty response. // If the user has recognition disabled, just returns an empty response.
@ -155,18 +156,18 @@ class PeopleController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check if face recognition is installed and enabled for this user // Check if face recognition is installed and enabled for this user
if (!$this->facerecognitionIsInstalled()) { if (!$this->facerecognitionIsInstalled()) {
return new DataResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotEnabled('Face Recognition');
} }
// Get folder to search for // Get folder to search for
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// If the user has facerecognition disabled, just returns an empty response. // 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); $detections = $this->timelineQuery->getFaceRecognitionPreview($root, $currentModel, $id);
if (null === $detections || 0 === \count($detections)) { if (null === $detections || 0 === \count($detections)) {
return new DataResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound('detections');
} }
return $this->getPreviewResponse($detections, $user, 1.8); return $this->getPreviewResponse($detections, $user, 1.8);
@ -242,7 +243,7 @@ class PeopleController extends ApiBase
// Make sure the preview is valid // Make sure the preview is valid
if (null === $image) { if (null === $image) {
return new DataResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound('preview');
} }
// Set quality and make progressive // Set quality and make progressive

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
@ -37,18 +38,18 @@ class PlacesController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check tags enabled for this user // Check tags enabled for this user
if (!$this->placesIsEnabled()) { 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 // If this isn't the timeline folder then things aren't going to work
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// Run actual query // Run actual query
@ -68,24 +69,24 @@ class PlacesController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check tags enabled for this user // Check tags enabled for this user
if (!$this->placesIsEnabled()) { 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 // If this isn't the timeline folder then things aren't going to work
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// Run actual query // Run actual query
$list = $this->timelineQuery->getPlacePreviews($id, $root); $list = $this->timelineQuery->getPlacePreviews($id, $root);
if (null === $list || 0 === \count($list)) { if (null === $list || 0 === \count($list)) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NotFound('previews');
} }
shuffle($list); shuffle($list);

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
@ -40,9 +41,7 @@ class ShareController extends ApiBase
{ {
$file = $this->getNodeByIdOrPath($id, $path); $file = $this->getNodeByIdOrPath($id, $path);
if (!$file) { if (!$file) {
return new JSONResponse([ return Errors::Forbidden('file');
'message' => 'File not found',
], Http::STATUS_FORBIDDEN);
} }
/** @var \OCP\Share\IManager $shareManager */ /** @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); $shares = $shareManager->getSharesBy($this->getUID(), \OCP\Share\IShare::TYPE_LINK, $file, true, 50, 0);
if (empty($shares)) { if (empty($shares)) {
return new JSONResponse([ return Errors::NotFound('external links');
'message' => 'No external links found',
], Http::STATUS_NOT_FOUND);
} }
$links = array_map([$this, 'makeShareResponse'], $shares); $links = array_map([$this, 'makeShareResponse'], $shares);
@ -72,9 +69,7 @@ class ShareController extends ApiBase
{ {
$file = $this->getNodeByIdOrPath($id, $path); $file = $this->getNodeByIdOrPath($id, $path);
if (!$file) { if (!$file) {
return new JSONResponse([ return Errors::Forbidden('You are not allowed to share this file');
'message' => 'You are not allowed to share this file',
], Http::STATUS_FORBIDDEN);
} }
/** @var \OCP\Share\IManager $shareManager */ /** @var \OCP\Share\IManager $shareManager */
@ -101,9 +96,7 @@ class ShareController extends ApiBase
{ {
$uid = $this->getUID(); $uid = $this->getUID();
if (!$uid) { if (!$uid) {
return new JSONResponse([ return Errors::NotLoggedIn();
'message' => 'You are not logged in',
], Http::STATUS_FORBIDDEN);
} }
/** @var \OCP\Share\IManager $shareManager */ /** @var \OCP\Share\IManager $shareManager */
@ -112,9 +105,7 @@ class ShareController extends ApiBase
$share = $shareManager->getShareById($id); $share = $shareManager->getShareById($id);
if ($share->getSharedBy() !== $uid) { if ($share->getSharedBy() !== $uid) {
return new JSONResponse([ return Errors::Forbidden('You are not the owner of this share');
'message' => 'You are not the owner of this share',
], Http::STATUS_FORBIDDEN);
} }
$shareManager->deleteShare($share); $shareManager->deleteShare($share);

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Errors;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
@ -37,18 +38,18 @@ class TagsController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check tags enabled for this user // Check tags enabled for this user
if (!$this->tagsIsEnabled()) { 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 // If this isn't the timeline folder then things aren't going to work
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// Run actual query // Run actual query
@ -70,18 +71,18 @@ class TagsController extends ApiBase
{ {
$user = $this->userSession->getUser(); $user = $this->userSession->getUser();
if (null === $user) { if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED); return Errors::NotLoggedIn();
} }
// Check tags enabled for this user // Check tags enabled for this user
if (!$this->tagsIsEnabled()) { 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 // If this isn't the timeline folder then things aren't going to work
$root = $this->getRequestRoot(); $root = $this->getRequestRoot();
if ($root->isEmpty()) { if ($root->isEmpty()) {
return new JSONResponse([], Http::STATUS_NOT_FOUND); return Errors::NoRequestRoot();
} }
// Run actual query // Run actual query
@ -106,20 +107,18 @@ class TagsController extends ApiBase
{ {
// Check tags enabled for this user // Check tags enabled for this user
if (!$this->tagsIsEnabled()) { 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 // Check the user is allowed to edit the file
$file = $this->getUserFile($id); $file = $this->getUserFile($id);
if (null === $file) { if (null === $file) {
return new JSONResponse([ return Errors::NotFoundFile($id);
'message' => 'File not found',
], Http::STATUS_NOT_FOUND);
} }
// Check the user is allowed to edit the file // Check the user is allowed to edit the file
if (!$file->isUpdateable() || !($file->getPermissions() & \OCP\Constants::PERMISSION_UPDATE)) { 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 // Get mapper from tags to objects

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace OCA\Memories\Controller; namespace OCA\Memories\Controller;
use OCA\Memories\Errors;
use OCA\Memories\Exif; use OCA\Memories\Exif;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataDisplayResponse; use OCP\AppFramework\Http\DataDisplayResponse;
@ -44,39 +45,35 @@ class VideoController extends ApiBase
{ {
// Make sure not running in read-only mode // Make sure not running in read-only mode
if (false !== $this->config->getSystemValue('memories.vod.disable', 'UNSET')) { 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 // Check client identifier is 8 characters or more
if (\strlen($client) < 8) { if (\strlen($client) < 8) {
return new JSONResponse(['message' => 'Invalid client identifier'], Http::STATUS_BAD_REQUEST); return Errors::MissingParameter('client (invalid)');
} }
// Get file // Get file
$file = $this->getUserFile($fileid); $file = $this->getUserFile($fileid);
if (!$file) { if (!$file || !$file->isReadable()) {
return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND); return Errors::NotFoundFile($fileid);
}
if (!$file->isReadable()) {
return new JSONResponse(['message' => 'File not readable'], Http::STATUS_FORBIDDEN);
} }
// Local files only for now // Local files only for now
if (!$file->getStorage()->isLocal()) { 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 // Get file path
$path = $file->getStorage()->getLocalFile($file->getInternalPath()); $path = $file->getStorage()->getLocalFile($file->getInternalPath());
if (!$path || !file_exists($path)) { 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 // Check if file starts with temp dir
$tmpDir = sys_get_temp_dir(); $tmpDir = sys_get_temp_dir();
if (0 === strpos($path, $tmpDir)) { 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 // Request and check data was received
@ -93,7 +90,7 @@ class VideoController extends ApiBase
$msg = 'Transcode failed: '.$e->getMessage(); $msg = 'Transcode failed: '.$e->getMessage();
$this->logger->error($msg, ['app' => 'memories']); $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 // The response was already streamed, so we have nothing to do here
@ -117,12 +114,12 @@ class VideoController extends ApiBase
) { ) {
$file = $this->getUserFile($fileid); $file = $this->getUserFile($fileid);
if (null === $file) { if (null === $file) {
return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND); return Errors::NotFoundFile($fileid);
} }
// Check file liveid // Check file liveid
if (!$liveid) { if (!$liveid) {
return new JSONResponse(['message' => 'Live ID not provided'], Http::STATUS_BAD_REQUEST); return Errors::MissingParameter('liveid');
} }
// Response data // Response data
@ -144,13 +141,13 @@ class VideoController extends ApiBase
try { // Get trailer try { // Get trailer
$blob = Exif::getBinaryExifProp($path, '-trailer'); $blob = Exif::getBinaryExifProp($path, '-trailer');
} catch (\Exception $e) { } catch (\Exception $e) {
return new JSONResponse(['message' => 'Trailer not found'], Http::STATUS_NOT_FOUND); return Errors::NotFound('file trailer');
} }
} elseif ('self__embeddedvideo' === $liveid) { } elseif ('self__embeddedvideo' === $liveid) {
try { // Get embedded video file try { // Get embedded video file
$blob = Exif::getBinaryExifProp($path, '-EmbeddedVideoFile'); $blob = Exif::getBinaryExifProp($path, '-EmbeddedVideoFile');
} catch (\Exception $e) { } 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=')) { } elseif (str_starts_with($liveid, 'self__traileroffset=')) {
// Remove prefix // Remove prefix
@ -165,14 +162,14 @@ class VideoController extends ApiBase
// Get stored video file (Apple MOV) // Get stored video file (Apple MOV)
$lp = $this->timelineQuery->getLivePhoto($fileid); $lp = $this->timelineQuery->getLivePhoto($fileid);
if (!$lp || $lp['liveid'] !== $liveid) { 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 // Get and return file
$liveFileId = (int) $lp['fileid']; $liveFileId = (int) $lp['fileid'];
$files = $this->rootFolder->getById($liveFileId); $files = $this->rootFolder->getById($liveFileId);
if (0 === \count($files)) { 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]; $liveFile = $files[0];
@ -191,7 +188,7 @@ class VideoController extends ApiBase
// Data not found // Data not found
if (!$blob) { if (!$blob) {
return new JSONResponse(['message' => 'Live file not found'], Http::STATUS_NOT_FOUND); return Errors::NotFound('live video data');
} }
// Transcode video if allowed // Transcode video if allowed

74
lib/Errors.php 100644
View File

@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace OCA\Memories;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
class Errors
{
public static function Generic(\Exception $e, int $status = Http::STATUS_INTERNAL_SERVER_ERROR): Http\Response
{
return new DataResponse([
'message' => $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);
}
}