This repository has been archived on 2024-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
epubreader/lib/Controller/PageController.php

177 lines
5.2 KiB
PHP
Raw Normal View History

2020-04-21 20:37:42 +00:00
<?php
/**
* @author Frank de Lange
* @copyright 2015 Frank de Lange
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Epubreader\Controller;
2020-04-21 20:37:42 +00:00
2023-06-16 14:58:23 +00:00
use OCA\Epubreader\Service\BookmarkService;
use OCA\Epubreader\Service\PreferenceService;
2020-04-21 20:37:42 +00:00
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\ContentSecurityPolicy;
2023-06-16 14:58:23 +00:00
use OCP\AppFramework\Http\TemplateResponse;
2023-06-16 19:20:03 +00:00
use OCP\Files\FileInfo;
use OCP\Files\Folder;
2023-06-17 22:37:08 +00:00
use OCP\Files\InvalidPathException;
2020-04-21 20:37:42 +00:00
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
2023-06-16 14:58:23 +00:00
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\Share\IManager;
2020-04-21 20:37:42 +00:00
class PageController extends Controller {
2023-06-16 19:20:03 +00:00
private IURLGenerator $urlGenerator;
private IRootFolder $rootFolder;
private IManager $shareManager;
private string $userId;
private BookmarkService $bookmarkService;
private PreferenceService $preferenceService;
2023-06-16 14:58:23 +00:00
/**
* @param string $AppName
* @param IRequest $request
* @param IURLGenerator $urlGenerator
* @param IRootFolder $rootFolder
* @param IManager $shareManager
* @param string $UserId
* @param BookmarkService $bookmarkService
* @param PreferenceService $preferenceService
*/
public function __construct(
2023-06-16 19:20:03 +00:00
string $AppName,
2023-06-16 14:58:23 +00:00
IRequest $request,
IURLGenerator $urlGenerator,
IRootFolder $rootFolder,
IManager $shareManager,
2023-06-16 19:20:03 +00:00
string $UserId,
2023-06-16 14:58:23 +00:00
BookmarkService $bookmarkService,
PreferenceService $preferenceService,
2023-06-16 19:20:03 +00:00
) {
2023-06-16 14:58:23 +00:00
parent::__construct($AppName, $request);
$this->urlGenerator = $urlGenerator;
$this->rootFolder = $rootFolder;
$this->shareManager = $shareManager;
$this->userId = $UserId;
$this->bookmarkService = $bookmarkService;
$this->preferenceService = $preferenceService;
}
/**
* @PublicPage
* @NoCSRFRequired
*/
2023-06-16 19:20:03 +00:00
public function showReader(): TemplateResponse {
2023-06-16 14:58:23 +00:00
$templates = [
'application/epub+zip' => 'epubreader',
'application/x-cbr' => 'cbreader',
'application/pdf' => 'pdfreader'
];
/**
2023-06-16 19:31:46 +00:00
* @var array{
* fileId: int,
* fileName: string,
* fileType: string
* } $fileInfo
2023-06-16 14:58:23 +00:00
*/
2023-06-16 19:31:46 +00:00
$fileInfo = $this->getFileInfo((string) $this->request->getParam('file'));
2023-06-16 14:58:23 +00:00
$fileId = $fileInfo['fileId'];
2023-06-16 19:31:46 +00:00
$type = (string) $this->request->getParam('type');
2023-06-16 14:58:23 +00:00
$scope = $template = $templates[$type];
$params = [
'urlGenerator' => $this->urlGenerator,
'downloadLink' => $this->request->getParam('file'),
'scope' => $scope,
'fileId' => $fileInfo['fileId'],
'fileName' => $fileInfo['fileName'],
'fileType' => $fileInfo['fileType'],
'cursor' => $this->toJson($this->bookmarkService->getCursor($fileId)),
'defaults' => $this->toJson($this->preferenceService->getDefault($scope)),
'preferences' => $this->toJson($this->preferenceService->get($scope, $fileId)),
2023-06-16 19:20:03 +00:00
'metadata' => $this->toJson([]),
2023-06-16 14:58:23 +00:00
'annotations' => $this->toJson($this->bookmarkService->get($fileId))
];
$policy = new ContentSecurityPolicy();
2020-04-21 20:37:42 +00:00
$policy->addAllowedStyleDomain('\'self\'');
$policy->addAllowedStyleDomain('blob:');
$policy->addAllowedScriptDomain('\'self\'');
$policy->addAllowedFrameDomain('\'self\'');
$policy->addAllowedFontDomain('\'self\'');
$policy->addAllowedFontDomain('data:');
$policy->addAllowedFontDomain('blob:');
$policy->addAllowedImageDomain('blob:');
2023-06-16 14:58:23 +00:00
$response = new TemplateResponse($this->appName, $template, $params, 'blank');
2020-04-21 20:37:42 +00:00
$response->setContentSecurityPolicy($policy);
2023-06-16 14:58:23 +00:00
return $response;
}
/**
* @brief sharing-aware file info retriever
*
* Work around the differences between normal and shared file access
* (this should be abstracted away in OC/NC IMnsHO)
*
* @param string $path path-fragment from url
2023-06-17 22:55:37 +00:00
*
* @throws NotFoundException|InvalidPathException
2023-06-16 14:58:23 +00:00
*/
2023-06-16 19:20:03 +00:00
private function getFileInfo(string $path): array {
2023-06-16 14:58:23 +00:00
$count = 0;
$shareToken = preg_replace("/(?:\/index\.php)?\/s\/([A-Za-z0-9]{15,32})\/download.*/", "$1", $path, 1, $count);
if ($count === 1) {
/* shared file or directory */
$node = $this->shareManager->getShareByToken($shareToken)->getNode();
$type = $node->getType();
/* shared directory, need file path to continue, */
2023-06-16 19:20:03 +00:00
if ($type == FileInfo::TYPE_FOLDER && $node instanceof Folder) {
2023-06-16 14:58:23 +00:00
$query = [];
parse_str(parse_url($path, PHP_URL_QUERY), $query);
2023-06-16 19:31:46 +00:00
if (isset($query['path']) && is_string($query['path'])) {
2023-06-16 19:20:03 +00:00
$node = $node->get($query['path']);
2023-06-17 22:37:08 +00:00
} elseif (isset($query['files']) && is_string($query['files'])) {
$node = $node->get($query['files']);
2023-06-16 14:58:23 +00:00
} else {
throw new NotFoundException('Shared file path or name not set');
}
}
$filePath = $node->getPath();
$fileId = $node->getId();
} else {
$filePath = $path;
$fileId = $this->rootFolder->getUserFolder($this->userId)
2023-06-16 19:31:46 +00:00
->get(preg_replace("/.*\/remote.php\/webdav(.*)/", "$1", rawurldecode((string) $this->request->getParam('file'))))
2023-06-16 14:58:23 +00:00
->getId();
}
2023-06-16 15:21:29 +00:00
$pathInfo = pathInfo($filePath);
2023-06-17 22:37:08 +00:00
if (!is_array($pathInfo)) {
throw new InvalidPathException("Can not get info for $filePath");
}
2023-06-16 15:21:29 +00:00
2023-06-16 14:58:23 +00:00
return [
2023-06-16 15:21:29 +00:00
'fileName' => $pathInfo['filename'],
2023-06-17 22:37:08 +00:00
'fileType' => strtolower($pathInfo['extension'] ?? ''),
2023-06-16 14:58:23 +00:00
'fileId' => $fileId
];
}
2023-06-16 19:20:03 +00:00
/**
* @param mixed $value
*/
private function toJson($value): string {
2023-06-16 14:58:23 +00:00
return htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8');
}
2020-04-21 20:37:42 +00:00
}