Skip to content

Commit

Permalink
Add some more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Jul 23, 2024
1 parent 650333a commit 714c181
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 42 deletions.
60 changes: 35 additions & 25 deletions src/SAML2/Entity/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use SimpleSAML\SAML2\{Binding, HTTPArtifact, Metadata, StateProviderInterface, Utils};
use SimpleSAML\SAML2\Exception\{MetadataNotFoundException, RemoteException, RuntimeException};
use SimpleSAML\SAML2\Exception\Protocol\{RequestDeniedException, ResourceNotRecognizedException};
use SimpleSAML\SAML2\Process\Validation\ResponseValidator;
use SimpleSAML\SAML2\Process\Validator\ResponseValidator;
use SimpleSAML\SAML2\XML\saml\{
Assertion,
AttributeStatement,
Expand Down Expand Up @@ -41,7 +41,7 @@ final class ServiceProvider
protected ?Metadata\MetadataProviderInterface $metadataProvider = null;
protected ?StateProviderInterface $stateProvider = null;
protected ?StorageProviderInterface $storageProvider = null;
protected Metadata\IdentityProvider $idpMetadata;
protected ?Metadata\IdentityProvider $idpMetadata = null;


/**
Expand Down Expand Up @@ -70,6 +70,14 @@ public function __construct(
}


/**
*/
public function setStateProvider(StateProviderInterface $stateProvider): void
{
$this->stateProvider = $stateProvider;
}


/**
* Receive a verified, and optionally validated Response.
*
Expand Down Expand Up @@ -112,7 +120,7 @@ public function receiveResponse(ServerRequestInterface $request): Response
}

$rawResponse = $binding->receive($request);
Assert::isInstanceOf($rawResponse, Response::class, ResourceNotRecognizedException::class); // Wrong type if msg
Assert::isInstanceOf($rawResponse, Response::class, ResourceNotRecognizedException::class); // Wrong type of msg

// Will return a raw Response prior to any form of verification
if ($this->bypassResponseVerification === true) {
Expand All @@ -138,36 +146,38 @@ public function receiveResponse(ServerRequestInterface $request): Response
} catch (RuntimeException $e) {
// something went wrong,
Utils::getContainer()->getLogger()->warning(sprintf(
'Could not load state specified by InResponseTo: %s Processing response as unsolicited.',
'Could not load state specified by InResponseTo: %s; processing response as unsolicited.',
$e->getMessage(),
));
}
}

if ($state === null && $this->enableUnsolicited === false) {
throw new RequestDeniedException('Unsolicited responses are denied by configuration.');
}

// check that the issuer is the one we are expecting
Assert::keyExists($state, 'ExpectedIssuer');
$issuer = $verifiedResponse->getIssuer()->getValue();
if ($state === null) {
if ($this->enableUnsolicited === false) {
throw new RequestDeniedException('Unsolicited responses are denied by configuration.');
}
} else {
// check that the issuer is the one we are expecting
Assert::keyExists($state, 'ExpectedIssuer');
$issuer = $verifiedResponse->getIssuer()->getContent();

if ($state['ExpectedIssuer'] !== $issuer) {
throw new ResourceNotRecognizedException("Issuer doesn't match the one the AuthnRequest was sent to.");
}
if ($state['ExpectedIssuer'] !== $issuer) {
throw new ResourceNotRecognizedException("Issuer doesn't match the one the AuthnRequest was sent to.");
}

if ($this->metadataProvider === null) {
throw new RuntimeException(
"A MetadataProvider is required to be able to perform token decryption.",
);
}
if ($this->metadataProvider === null) {
throw new RuntimeException(
"A MetadataProvider is required to be able to perform token decryption.",
);
}

$this->idpMetadata = $this->metadataProvider->getIdPMetadata($issuer);
if ($this->idpMetadata === null) {
throw new MetadataNotFoundException(sprintf(
'No metadata found for remote identity provider with entityID: %s',
$issuer,
));
$this->idpMetadata = $this->metadataProvider->getIdPMetadata($issuer);
if ($this->idpMetadata === null) {
throw new MetadataNotFoundException(sprintf(
'No metadata found for remote identity provider with entityID: %s',
$issuer,
));
}
}

$responseValidator = ResponseValidator::createResponseValidator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace SimpleSAML\SAML2\Process\Validation;

use SimpleSAML\XML\SerializableElementInterface;

interface ConstraintValidatorInterface
{
/**
Expand All @@ -13,5 +15,5 @@ interface ConstraintValidatorInterface
*
* @throws \SimpleSAML\SAML2\Exception\ConstraintViolationException when the condition fails.
*/
public function validate(): void;
public function validate(SerializableElementInterface $element): void;
}
6 changes: 3 additions & 3 deletions src/SAML2/Process/Validation/Response/DestinationMatches.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use SimpleSAML\SAML2\Process\{ServiceProviderAwareInterface, ServiceProviderAwareTrait};
use SimpleSAML\SAML2\Process\Validation\ConstraintValidatorInterface;
use SimpleSAML\SAML2\XML\samlp\Response;
use SimpleSAML\XML\SerializableElementInterface;

final class DestinationMatches implements ConstraintValidatorInterface
{
Expand All @@ -26,9 +27,9 @@ public function __construct(


/**
* @param \SimpleSAML\SAML2\XML\samlp\Response $response
* @param \SimpleSAML\XML\SerializableElementInterface $response
*/
public function validate(Response $response): void
public function validate(SerializableElementInterface $response): void
{
// Validate that the destination matches the appropriate endpoint from the SP-metadata
foreach ($this->spMetadata->getAssertionConsumerService() as $assertionConsumerService) {
Expand All @@ -38,7 +39,6 @@ public function validate(Response $response): void
}
}
}

throw new ResourceNotRecognizedException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace SimpleSAML\SAML2\Process\Validation;
namespace SimpleSAML\SAML2\Process\Validator;

use SimpleSAML\SAML2\{Binding, Metadata};
use SimpleSAML\SAML2\Process\Validation\Response\{DestinationMatches, IsSuccessful};
Expand All @@ -16,26 +16,26 @@ class ResponseValidator implements ValidatorInterface
* @param \SimpleSAML\SAML2\Metadata\ServiceProvider The SP-metadata
*/
private function __construct(
protected Metadata\IdentityProvider $idpMetadata,
protected ?Metadata\IdentityProvider $idpMetadata,
protected Metadata\ServiceProvider $spMetadata,
) {
}


/**
* @param \SimpleSAML\SAML2\Metadata\IdentityProvider $idpMetadata
* @param \SimpleSAML\SAML2\Metadata\IdentityProvider|null $idpMetadata
* @param \SimpleSAML\SAML2\Metadata\ServiceProvider $spMetadata
* @param string $binding
* @return \SimpleSAML\SAML2\Validation\ResponseValidator
*/
public static function createResponseValidator(
Metadata\IdentityProvider $idpMetadata,
?Metadata\IdentityProvider $idpMetadata,
Metadata\ServiceProvider $spMetadata,
Binding $binding,
): ResponseValidator {
$validator = new self();
$validator->addConstraintValidator(new DestinationMatches($binding));
$validator->addConstraintValidator(new IsSuccesful());
$validator = new self($idpMetadata, $spMetadata);
$validator->addConstraintValidator(new DestinationMatches($spMetadata, $binding));
// $validator->addConstraintValidator(new IsSuccesful());

return $validator;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

declare(strict_types=1);

namespace SimpleSAML\SAML2\Process\Validation;
namespace SimpleSAML\SAML2\Process\Validator;

use SimpleSAML\XML\SerializableElementInterface;
use SimpleSAML\SAML2\Process\Validation\ConstraintValidatorInterface;

interface ValidatorInterface
{
Expand All @@ -21,5 +22,5 @@ public function validate(SerializableElementInterface $element): void;
/**
* Add a validation to the chain.
*/
public function addValidation(ConstraintValidatorInterface $validation);
public function addConstraintValidator(ConstraintValidatorInterface $validation);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

declare(strict_types=1);

namespace SimpleSAML\SAML2\Process\Validation;
namespace SimpleSAML\SAML2\Process\Validator;

use SimpleSAML\SAML2\Process\{IdentityProviderAwareInterface, ServiceProviderAwareInterface};
use SimpleSAML\SAML2\Process\Validation\ConstraintValidatorInterface;
use SimpleSAML\XML\SerializableElementInterface;

trait ValidatorTrait
Expand All @@ -18,7 +19,7 @@ trait ValidatorTrait
*
* @param \SimpleSAML\SAML2\Process\Validation\ConstraintValidatorInterface $validation
*/
public function addConstraintValidator(ConstraintValidationInterface $validator)
public function addConstraintValidator(ConstraintValidatorInterface $validator)
{
if ($validator instanceof IdentityProviderAwareInterface) {
$validator->setIdentityProvider($this->idpMetadata);
Expand All @@ -42,7 +43,7 @@ public function addConstraintValidator(ConstraintValidationInterface $validator)
public function validate(SerializableElementInterface $element): void
{
foreach ($this->validators as $validator) {
$this->validate($element);
$validator->validate($element);
}
}
}
Loading

0 comments on commit 714c181

Please sign in to comment.