diff --git a/library/EngineBlock/Corto/Filter/Command/EnforcePolicy.php b/library/EngineBlock/Corto/Filter/Command/EnforcePolicy.php index 014e17c6bf..fe0f7bb3d0 100644 --- a/library/EngineBlock/Corto/Filter/Command/EnforcePolicy.php +++ b/library/EngineBlock/Corto/Filter/Command/EnforcePolicy.php @@ -20,6 +20,13 @@ class EngineBlock_Corto_Filter_Command_EnforcePolicy extends EngineBlock_Corto_Filter_Command_Abstract { + /** + * @throws EngineBlock_Exception_UnknownRequesterIdInAuthnRequest + * @throws EngineBlock_Exception_UnknownServiceProvider + * @throws EngineBlock_Exception + * @throws EngineBlock_Corto_Exception_PEPNoAccess + * @throws EngineBlock_Exception_PdpCheckFailed + */ public function execute() { $log = EngineBlock_ApplicationSingleton::getLog(); @@ -54,8 +61,15 @@ public function execute() $log->debug("Policy Enforcement Point: Requesting decision from PDP"); - $pdp = $this->getPdpClient(); - $policyDecision = $pdp->requestDecisionFor($pdpRequest); + try { + $pdp = $this->getPdpClient(); + $policyDecision = $pdp->requestDecisionFor($pdpRequest); + } catch (\OpenConext\EngineBlock\Http\Exception\HttpException $e) { + throw new EngineBlock_Exception_PdpCheckFailed( + 'Policy Enforcement Point: Could not perform PDP check: ' . $e->getMessage() + ); + } + // The IdP logo is set after getting the PolicyDecision as it would be inappropriate to inject this into the // decision request. if ($this->_identityProvider->getMdui()->hasLogo()){ diff --git a/library/EngineBlock/Exception/PdpCheckFailed.php b/library/EngineBlock/Exception/PdpCheckFailed.php new file mode 100644 index 0000000000..43ddb63059 --- /dev/null +++ b/library/EngineBlock/Exception/PdpCheckFailed.php @@ -0,0 +1,21 @@ +expectException('EngineBlock_Exception_PdpCheckFailed'); + $this->expectExceptionMessage('Policy Enforcement Point: Could not perform PDP check: Resource could not be read (status code "503")'); + + $policy = new EngineBlock_Corto_Filter_Command_EnforcePolicy(); + + $request = $this->mockRequest(); + $policy->setRequest($request); + + $repo = Mockery::mock(MetadataRepositoryInterface::class); + $server = Mockery::mock(EngineBlock_Corto_ProxyServer::class); + $server->expects('getRepository')->andReturn($repo); + + $sp = $this->mockServiceProvider(); + + $policy->setServiceProvider($sp); + $policy->setProxyServer($server); + $policy->setResponseAttributes([]); + + $policy->setCollabPersonId('foo'); + + $idp = Mockery::mock(IdentityProvider::class); + $idp->entityId = 'bar'; + $policy->setIdentityProvider($idp); + + $policy->execute(); + } + + private function mockServiceProvider(): ServiceProvider + { + $sp = Mockery::mock(ServiceProvider::class); + $sp->entityId = 'bar'; + $sp->shouldReceive('getCoins->isTrustedProxy')->andReturn(false); + $sp->shouldReceive('getCoins->policyEnforcementDecisionRequired')->andReturn(true); + return $sp; + } + + private function mockRequest(): EngineBlock_Saml2_AuthnRequestAnnotationDecorator + { + $assertion = new Assertion(); + $request = new AuthnRequest(); + $response = new SAML2\Response(); + $response->setAssertions(array($assertion)); + return new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($request); + } + +}