From 151a418de9a3a383cef1f0cca28a0ceb12ead707 Mon Sep 17 00:00:00 2001 From: Michiel Kodde Date: Tue, 18 Aug 2020 13:40:12 +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 | 10 ++- tests/SAML2/Assertion/ProcessorTest.php | 81 +++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 tests/SAML2/Assertion/ProcessorTest.php diff --git a/src/SAML2/Assertion/Processor.php b/src/SAML2/Assertion/Processor.php index 306567bab..e131bfa43 100644 --- a/src/SAML2/Assertion/Processor.php +++ b/src/SAML2/Assertion/Processor.php @@ -5,7 +5,6 @@ namespace SAML2\Assertion; use Psr\Log\LoggerInterface; - use SAML2\Assertion; use SAML2\Assertion\Exception\InvalidAssertionException; use SAML2\Assertion\Exception\InvalidSubjectConfirmationException; @@ -15,7 +14,6 @@ use SAML2\Configuration\IdentityProvider; use SAML2\EncryptedAssertion; use SAML2\Response\Exception\InvalidSignatureException; -use SAML2\Response\Exception\UnencryptedAssertionFoundException; use SAML2\Signature\Validator; use SAML2\Utilities\ArrayCollection; @@ -95,7 +93,13 @@ public function decryptAssertions(ArrayCollection $assertions) { $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..2a37a9567 --- /dev/null +++ b/tests/SAML2/Assertion/ProcessorTest.php @@ -0,0 +1,81 @@ +decrypter = m::mock(Decrypter::class); + $validator = m::mock(\SAML2\Signature\Validator::class); + $assertionValidator = m::mock(\SAML2\Assertion\Validation\AssertionValidator::class); + $subjectConfirmationValidator = m::mock(\SAML2\Assertion\Validation\SubjectConfirmationValidator::class); + $transformer = m::mock(\SAML2\Assertion\Transformer\Transformer::class); + $identityProvider = new \SAML2\Configuration\IdentityProvider([]); + $logger = m::mock(\Psr\Log\LoggerInterface::class); + + $this->processor = new Processor( + $this->decrypter, + $validator, + $assertionValidator, + $subjectConfirmationValidator, + $transformer, + $identityProvider, + $logger + ); + } + + /** + * @test + */ + public function processor_correctly_encrypts_assertions(): void + { + $testData = [ + [new \SAML2\Assertion()], + [new \SAML2\EncryptedAssertion()], + [new \SAML2\Assertion(), new \SAML2\EncryptedAssertion(), new \SAML2\Assertion()], + [new \SAML2\EncryptedAssertion(), new \SAML2\EncryptedAssertion(), new \SAML2\EncryptedAssertion()], + ]; + + foreach ($testData as $assertions) { + $this->decrypter + ->shouldReceive('decrypt') + ->andReturn(new \SAML2\Assertion()); + + $collection = new \SAML2\Utilities\ArrayCollection($assertions); + $result = $this->processor->decryptAssertions($collection); + self::assertInstanceOf(\SAML2\Utilities\ArrayCollection::class, $result); + foreach ($result as $assertion) { + self::assertInstanceOf(\SAML2\Assertion::class, $assertion); + } + } + } + + /** + * @test + */ + public function unsuported_assertions_are_rejected(): void + { + $this->expectException('\SAML2\Assertion\Exception\InvalidAssertionException'); + $this->expectExceptionMessage('The assertion must be of type: EncryptedAssertion or Assertion'); + $this->processor->decryptAssertions(new \SAML2\Utilities\ArrayCollection([new \stdClass()])); + } +}