Skip to content

Commit

Permalink
[Improvement]: Add sanitizing pdf (#301)
Browse files Browse the repository at this point in the history
* Improve: add sanitizing pdf

* Review changes - use scan instead of sanitizing

* Review changes

* Update translations/admin.en.yaml

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Review changes

* Update src/Controller/Admin/Asset/AssetController.php

Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>

* Update src/Controller/Admin/Asset/AssetController.php

Co-authored-by: aryaantony92 <97134765+aryaantony92@users.noreply.github.com>

---------

Co-authored-by: Divesh Pahuja <divesh.pahuja@pimcore.com>
Co-authored-by: Jacob Dreesen <jacob@hdreesen.de>
Co-authored-by: aryaantony92 <97134765+aryaantony92@users.noreply.github.com>
  • Loading branch information
4 people authored Oct 9, 2023
1 parent d0bde0d commit 19fda2e
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 7 deletions.
54 changes: 48 additions & 6 deletions src/Controller/Admin/Asset/AssetController.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use Pimcore\Loader\ImplementationLoader\Exception\UnsupportedException;
use Pimcore\Logger;
use Pimcore\Messenger\AssetPreviewImageMessage;
use Pimcore\Messenger\AssetUpdateTasksMessage;
use Pimcore\Model;
use Pimcore\Model\Asset;
use Pimcore\Model\DataObject\ClassDefinition\Data\ManyToManyRelation;
Expand Down Expand Up @@ -984,6 +985,13 @@ public function showVersionAction(Request $request): Response
throw $this->createAccessDeniedHttpException('Permission denied, version id [' . $id . ']');
}

if ($asset->getMimeType() === 'application/pdf') {
$scanResponse = $this->getResponseByScanStatus($asset, false);
if ($scanResponse) {
return $scanResponse;
}
}

$loader = \Pimcore::getContainer()->get('pimcore.implementation_loader.asset.metadata.data');

return $this->render(
Expand Down Expand Up @@ -1487,12 +1495,11 @@ protected function addThumbnailCacheHeaders(Response $response): void

/**
* @Route("/get-preview-document", name="pimcore_admin_asset_getpreviewdocument", methods={"GET"})
*
* @param Request $request
*
* @return StreamedResponse
*/
public function getPreviewDocumentAction(Request $request): StreamedResponse
public function getPreviewDocumentAction(
Request $request,
TranslatorInterface $translator
): StreamedResponse|Response
{
$asset = Asset\Document::getById((int) $request->get('id'));

Expand All @@ -1501,6 +1508,13 @@ public function getPreviewDocumentAction(Request $request): StreamedResponse
}

if ($asset->isAllowed('view')) {
if ($asset->getMimeType() === 'application/pdf') {
$scanResponse = $this->getResponseByScanStatus($asset);
if ($scanResponse) {
return $scanResponse;
}
}

$stream = $this->getDocumentPreviewPdf($asset);
if ($stream) {
return new StreamedResponse(function () use ($stream) {
Expand All @@ -1516,6 +1530,29 @@ public function getPreviewDocumentAction(Request $request): StreamedResponse
}
}

private function getResponseByScanStatus(Asset\Document $asset, bool $processBackground = true) :?Response
{
if (!Config::getSystemConfiguration('assets')['document']['scan_pdf']) {
return null;
}

$scanStatus = $asset->getScanStatus();
if ($scanStatus === null) {
$scanStatus = Asset\Enum\PdfScanStatus::IN_PROGRESS;
if ($processBackground) {
\Pimcore::getContainer()->get('messenger.bus.pimcore-core')->dispatch(
new AssetUpdateTasksMessage($asset->getId())
);
}
}

return match($scanStatus) {
Asset\Enum\PdfScanStatus::IN_PROGRESS => $this->render('@PimcoreAdmin/admin/asset/get_preview_pdf_in_progress.html.twig'),
Asset\Enum\PdfScanStatus::UNSAFE => $this->render('@PimcoreAdmin/admin/asset/get_preview_pdf_unsafe.html.twig'),
default => null,
};
}

/**
* @param Asset\Document $asset
*
Expand All @@ -1529,7 +1566,12 @@ protected function getDocumentPreviewPdf(Asset\Document $asset)
$stream = $asset->getStream();
}

if (!$stream && $asset->getPageCount() && \Pimcore\Document::isAvailable() && \Pimcore\Document::isFileTypeSupported($asset->getFilename())) {
if (
!$stream &&
$asset->getPageCount() &&
\Pimcore\Document::isAvailable() &&
\Pimcore\Document::isFileTypeSupported($asset->getFilename())
) {
try {
$document = \Pimcore\Document::getInstance();
$stream = $document->getPdf($asset);
Expand Down
51 changes: 51 additions & 0 deletions templates/admin/asset/get_preview_pdf_in_progress.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<style>
/* hide from ie on mac \*/
html {
height: 100%;
overflow: hidden;
}
/* end hide */
body {
height: 100%;
margin: 0;
padding: 0;
background: #EEE;
}
#container {
text-align: center;
position: absolute;
top:50%;
margin-top: -200px;
width: 100%;
}
#message {
margin-left: 8px;
}
</style>

<script {{ pimcore_csp.getNonceHtmlAttribute()|raw }}>
window.setTimeout(() => {
window.location.reload();
}, 5000)
</script>
</head>

<body>

<div id="container">
<span id="message">{{ 'pdf_scan_in_progress'|trans([], 'admin') }}</span>
</div>


</body>
</html>
54 changes: 54 additions & 0 deletions templates/admin/asset/get_preview_pdf_unsafe.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<style>
/* hide from ie on mac \*/
html {
height: 100%;
overflow: hidden;
}
/* end hide */
body {
height: 100%;
margin: 0;
padding: 0;
background: #EEE;
}
#container {
text-align: center;
position: absolute;
top:50%;
margin-top: -200px;
width: 100%;
}
#warning {
position: relative;
width: 40px;
height: 40px;
top: 13px;
}
#message {
margin-left: 8px;
}
</style>

</head>

<body>

<div id="container">
<img alt="warning" id="warning" src="/bundles/pimcoreadmin/img/flat-color-icons/overlay-error.svg" />
<span id="message">{{ 'pdf_js_unsafe'|trans([], 'admin') }}</span>
</div>


</body>
</html>
2 changes: 1 addition & 1 deletion templates/admin/asset/show_version_document.html.twig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% if asset.getMimeType() == 'application/pdf' %}
{% set tempFile = asset.getTemporaryFile() %}
{% set dataUri = pimcore_asset_version_preview(tempFile) %}

<div style="display: flex; width: 100%; height: 100%; flex-direction: column; overflow: hidden;">
<iframe src="{{ dataUri }}" frameborder="0" style="flex-grow: 1; border: none; margin: 0; padding: 0;"></iframe>
</div>
Expand Down
2 changes: 2 additions & 0 deletions translations/admin.en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -988,3 +988,5 @@ allow_asset_inline_download: Allow inline download
system_appearance_settings: 'Appearance & Branding'
male: Male
female: Female
pdf_js_unsafe: This PDF file contains JavaScript. If you want to view it, please download and open it in your local PDF viewer.
pdf_scan_in_progress: 'Preview not available: PDF is being scanned. This may take a while.'

0 comments on commit 19fda2e

Please sign in to comment.