diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 5d17fe6..2c7cc9d 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,34 +1,14 @@ -name: "CLA Assistant" +name: CLA check + on: issue_comment: types: [created] pull_request_target: - types: [opened,closed,synchronize] + types: [opened, closed, synchronize] jobs: - CLAssistant: - runs-on: ubuntu-latest - steps: - - name: "CLA Assistant" - if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - # Beta Release - uses: cla-assistant/github-action@v2.1.1-beta - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # the below token should have repo scope and must be manually added by you in the repository's secret - PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }} - with: - path-to-signatures: 'signatures/version1/cla.json' - path-to-document: 'https://github.com/pimcore/pimcore/blob/master/CLA.md' # e.g. a CLA or a DCO document - # branch should not be protected - branch: 'main' - allowlist: user1,bot* - - #below are the optional inputs - If the optional inputs are not given, then default values will be taken - remote-organization-name: 'pimcore' #enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository) - remote-repository-name: 'cla' - #create-file-commit-message: 'For example: Creating file for storing CLA Signatures' - #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo' - #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign' - #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA' - #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.' + cla-workflow: + uses: pimcore/workflows-collection-public/.github/workflows/reusable-cla-check.yaml@v1.3.0 + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + secrets: + CLA_ACTION_ACCESS_TOKEN: ${{ secrets.CLA_ACTION_ACCESS_TOKEN }} diff --git a/SECURITY.md b/SECURITY.md index 53173b7..15268a0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,19 +2,21 @@ ## Reporting a Vulnerability -If you think that you have found a security issue, -don’t use the bug tracker and don’t publish it publicly. -Instead, all security issues must be reported via 📫 to [security-issue@pimcore.com](mailto:security-issue@pimcore.com). +If you think that you have found a security issue, +don’t use the bug tracker and don’t publish it publicly. +Instead, all security issues must be reported via a private vulnerability report. + +Please follow the [instructions](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability) to submit a private report. ## Resolving Process -Every submitted security issue is handled with top priority by following these steps: +Every submitted security issue is handled with top priority by following these steps: 1. Confirm the vulnerability 2. Determine the severity 3. Contact reporter 4. Work on a patch 5. Get a CVE identification number (may be done by the reporter or a security service provider) -6. Patch reviewing +6. Patch reviewing 7. Tagging a new release for supported versions -8. Publish security announcement \ No newline at end of file +8. Publish security announcement diff --git a/public/img/logo.png b/public/img/logo.png new file mode 100644 index 0000000..1ce55ce Binary files /dev/null and b/public/img/logo.png differ diff --git a/src/Controller/Document/PrintpageControllerBase.php b/src/Controller/Document/PrintpageControllerBase.php index 0a17761..a047f7e 100644 --- a/src/Controller/Document/PrintpageControllerBase.php +++ b/src/Controller/Document/PrintpageControllerBase.php @@ -42,7 +42,7 @@ abstract class PrintpageControllerBase extends DocumentControllerBase * * @return JsonResponse * - * @throws \Exception + * @throws Exception */ public function getDataByIdAction(Request $request): JsonResponse { @@ -250,7 +250,7 @@ protected function setValuesToDocument(Request $request, Document $document): vo * * @return JsonResponse * - * @throws \Exception + * @throws Exception */ public function activeGenerateProcessAction(Request $request): JsonResponse { @@ -276,7 +276,7 @@ public function activeGenerateProcessAction(Request $request): JsonResponse 'activeGenerateProcess' => !empty($inProgress), 'date' => $date, 'message' => $document->getLastGenerateMessage(), - 'downloadAvailable' => file_exists($document->getPdfFileName()), + 'downloadAvailable' => $this->checkFileExists($document->getPdfFileName()), 'statusUpdate' => $statusUpdate, ]); } @@ -288,7 +288,7 @@ public function activeGenerateProcessAction(Request $request): JsonResponse * * @return BinaryFileResponse * - * @throws \Exception + * @throws Exception */ public function pdfDownloadAction(Request $request): BinaryFileResponse { @@ -298,7 +298,7 @@ public function pdfDownloadAction(Request $request): BinaryFileResponse throw $this->createNotFoundException('Document with id ' . $request->get('id') . ' not found.'); } - if (file_exists($document->getPdfFileName())) { + if ($this->checkFileExists($document->getPdfFileName())) { $response = new BinaryFileResponse($document->getPdfFileName()); $response->headers->set('Content-Type', 'application/pdf'); if ($request->get('download')) { @@ -319,7 +319,7 @@ public function pdfDownloadAction(Request $request): BinaryFileResponse * * @return JsonResponse * - * @throws \Exception + * @throws Exception */ public function startPdfGenerationAction(Request $request, \Pimcore\Config $config): JsonResponse { @@ -404,7 +404,7 @@ public function getProcessingOptionsAction(Request $request): JsonResponse private function getStoredProcessingOptions(int $documentId): array { $filename = PIMCORE_SYSTEM_TEMP_DIRECTORY . DIRECTORY_SEPARATOR . 'web2print-processingoptions-' . $documentId . '_' . $this->getAdminUser()->getId() . '.psf'; - if (file_exists($filename)) { + if ($this->checkFileExists($filename)) { $options = \Pimcore\Tool\Serialize::unserialize(file_get_contents($filename)); if (is_array($options)) { return $options; @@ -426,7 +426,7 @@ private function saveProcessingOptions(int $documentId, array $options): void * * @return JsonResponse * - * @throws \Exception + * @throws Exception */ public function cancelGenerationAction(Request $request): JsonResponse { @@ -434,4 +434,36 @@ public function cancelGenerationAction(Request $request): JsonResponse return $this->adminJson(['success' => true]); } + + /** + * Checks if a file exists on the filesystem. + * + * @param string $filePath + * + * @return bool + */ + private function checkFileExists(string $filePath): bool + { + $this->invalidateFsCacheFor($filePath); + + return file_exists($filePath); + } + + /** + * Invalidates the FS cache for a given file path by opening and closing the directory. + * This is a workaround for a bug which happens when the local filesystem is using a NFS with cache. + * + * @param string $filePath + * + * @return void + */ + private function invalidateFsCacheFor(string $filePath): void + { + try { + if ($dh = opendir(dirname($filePath))) { + closedir($dh); + } + } catch (Exception) { + } + } } diff --git a/src/Processor/Gotenberg.php b/src/Processor/Gotenberg.php index c018323..f55e9c4 100644 --- a/src/Processor/Gotenberg.php +++ b/src/Processor/Gotenberg.php @@ -16,8 +16,12 @@ namespace Pimcore\Bundle\WebToPrintBundle\Processor; +use function array_merge; +use function file_exists; use Gotenberg\Gotenberg as GotenbergAPI; use Gotenberg\Stream; +use function json_decode; +use function key_exists; use Pimcore\Bundle\WebToPrintBundle\Config; use Pimcore\Bundle\WebToPrintBundle\Event\DocumentEvents; use Pimcore\Bundle\WebToPrintBundle\Event\Model\PrintConfigEvent; @@ -32,35 +36,15 @@ class Gotenberg extends Processor */ protected function buildPdf(PrintAbstract $document, object $config): string { - $web2printConfig = Config::getWeb2PrintConfig(); - $gotenbergSettings = $web2printConfig['gotenbergSettings']; - $gotenbergSettings = json_decode($gotenbergSettings, true); - $params = ['document' => $document]; $this->updateStatus($document->getId(), 10, 'start_html_rendering'); $html = $document->renderDocument($params); - $params['hostUrl'] = 'http://nginx:80'; - if (!empty($web2printConfig['gotenbergHostUrl'])) { - $params['hostUrl'] = $web2printConfig['gotenbergHostUrl']; - } - - $html = $this->processHtml($html, $params); $this->updateStatus($document->getId(), 40, 'finished_html_rendering'); - if ($gotenbergSettings) { - foreach (['header', 'footer'] as $item) { - if (key_exists($item, $gotenbergSettings) && $gotenbergSettings[$item] && - file_exists($gotenbergSettings[$item])) { - $gotenbergSettings[$item . 'Template'] = $gotenbergSettings[$item]; - } - unset($gotenbergSettings[$item]); - } - } - try { $this->updateStatus($document->getId(), 50, 'pdf_conversion'); - $pdf = $this->getPdfFromString($html, $gotenbergSettings ?? []); + $pdf = $this->getPdfFromString($html); $this->updateStatus($document->getId(), 100, 'saving_pdf_document'); } catch (\Exception $e) { Logger::error((string) $e); @@ -92,6 +76,29 @@ public function getProcessingOptions(): array */ public function getPdfFromString(string $html, array $params = [], bool $returnFilePath = false): string { + $web2printConfig = Config::getWeb2PrintConfig(); + + $processParams = [ + 'hostUrl' => $web2printConfig['gotenbergHostUrl'] ?? 'http://nginx:80', + ]; + + $html = $this->processHtml($html, $processParams); + + $gotenbergSettings = $web2printConfig['gotenbergSettings'] ?? ''; + $gotenbergSettings = json_decode($gotenbergSettings, true); + + if ($gotenbergSettings) { + foreach (['header', 'footer'] as $item) { + if (key_exists($item, $gotenbergSettings) && $gotenbergSettings[$item] && + file_exists($gotenbergSettings[$item])) { + $gotenbergSettings[$item . 'Template'] = $gotenbergSettings[$item]; + } + unset($gotenbergSettings[$item]); + } + + $params = array_merge($params, $gotenbergSettings); + } + $params = $params ?: $this->getDefaultOptions(); $event = new PrintConfigEvent($this, [ diff --git a/templates/settings/test_web2print.html.twig b/templates/settings/test_web2print.html.twig index 5ec22f0..356106c 100644 --- a/templates/settings/test_web2print.html.twig +++ b/templates/settings/test_web2print.html.twig @@ -76,5 +76,10 @@

Background Test

This text could have a background color depending on configured settings.

+ +

Image Test

+ + +