From bd1fe04fdb81ebf139867a313d3a9312e58ba344 Mon Sep 17 00:00:00 2001 From: Michiel Kodde Date: Wed, 19 Aug 2020 08:23:16 +0200 Subject: [PATCH] Make processor aware of assertion types Both the Encrypted and regular Assertion classes should be passable in the decryptAssertion method. If not, you would never be able to process a SAML Response consisting of regular Assertion objects. The test merely verifies the behaviour that was changed in this commit. No additional processor tests where added. But that should be simple enough in the future. For some odd reason using a data provider for the processor_correctly_encrypts_assertions caused issues in other tests. The test suite does not seem to be fully idempotent. --- src/SAML2/Assertion/Processor.php | 8 ++- tests/SAML2/Assertion/ProcessorTest.php | 95 +++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 tests/SAML2/Assertion/ProcessorTest.php diff --git a/src/SAML2/Assertion/Processor.php b/src/SAML2/Assertion/Processor.php index f971e91cc..76a3aa978 100644 --- a/src/SAML2/Assertion/Processor.php +++ b/src/SAML2/Assertion/Processor.php @@ -93,7 +93,13 @@ public function decryptAssertions(ArrayCollection $assertions): ArrayCollection { $decrypted = new ArrayCollection(); foreach ($assertions->getIterator() as $assertion) { - $decrypted->add($this->decryptAssertion($assertion)); + if ($assertion instanceof EncryptedAssertion) { + $decrypted->add($this->decryptAssertion($assertion)); + } elseif ($assertion instanceof Assertion) { + $decrypted->add($assertion); + } else { + throw new InvalidAssertionException('The assertion must be of type: EncryptedAssertion or Assertion'); + } } return $decrypted; diff --git a/tests/SAML2/Assertion/ProcessorTest.php b/tests/SAML2/Assertion/ProcessorTest.php new file mode 100644 index 000000000..e2eebd849 --- /dev/null +++ b/tests/SAML2/Assertion/ProcessorTest.php @@ -0,0 +1,95 @@ +decrypter = m::mock(Decrypter::class); + $validator = m::mock(Validator::class); + $assertionValidator = m::mock(AssertionValidator::class); + $subjectConfirmationValidator = m::mock(SubjectConfirmationValidator::class); + $transformer = m::mock(TransformerInterface::class); + $identityProvider = new IdentityProvider([]); + $logger = m::mock(LoggerInterface::class); + + $this->processor = new Processor( + $this->decrypter, + $validator, + $assertionValidator, + $subjectConfirmationValidator, + $transformer, + $identityProvider, + $logger + ); + } + + /** + * @test + */ + public function processor_correctly_encrypts_assertions(): void + { + $encryptedAssertion = \Mockery::mock(EncryptedAssertion::class); + $assertion = \Mockery::mock(Assertion::class); + + $testData = [ + [$assertion], + [$encryptedAssertion], + [$assertion, $encryptedAssertion, $assertion], + [$encryptedAssertion, $encryptedAssertion, $encryptedAssertion], + ]; + + foreach ($testData as $assertions) { + $this->decrypter + ->shouldReceive('decrypt') + ->andReturn(new Assertion()); + + $collection = new ArrayCollection($assertions); + $result = $this->processor->decryptAssertions($collection); + self::assertInstanceOf(ArrayCollection::class, $result); + foreach ($result as $assertion) { + self::assertInstanceOf(Assertion::class, $assertion); + } + } + } + + /** + * @test + */ + public function unsuported_assertions_are_rejected(): void + { + $this->expectException(InvalidAssertionException::class); + $this->expectExceptionMessage('The assertion must be of type: EncryptedAssertion or Assertion'); + $this->processor->decryptAssertions(new ArrayCollection([new stdClass()])); + } +}