private function factoryProxyServer()
 {
     $proxyServer = new EngineBlock_Corto_ProxyServer();
     $proxyServer->setHostName('test-host');
     $proxyServer->setRepository(new InMemoryMetadataRepository(array(new IdentityProvider('testIdp')), array()));
     return $proxyServer;
 }
 public function serve($serviceName)
 {
     if (!isset($_SESSION['consent'])) {
         throw new EngineBlock_Corto_Module_Services_SessionLostException('Session lost after consent');
     }
     if (!isset($_SESSION['consent'][$_POST['ID']]['response'])) {
         throw new EngineBlock_Corto_Module_Services_SessionLostException("Stored response for ResponseID '{$_POST['ID']}' not found");
     }
     /** @var SAML2_Response|EngineBlock_Saml2_ResponseAnnotationDecorator $response */
     $response = $_SESSION['consent'][$_POST['ID']]['response'];
     $request = $this->_server->getReceivedRequestFromResponse($response);
     $serviceProvider = $this->_server->getRepository()->fetchServiceProviderByEntityId($request->getIssuer());
     $destinationMetadata = EngineBlock_SamlHelper::getDestinationSpMetadata($serviceProvider, $request, $this->_server->getRepository());
     if (!isset($_POST['consent']) || $_POST['consent'] !== 'yes') {
         throw new EngineBlock_Corto_Exception_NoConsentProvided('No consent given...');
     }
     $attributes = $response->getAssertion()->getAttributes();
     $consent = $this->_consentFactory->create($this->_server, $response, $attributes);
     $consent->storeConsent($destinationMetadata);
     if ($consent->countTotalConsent() === 1) {
         $this->_sendIntroductionMail($attributes);
     }
     $response->setConsent(SAML2_Const::CONSENT_OBTAINED);
     $response->setDestination($response->getReturn());
     $response->setDeliverByBinding('INTERNAL');
     $this->_server->getBindingsModule()->send($response, $serviceProvider);
 }
 public function testConsentIsSkippedWhenDisabledPerSp()
 {
     $this->proxyServerMock->getRepository()->fetchIdentityProviderByEntityId('testIdP')->spsEntityIdsWithoutConsent[] = 'testSp';
     $provideConsentService = $this->factoryService();
     $provideConsentService->serve(null);
     Phake::verify($this->proxyServerMock->getBindingsModule())->send(Phake::capture($message), Phake::capture($metadata));
     $this->assertEquals('urn:oasis:names:tc:SAML:2.0:consent:inapplicable', $message->getConsent());
 }
 public function testResponseIsSent()
 {
     $processConsentService = $this->factoryService();
     Phake::when($this->proxyServerMock)->redirect(Phake::anyParameters())->thenReturn(null);
     Phake::when($this->proxyServerMock->getBindingsModule())->send(Phake::anyParameters())->thenReturn(null);
     $processConsentService->serve(null);
     Phake::verify($this->proxyServerMock->getBindingsModule())->send(Phake::anyParameters());
 }
 public static function createFromRequest(EngineBlock_Saml2_AuthnRequestAnnotationDecorator $originalRequest, IdentityProvider $idpMetadata, EngineBlock_Corto_ProxyServer $server)
 {
     $nameIdPolicy = array('AllowCreate' => 'true');
     /**
      * Name policy is not required, so it is only set if configured, SAML 2.0 spec
      * says only following values are allowed:
      *  - urn:oasis:names:tc:SAML:2.0:nameid-format:transient
      *  - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent.
      *
      * Note: Some IDP's like those using ADFS2 do not understand those, for these cases the format can be 'configured as empty
      * or set to an older version.
      */
     if (!empty($idpMetadata->nameIdFormat)) {
         $nameIdPolicy['Format'] = $idpMetadata->nameIdFormat;
     }
     /** @var SAML2_AuthnRequest $originalRequest */
     $sspRequest = new SAML2_AuthnRequest();
     $sspRequest->setId($server->getNewId(\OpenConext\Component\EngineBlockFixtures\IdFrame::ID_USAGE_SAML2_REQUEST));
     $sspRequest->setIssueInstant(time());
     $sspRequest->setDestination($idpMetadata->singleSignOnServices[0]->location);
     $sspRequest->setForceAuthn($originalRequest->getForceAuthn());
     $sspRequest->setIsPassive($originalRequest->getIsPassive());
     $sspRequest->setAssertionConsumerServiceURL($server->getUrl('assertionConsumerService'));
     $sspRequest->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST);
     $sspRequest->setIssuer($server->getUrl('spMetadataService'));
     $sspRequest->setNameIdPolicy($nameIdPolicy);
     if (empty($idpMetadata->disableScoping)) {
         // Copy over the Idps that are allowed to answer this request.
         $sspRequest->setIDPList($originalRequest->getIDPList());
         // Proxy Count
         $sspRequest->setProxyCount($originalRequest->getProxyCount() ? $originalRequest->getProxyCount() : $server->getConfig('max_proxies', 10));
         // Add the SP to the requesterIds
         $requesterIds = $originalRequest->getRequesterID();
         $requesterIds[] = $originalRequest->getIssuer();
         // Add the SP as the requester
         $sspRequest->setRequesterID($requesterIds);
     }
     // Use the default binding even if more exist
     $request = new EngineBlock_Saml2_AuthnRequestAnnotationDecorator($sspRequest);
     $request->setDeliverByBinding($idpMetadata->singleSignOnServices[0]->binding);
     return $request;
 }
 private function getTraceHtml($xml)
 {
     if (!$this->_server->getConfig('debug', false)) {
         return '';
     }
     $doc = new DOMDocument();
     $doc->preserveWhiteSpace = false;
     $doc->formatOutput = true;
     $doc->loadXML($xml);
     $xml = $doc->saveXML();
     return htmlentities(trim($xml));
 }
 public function serve($serviceName)
 {
     $response = $this->_server->getBindingsModule()->receiveResponse();
     $_SESSION['consent'][$response->getId()]['response'] = $response;
     $request = $this->_server->getReceivedRequestFromResponse($response);
     $serviceProvider = $this->_server->getRepository()->fetchServiceProviderByEntityId($request->getIssuer());
     $spMetadataChain = EngineBlock_SamlHelper::getSpRequesterChain($serviceProvider, $request, $this->_server->getRepository());
     $identityProviderEntityId = $response->getOriginalIssuer();
     $identityProvider = $this->_server->getRepository()->fetchIdentityProviderByEntityId($identityProviderEntityId);
     // Flush log if SP or IdP has additional logging enabled
     $requireAdditionalLogging = EngineBlock_SamlHelper::doRemoteEntitiesRequireAdditionalLogging(array_merge($spMetadataChain, array($identityProvider)));
     if ($requireAdditionalLogging) {
         $application = EngineBlock_ApplicationSingleton::getInstance();
         $application->flushLog('Activated additional logging for one or more SPs in the SP requester chain, or the IdP');
         $log = $application->getLogInstance();
         $log->info('Raw HTTP request', array('http_request' => (string) $application->getHttpRequest()));
     }
     if ($this->isConsentDisabled($spMetadataChain, $identityProvider)) {
         $response->setConsent(SAML2_Const::CONSENT_INAPPLICABLE);
         $response->setDestination($response->getReturn());
         $response->setDeliverByBinding('INTERNAL');
         $this->_server->getBindingsModule()->send($response, $serviceProvider);
         return;
     }
     $consentDestinationEntityMetadata = $spMetadataChain[0];
     $attributes = $response->getAssertion()->getAttributes();
     $consent = $this->_consentFactory->create($this->_server, $response, $attributes);
     $priorConsent = $consent->hasStoredConsent($consentDestinationEntityMetadata);
     if ($priorConsent) {
         $response->setConsent(SAML2_Const::CONSENT_PRIOR);
         $response->setDestination($response->getReturn());
         $response->setDeliverByBinding('INTERNAL');
         $this->_server->getBindingsModule()->send($response, $serviceProvider);
         return;
     }
     $html = $this->_server->renderTemplate('consent', array('action' => $this->_server->getUrl('processConsentService'), 'ID' => $response->getId(), 'attributes' => $attributes, 'sp' => $consentDestinationEntityMetadata, 'idp' => $identityProvider));
     $this->_server->sendOutput($html);
 }
 /**
  * Creates a new Consent instance
  *
  * @param EngineBlock_Corto_ProxyServer $proxyServer
  * @param EngineBlock_Saml2_ResponseAnnotationDecorator $response
  * @param array $attributes
  * @return EngineBlock_Corto_Model_Consent
  */
 public function create(EngineBlock_Corto_ProxyServer $proxyServer, EngineBlock_Saml2_ResponseAnnotationDecorator $response, array $attributes)
 {
     return new EngineBlock_Corto_Model_Consent($proxyServer->getConfig('ConsentDbTable', 'consent'), $proxyServer->getConfig('ConsentStoreValues', true), $response, $attributes, $this->_databaseConnectionFactory);
 }
 /**
  * @param MetadataRepositoryInterface $metadataRepository
  * @param EngineBlock_X509_KeyPair $keyPair
  * @param EngineBlock_Corto_ProxyServer $proxyServer
  * @return ServiceProvider
  * @throws EngineBlock_Corto_ProxyServer_Exception
  * @throws EngineBlock_Exception
  */
 protected function getEngineSpRole(MetadataRepositoryInterface $metadataRepository, EngineBlock_X509_KeyPair $keyPair, EngineBlock_Corto_ProxyServer $proxyServer)
 {
     /**
      * Augment our own SP entry with stuff that can't be set via the Service Registry (yet)
      */
     $spEntityId = $proxyServer->getUrl('spMetadataService');
     $engineServiceProvider = $metadataRepository->findServiceProviderByEntityId($spEntityId);
     if (!$engineServiceProvider) {
         throw new EngineBlock_Exception("Unable to find EngineBlock configured as Service Provider. No '{$spEntityId}' in repository!");
     }
     $engineServiceProvider->certificates = array($keyPair->getCertificate());
     $engineServiceProvider->supportedNameIdFormats = array(SAML2_Const::NAMEID_PERSISTENT, SAML2_Const::NAMEID_TRANSIENT, SAML2_Const::NAMEID_UNSPECIFIED);
     $metadata = EngineBlock_ApplicationSingleton::getInstance()->getDiContainer()->getAttributeMetadata();
     $requestedAttributeIds = $metadata->findRequestedAttributeIds();
     $requiredAttributeIds = $metadata->findRequiredAttributeIds();
     $requestedAttributes = array();
     foreach ($requestedAttributeIds as $requestedAttributeId) {
         $requestedAttributes[] = new RequestedAttribute($requestedAttributeId);
     }
     foreach ($requiredAttributeIds as $requiredAttributeId) {
         $requestedAttributes[] = new RequestedAttribute($requiredAttributeId, true);
     }
     $engineServiceProvider->requestedAttributes = $requestedAttributes;
     // Allow all Identity Providers for EngineBlock.
     $engineServiceProvider->allowedIdpEntityIds = $metadataRepository->findAllIdentityProviderEntityIds();
     $engineServiceProvider->responseProcessingService = new Service($proxyServer->getUrl('provideConsentService'), 'INTERNAL');
     return $engineServiceProvider;
 }