diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml index 844afbc7a..a18b476d2 100644 --- a/.github/workflows/psalm.yml +++ b/.github/workflows/psalm.yml @@ -75,7 +75,7 @@ jobs: - name: Install dependencies # zizmor: ignore[template-injection] - run: composer require --dev 'nextcloud/ocp:${{ matrix.ocp-version }}' --ignore-platform-reqs --with-dependencies + run: composer require --dev 'nextcloud/ocp:${{ matrix.ocp-version }}' --ignore-platform-reqs --with-all-dependencies - name: Run coding standards check run: composer run psalm -- --threads=1 --monochrome --no-progress --output-format=github diff --git a/lib/Controller/FoldersController.php b/lib/Controller/FoldersController.php index 289114d84..4ac0b1caf 100644 --- a/lib/Controller/FoldersController.php +++ b/lib/Controller/FoldersController.php @@ -221,8 +221,8 @@ public function getFolder($folderId): JSONResponse { * @throws UnauthenticatedError */ public function addToFolder($folderId, $bookmarkId): JSONResponse { - if (!Authorizer::hasPermission(Authorizer::PERM_WRITE, $this->authorizer->getPermissionsForFolder($folderId, $this->request)) || - !Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($bookmarkId, $this->request))) { + if (!Authorizer::hasPermission(Authorizer::PERM_WRITE, $this->authorizer->getPermissionsForFolder($folderId, $this->request)) + || !Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($bookmarkId, $this->request))) { $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND); $res->throttle(); return $res; @@ -259,8 +259,8 @@ public function addToFolder($folderId, $bookmarkId): JSONResponse { * @throws UnauthenticatedError */ public function removeFromFolder($folderId, $bookmarkId, bool $hardDelete = false): JSONResponse { - if (!Authorizer::hasPermission(Authorizer::PERM_WRITE, $this->authorizer->getPermissionsForFolder($folderId, $this->request)) || - !Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($bookmarkId, $this->request))) { + if (!Authorizer::hasPermission(Authorizer::PERM_WRITE, $this->authorizer->getPermissionsForFolder($folderId, $this->request)) + || !Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($bookmarkId, $this->request))) { $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_BAD_REQUEST); $res->throttle(); return $res; @@ -293,8 +293,8 @@ public function removeFromFolder($folderId, $bookmarkId, bool $hardDelete = fals * @throws UnauthenticatedError */ public function undeleteFromFolder(int $folderId, int $bookmarkId): JSONResponse { - if (!Authorizer::hasPermission(Authorizer::PERM_WRITE, $this->authorizer->getPermissionsForFolder($folderId, $this->request)) || - !Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($bookmarkId, $this->request))) { + if (!Authorizer::hasPermission(Authorizer::PERM_WRITE, $this->authorizer->getPermissionsForFolder($folderId, $this->request)) + || !Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForBookmark($bookmarkId, $this->request))) { $res = new JSONResponse(['status' => 'error', 'data' => ['Unauthorized']], Http::STATUS_FORBIDDEN); $res->throttle(); return $res; diff --git a/lib/Controller/WebViewController.php b/lib/Controller/WebViewController.php index ffdfd4278..33343ff53 100644 --- a/lib/Controller/WebViewController.php +++ b/lib/Controller/WebViewController.php @@ -172,8 +172,8 @@ public function manifest(): JSONResponse { 'name' => $this->l->t('Bookmarks'), 'short_name' => $this->l->t('Bookmarks'), 'start_url' => $this->urlGenerator->linkToRouteAbsolute('bookmarks.web_view.index'), - 'icons' => - [ + 'icons' + => [ [ 'src' => $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon', ['app' => 'bookmarks']), diff --git a/lib/Db/BookmarkMapper.php b/lib/Db/BookmarkMapper.php index e6f5b47b3..c81c6c885 100644 --- a/lib/Db/BookmarkMapper.php +++ b/lib/Db/BookmarkMapper.php @@ -220,8 +220,8 @@ public function findAll(string $userId, QueryParameters $queryParams, bool $with $qb ->from('*PREFIX*bookmarks', 'b') - ->innerJoin('b', 'folder_tree', 'tree', 'tree.item_id = b.id AND tree.type = ' . $qb->createPositionalParameter(TreeMapper::TYPE_BOOKMARK) . - ($queryParams->getSoftDeleted() ? ' AND tree.soft_deleted_at is NOT NULL' : ' AND tree.soft_deleted_at is NULL')); + ->innerJoin('b', 'folder_tree', 'tree', 'tree.item_id = b.id AND tree.type = ' . $qb->createPositionalParameter(TreeMapper::TYPE_BOOKMARK) + . ($queryParams->getSoftDeleted() ? ' AND tree.soft_deleted_at is NOT NULL' : ' AND tree.soft_deleted_at is NULL')); $this->_filterUrl($qb, $queryParams); $this->_filterArchived($qb, $queryParams); @@ -298,9 +298,9 @@ private function _generateCTE(int $folderId, bool $withSoftDeleted) : array { if ($this->getDbType() === 'mysql') { // For mysql we can just throw these three queries together in a CTE - $withRecursiveQuery = 'WITH RECURSIVE folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS ( ' . - $baseCase->getSQL() . ' UNION ALL ' . $recursiveCase->getSQL() . - ' UNION ALL ' . $recursiveCaseShares->getSQL() . ')'; + $withRecursiveQuery = 'WITH RECURSIVE folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS ( ' + . $baseCase->getSQL() . ' UNION ALL ' . $recursiveCase->getSQL() + . ' UNION ALL ' . $recursiveCaseShares->getSQL() . ')'; } else { // Postgres loves us dearly and doesn't allow two recursive references in one CTE, aaah. // So we nest them: @@ -333,12 +333,12 @@ private function _generateCTE(int $folderId, bool $withSoftDeleted) : array { // then we need another instance of the first recursive case, duplicated here as secondRecursive case // to recurse into child folders of shared folders // Note: This doesn't cover cases where a shared folder is inside a shared folder. - $withRecursiveQuery = 'WITH RECURSIVE folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS ( ' . - 'WITH RECURSIVE second_folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS (' . - 'WITH RECURSIVE inner_folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS ( ' . - $baseCase->getSQL() . ' UNION ALL ' . $recursiveCase->getSQL() . ')' . - ' ' . $secondBaseCase->getSQL() . ' UNION ALL ' . $recursiveCaseShares->getSQL() . ')' . - ' ' . $thirdBaseCase->getSQL() . ' UNION ALL ' . $secondRecursiveCase->getSQL() . ')'; + $withRecursiveQuery = 'WITH RECURSIVE folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS ( ' + . 'WITH RECURSIVE second_folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS (' + . 'WITH RECURSIVE inner_folder_tree(item_id, parent_folder, type, idx, soft_deleted_at) AS ( ' + . $baseCase->getSQL() . ' UNION ALL ' . $recursiveCase->getSQL() . ')' + . ' ' . $secondBaseCase->getSQL() . ' UNION ALL ' . $recursiveCaseShares->getSQL() . ')' + . ' ' . $thirdBaseCase->getSQL() . ' UNION ALL ' . $secondRecursiveCase->getSQL() . ')'; } // Now we need to concatenate the params of all these queries for downstream assembly of the greater query diff --git a/lib/Migration/Version000014000Date20181029094721.php b/lib/Migration/Version000014000Date20181029094721.php index 3192aa752..4f9880251 100644 --- a/lib/Migration/Version000014000Date20181029094721.php +++ b/lib/Migration/Version000014000Date20181029094721.php @@ -90,8 +90,8 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $children = array_merge($childFolders, $childBookmarks); $children = array_map(static function ($child) { - return $child['bookmark_id'] ? - ['type' => 'bookmark', 'id' => $child['bookmark_id']] + return $child['bookmark_id'] + ? ['type' => 'bookmark', 'id' => $child['bookmark_id']] : ['type' => 'folder', 'id' => $child['id']]; }, $children); if (count($children) > 0) { diff --git a/lib/Service/BookmarkPreviewer.php b/lib/Service/BookmarkPreviewer.php index 035fed1a1..6a9301b44 100644 --- a/lib/Service/BookmarkPreviewer.php +++ b/lib/Service/BookmarkPreviewer.php @@ -13,6 +13,7 @@ use OCA\Bookmarks\Db\Bookmark; use OCA\Bookmarks\Image; use OCA\Bookmarks\Service\Previewers\DefaultBookmarkPreviewer; +use OCA\Bookmarks\Service\Previewers\GenericUrlBookmarkPreviewer; use OCA\Bookmarks\Service\Previewers\PageresBookmarkPreviewer; use OCA\Bookmarks\Service\Previewers\ScreeenlyBookmarkPreviewer; use OCA\Bookmarks\Service\Previewers\ScreenshotMachineBookmarkPreviewer; @@ -23,46 +24,28 @@ class BookmarkPreviewer implements IBookmarkPreviewer { // Cache for one month public const CACHE_TTL = 4 * 4 * 7 * 24 * 60 * 60; + private string $enabled; + private FileCache $cache; + private DefaultBookmarkPreviewer $defaultPreviewer; + private ScreeenlyBookmarkPreviewer $screeenlyPreviewer; + private ScreenshotMachineBookmarkPreviewer $screenshotMachinePreviewer; + private PageresBookmarkPreviewer $pageresPreviewer; + private Previewers\GenericUrlBookmarkPreviewer $genericUrlPreviewer; - /** - * @var string - */ - private $enabled; - /** - * @var DefaultBookmarkPreviewer - */ - private $defaultPreviewer; - /** - * @var ScreeenlyBookmarkPreviewer - */ - private $screeenlyPreviewer; - - /** - * @var FileCache - */ - private $cache; - /** - * @var Previewers\ScreenshotMachineBookmarkPreviewer - */ - private $screenshotMachinePreviewer; - /** - * @var Previewers\PageresBookmarkPreviewer - */ - private $pageresPreviewer; - - /** - * @param IConfig $config - * @param ScreeenlyBookmarkPreviewer $screeenlyPreviewer - * @param DefaultBookmarkPreviewer $defaultPreviewer - * @param FileCache $cache - * @param Previewers\ScreenshotMachineBookmarkPreviewer $screenshotMachinePreviewer - * @param Previewers\PageresBookmarkPreviewer $pageresPreviewer - */ - public function __construct(IConfig $config, ScreeenlyBookmarkPreviewer $screeenlyPreviewer, DefaultBookmarkPreviewer $defaultPreviewer, FileCache $cache, ScreenshotMachineBookmarkPreviewer $screenshotMachinePreviewer, PageresBookmarkPreviewer $pageresPreviewer) { + public function __construct( + IConfig $config, + ScreeenlyBookmarkPreviewer $screeenlyPreviewer, + DefaultBookmarkPreviewer $defaultPreviewer, + FileCache $cache, + ScreenshotMachineBookmarkPreviewer $screenshotMachinePreviewer, + PageresBookmarkPreviewer $pageresPreviewer, + GenericUrlBookmarkPreviewer $genericUrlPreviewer, + ) { $this->screeenlyPreviewer = $screeenlyPreviewer; $this->defaultPreviewer = $defaultPreviewer; $this->screenshotMachinePreviewer = $screenshotMachinePreviewer; $this->pageresPreviewer = $pageresPreviewer; + $this->genericUrlPreviewer = $genericUrlPreviewer; $this->enabled = $config->getAppValue('bookmarks', 'privacy.enableScraping', 'false'); $this->cache = $cache; @@ -85,7 +68,13 @@ public function getImage($bookmark, $cacheOnly = false): ?IImage { return null; } - $previewers = [$this->screeenlyPreviewer, $this->screenshotMachinePreviewer, $this->pageresPreviewer, $this->defaultPreviewer]; + $previewers = [ + $this->screeenlyPreviewer, + $this->screenshotMachinePreviewer, + $this->pageresPreviewer, + $this->genericUrlPreviewer, + $this->defaultPreviewer, + ]; foreach ($previewers as $previewer) { $key = $previewer::CACHE_PREFIX . '-' . md5($bookmark->getUrl()); // Try cache first diff --git a/lib/Service/FileCache.php b/lib/Service/FileCache.php index 22c0dfc97..8d109b61d 100644 --- a/lib/Service/FileCache.php +++ b/lib/Service/FileCache.php @@ -58,10 +58,10 @@ private function getStorage(): ISimpleFolder { if (!$this->storage->fileExists('CACHEDIR.TAG')) { try { $this->storage->newFile('CACHEDIR.TAG', - 'Signature: 8a477f597d28d172789f06886806bc55' . "\r\n" . - '# This file is a cache directory tag created by the nextcloud bookmarks app.' . "\r\n" . - '# For information about cache directory tags, see:' . "\r\n" . - '# http://www.brynosaurus.com/cachedir/)' . "\r\n" + 'Signature: 8a477f597d28d172789f06886806bc55' . "\r\n" + . '# This file is a cache directory tag created by the nextcloud bookmarks app.' . "\r\n" + . '# For information about cache directory tags, see:' . "\r\n" + . '# http://www.brynosaurus.com/cachedir/)' . "\r\n" ); } catch (NotPermittedException $e) { // No op diff --git a/lib/Service/Previewers/GenericUrlBookmarkPreviewer.php b/lib/Service/Previewers/GenericUrlBookmarkPreviewer.php index b4e8766e5..09288154e 100644 --- a/lib/Service/Previewers/GenericUrlBookmarkPreviewer.php +++ b/lib/Service/Previewers/GenericUrlBookmarkPreviewer.php @@ -67,7 +67,7 @@ public function getImage($bookmark, $cacheOnly = false): ?IImage { if (!isset($bookmark)) { return null; } - if ($this->apiKey === '' || $cacheOnly) { + if ($this->apiUrl === '' || $cacheOnly) { return null; } $url = $bookmark->getUrl(); diff --git a/lib/Service/Previewers/PageresBookmarkPreviewer.php b/lib/Service/Previewers/PageresBookmarkPreviewer.php index 89d4a2ef4..fc5dc935b 100644 --- a/lib/Service/Previewers/PageresBookmarkPreviewer.php +++ b/lib/Service/Previewers/PageresBookmarkPreviewer.php @@ -76,8 +76,8 @@ protected function fetchImage(string $serverPath, string $url): Image { $escapedUrl = escapeshellarg($url); $env = $this->config->getAppValue('bookmarks', 'previews.pageres.env'); - $cmd = "cd {$tempDir} && {$env} {$command} {$escapedUrl} 1024x768" . - ' --delay=4 --filename=' . escapeshellarg($tempFile) . ' --crop --overwrite 2>&1'; + $cmd = "cd {$tempDir} && {$env} {$command} {$escapedUrl} 1024x768" + . ' --delay=4 --filename=' . escapeshellarg($tempFile) . ' --crop --overwrite 2>&1'; $retries = 0; $output = []; diff --git a/tests/FolderControllerTest.php b/tests/FolderControllerTest.php index 3f28b5fde..4b0a7200c 100644 --- a/tests/FolderControllerTest.php +++ b/tests/FolderControllerTest.php @@ -3,7 +3,6 @@ namespace OCA\Bookmarks\Tests; use OC; -use OCA\Bookmarks\Controller\BookmarkController; use OCA\Bookmarks\Controller\FoldersController; use OCA\Bookmarks\Db\Bookmark; use OCA\Bookmarks\Db\BookmarkMapper;