diff --git a/src/Document/Document.php b/src/Document/Document.php index 7dbc634..f4db05d 100644 --- a/src/Document/Document.php +++ b/src/Document/Document.php @@ -20,6 +20,7 @@ use PrinsFrank\PdfParser\Document\Object\Item\UncompressedObject\UncompressedObjectParser; use PrinsFrank\PdfParser\Document\Security\StandardSecurity; use PrinsFrank\PdfParser\Document\Version\Version; +use PrinsFrank\PdfParser\Exception\AuthenticationFailedException; use PrinsFrank\PdfParser\Exception\NotImplementedException; use PrinsFrank\PdfParser\Exception\ParseFailureException; use PrinsFrank\PdfParser\Exception\PdfParserException; @@ -40,8 +41,16 @@ public function __construct( public readonly CrossReferenceSource $crossReferenceSource, public ?StandardSecurity $security, ) { - if ($this->getEncryptDictionary() !== null) { - throw new NotImplementedException('Encrypted documents are not supported yet'); + if (($encryptDictionary = $this->getEncryptDictionary()) !== null) { + if ($encryptDictionary->getSecurityHandler() === null) { + throw new NotImplementedException('Empty security handler is not supported'); + } + + $this->security ??= new StandardSecurity(); + if ($this->security->isUserPasswordValid($encryptDictionary, $crossReferenceSource->getFirstId()) === false + && $this->security->isOwnerPasswordValid($encryptDictionary, $crossReferenceSource->getFirstId()) === false) { + throw new AuthenticationFailedException($security === null ? 'Document could not be decrypted using default credentials, please supply an owner or user password' : 'User and owner password are invalid, please supply valid credentials'); + } } } diff --git a/tests/Samples/SamplesTest.php b/tests/Samples/SamplesTest.php index 625b24b..e4b6976 100644 --- a/tests/Samples/SamplesTest.php +++ b/tests/Samples/SamplesTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\Attributes\DataProviderExternal; use PHPUnit\Framework\TestCase; +use PrinsFrank\PdfParser\Document\Security\StandardSecurity; use PrinsFrank\PdfParser\Document\Version\Version; use PrinsFrank\PdfParser\PdfParser; use PrinsFrank\PdfParser\Tests\Samples\Info\FileInfo; @@ -18,8 +19,10 @@ class SamplesTest extends TestCase { /** @throws TypeError|ValueError|RuntimeException */ #[DataProviderExternal(SampleProvider::class, 'samples')] - public function testExternalSourcePDFs(FileInfo $fileInfo): void { - $document = (new PdfParser())->parseFile($fileInfo->pdfPath); + public function testSamples(FileInfo $fileInfo): void { + $document = (new PdfParser()) + ->parseFile($fileInfo->pdfPath, security: new StandardSecurity($fileInfo->userPassword, $fileInfo->ownerPassword)); + static::assertSame(Version::from(number_format($fileInfo->version / 10, 1)), $document->version); static::assertSame($fileInfo->title, $document->getInformationDictionary()?->getTitle()); static::assertSame($fileInfo->producer, $document->getInformationDictionary()?->getProducer());