diff --git a/appinfo/routes/routesFileController.php b/appinfo/routes/routesFileController.php index c791c01026..917ec6cdba 100644 --- a/appinfo/routes/routesFileController.php +++ b/appinfo/routes/routesFileController.php @@ -8,6 +8,7 @@ 'ocs' => [ ['name' => 'File#save', 'url' => '/api/{apiVersion}/file', 'verb' => 'POST', 'requirements' => $requirements], ['name' => 'File#list', 'url' => '/api/{apiVersion}/file/list', 'verb' => 'GET', 'requirements' => $requirements], + ['name' => 'File#validate', 'url' => '/api/{apiVersion}/file/validate/', 'verb' => 'GET', 'requirements' => $requirements], ['name' => 'File#validateUuid', 'url' => '/api/{apiVersion}/file/validate/uuid/{uuid}', 'verb' => 'GET', 'requirements' => $requirements], ['name' => 'File#validateFileId', 'url' => '/api/{apiVersion}/file/validate/file_id/{fileId}', 'verb' => 'GET', 'requirements' => $requirements], ['name' => 'File#getPage', 'url' => '/api/{apiVersion}/file/page/{uuid}/{page}.png', 'verb' => 'GET', 'requirements' => $requirements], diff --git a/lib/Controller/FileController.php b/lib/Controller/FileController.php index 735b240a20..db676220ae 100644 --- a/lib/Controller/FileController.php +++ b/lib/Controller/FileController.php @@ -68,9 +68,29 @@ public function validateFileId($fileId): JSONResponse { return $this->validate('FileId', $fileId); } - private function validate(string $type, $identifier): JSONResponse { + #[NoAdminRequired] + #[NoCSRFRequired] + #[PublicPage] + public function validate(?string $type = null, $identifier = null): JSONResponse { try { - $this->fileService->setFileByType($type, $identifier); + if (!empty($type) && !empty($identifier)) { + $this->fileService + ->setFileByType($type, $identifier); + } elseif ($this->request->getParam('path')) { + $this->fileService + ->setMe($this->userSession->getUser()) + ->setFileByPath($this->request->getParam('path')); + } elseif ($this->request->getParam('fileId')) { + $this->fileService->setFileByType( + 'FileId', + $this->request->getParam('fileId') + ); + } elseif ($this->request->getParam('uuid')) { + $this->fileService->setFileByType( + 'Uuid', + $this->request->getParam('uuid') + ); + } $return = []; $statusCode = Http::STATUS_OK; } catch (LibresignException $e) { @@ -137,13 +157,21 @@ public function getPage(string $uuid, int $page) { #[NoAdminRequired] #[NoCSRFRequired] #[RequireManager] - public function save(string $name, array $file, array $settings = []): JSONResponse { + public function save(array $file, string $name = '', array $settings = []): JSONResponse { try { + if (empty($name)) { + if (!empty($file['url'])) { + $name = rawurldecode(pathinfo($file['url'], PATHINFO_FILENAME)); + } + } if (empty($name)) { // The name of file to sign is mandatory. This phrase is used when we do a request to API sending a file to sign. throw new \Exception($this->l10n->t('Name is mandatory')); } - $this->validateHelper->validateNewFile(['file' => $file]); + $this->validateHelper->validateNewFile([ + 'file' => $file, + 'userManager' => $this->userSession->getUser(), + ]); $this->validateHelper->canRequestSign($this->userSession->getUser()); $node = $this->fileService->getNodeFromData([ diff --git a/lib/Helper/ValidateHelper.php b/lib/Helper/ValidateHelper.php index 3f61971ed6..5dd303d823 100644 --- a/lib/Helper/ValidateHelper.php +++ b/lib/Helper/ValidateHelper.php @@ -44,6 +44,7 @@ use OCP\Files\Config\IUserMountCache; use OCP\Files\IMimeTypeDetector; use OCP\Files\IRootFolder; +use OCP\Files\NotFoundException; use OCP\IConfig; use OCP\IGroupManager; use OCP\IL10N; @@ -88,6 +89,14 @@ public function validateNewFile(array $data): void { $this->validateFile($data, self::TYPE_TO_SIGN); if (!empty($data['file']['fileId'])) { $this->validateNotRequestedSign((int)$data['file']['fileId']); + } elseif (!empty($data['file']['path'])) { + $userFolder = $this->root->getUserFolder($data['userManager']->getUID()); + try { + $node = $userFolder->get($data['file']['path']); + } catch (NotFoundException $e) { + throw new LibresignException($this->l10n->t('Invalid data to validate file'), 404); + } + $this->validateNotRequestedSign($node->getId()); } } @@ -107,18 +116,30 @@ public function validateFile(array $data, int $type = self::TYPE_TO_SIGN): void } return; } - if (empty($data['file']['url']) && empty($data['file']['base64']) && empty($data['file']['fileId'])) { - throw new LibresignException($this->l10n->t('File type: %s. Specify a URL, a base64 string or a fileID.', [$this->getTypeOfFile($type)])); - } - if (!empty($data['file']['fileId'])) { + if (!empty($data['file']['url'])) { + if (!filter_var($data['file']['url'], FILTER_VALIDATE_URL)) { + throw new LibresignException($this->l10n->t('File type: %s. Specify a URL, a base64 string or a fileID.', [$this->getTypeOfFile($type)])); + } + } elseif (!empty($data['file']['fileId'])) { if (!is_numeric($data['file']['fileId'])) { throw new LibresignException($this->l10n->t('File type: %s. Invalid fileID.', [$this->getTypeOfFile($type)])); } $this->validateIfNodeIdExists((int)$data['file']['fileId'], $type); $this->validateMimeTypeAcceptedByNodeId((int)$data['file']['fileId'], $type); - } - if (!empty($data['file']['base64'])) { + } elseif (!empty($data['file']['base64'])) { $this->validateBase64($data['file']['base64'], $type); + } elseif (!empty($data['file']['path'])) { + if (!is_a($data['userManager'], IUser::class)) { + throw new LibresignException($this->l10n->t('User not found.')); + } + $userFolder = $this->root->getUserFolder($data['userManager']->getUID()); + try { + $userFolder->get($data['file']['path']); + } catch (NotFoundException $e) { + throw new LibresignException($this->l10n->t('Invalid data to validate file'), 404); + } + } else { + throw new LibresignException($this->l10n->t('File type: %s. Specify a URL, base64 string, path or a fileID.', [$this->getTypeOfFile($type)])); } } diff --git a/lib/Service/FileService.php b/lib/Service/FileService.php index 1b924a155e..b390159a8f 100644 --- a/lib/Service/FileService.php +++ b/lib/Service/FileService.php @@ -461,6 +461,12 @@ public function getPage(string $uuid, int $page, string $uid): string { return $imagick->getImageBlob(); } + public function setFileByPath(string $path): self { + $node = $this->folderService->getFileByPath($path); + $this->setFileByType('FileId', $node->getId()); + return $this; + } + /** * @return array[] * diff --git a/lib/Service/FolderService.php b/lib/Service/FolderService.php index 7d0ef5e440..59d3058dae 100644 --- a/lib/Service/FolderService.php +++ b/lib/Service/FolderService.php @@ -25,9 +25,11 @@ namespace OCA\Libresign\Service; use OCA\Libresign\AppInfo\Application; +use OCA\Libresign\Exception\LibresignException; use OCP\Files\Config\IUserMountCache; use OCP\Files\Folder; use OCP\Files\IRootFolder; +use OCP\Files\Node; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\IConfig; @@ -149,4 +151,13 @@ public function getFolderName(array $data, IUser $owner): string { } return implode($data['settings']['separator'], $folderName); } + + public function getFileByPath(string $path): Node { + $userFolder = $this->root->getUserFolder($this->getUserId()); + try { + return $userFolder->get($path); + } catch (NotFoundException $e) { + throw new LibresignException($this->l10n->t('Invalid data to validate file'), 404); + } + } } diff --git a/lib/Service/TFile.php b/lib/Service/TFile.php index 6b673511ea..4d0112669a 100644 --- a/lib/Service/TFile.php +++ b/lib/Service/TFile.php @@ -45,6 +45,9 @@ public function getNodeFromData(array $data): Node { $userFolder = $this->folderService->getFolder($data['file']['fileId']); return $userFolder->getById($data['file']['fileId'])[0]; } + if (isset($data['file']['path'])) { + return $this->folderService->getFileByPath($data['file']['path']); + } $content = $this->getFileRaw($data); @@ -99,16 +102,14 @@ private function getFileRaw(array $data) { } $response = $this->client->newClient()->get($data['file']['url']); $mimetypeFromHeader = $response->getHeader('Content-Type'); - $content = $response->getBody(); + $content = (string) $response->getBody(); if (!$content) { throw new \Exception($this->l10n->t('Empty file')); } - $this->validateHelper->validateBase64($content); $mimeTypeFromContent = $this->getMimeType($content); if ($mimetypeFromHeader !== $mimeTypeFromContent) { throw new \Exception($this->l10n->t('Invalid URL file')); } - $this->setMimeType($mimeTypeFromContent); } else { $content = $this->getFileFromBase64($data['file']['base64']); } diff --git a/src/Components/File/LibresignTab.vue b/src/Components/File/LibresignTab.vue index 24ed62f896..2f02dfdb2a 100644 --- a/src/Components/File/LibresignTab.vue +++ b/src/Components/File/LibresignTab.vue @@ -1,6 +1,8 @@