/**
  * Ask the user for consent over all of the attributes being sent to the SP.
  *
  * Note this is part 1/2 of the Corto Consent Internal Response Processing service.
  *
  * @return void
  */
 public function provideConsentService()
 {
     $response = $this->_server->getBindingsModule()->receiveResponse();
     $_SESSION['consent'][$response['_ID']]['response'] = $response;
     $attributes = Corto_XmlToArray::attributes2array($response['saml:Assertion']['saml:AttributeStatement'][0]['saml:Attribute']);
     $serviceProviderEntityId = $attributes['ServiceProvider'][0];
     unset($attributes['ServiceProvider']);
     $spEntityMetadata = $this->_server->getRemoteEntity($serviceProviderEntityId);
     $identityProviderEntityId = $response['__']['OriginalIssuer'];
     $idpEntityMetadata = $this->_server->getRemoteEntity($identityProviderEntityId);
     $commonName = $attributes['urn:mace:dir:attribute-def:cn'][0];
     // Apply ARP
     $arpFilter = new EngineBlock_Corto_Filter_Command_AttributeReleasePolicy();
     $arpFilter->setIdpMetadata($idpEntityMetadata);
     $arpFilter->setSpMetadata($spEntityMetadata);
     $arpFilter->setResponseAttributes($attributes);
     $arpFilter->execute();
     $attributes = $arpFilter->getResponseAttributes();
     $priorConsent = $this->_hasStoredConsent($serviceProviderEntityId, $response, $attributes);
     if ($priorConsent) {
         $response['_Consent'] = 'urn:oasis:names:tc:SAML:2.0:consent:prior';
         $response['_Destination'] = $response['__']['Return'];
         $response['__']['ProtocolBinding'] = 'INTERNAL';
         $this->_server->getBindingsModule()->send($response, $spEntityMetadata);
         return;
     }
     if (isset($spEntityMetadata['NoConsentRequired']) && $spEntityMetadata['NoConsentRequired']) {
         $response['_Consent'] = 'urn:oasis:names:tc:SAML:2.0:consent:inapplicable';
         $response['_Destination'] = $response['__']['Return'];
         $response['__']['ProtocolBinding'] = 'INTERNAL';
         $this->_server->getBindingsModule()->send($response, $spEntityMetadata);
         return;
     }
     $html = $this->_server->renderTemplate('consent', array('action' => $this->_server->getCurrentEntityUrl('processConsentService'), 'ID' => $response['_ID'], 'attributes' => $attributes, 'sp' => $spEntityMetadata, 'idp' => $idpEntityMetadata, 'commonName' => $commonName));
     $this->_server->sendOutput($html);
 }
 /**
  *
  * @return void
  */
 public function processedAssertionConsumerService()
 {
     $response = $this->_server->getBindingsModule()->receiveResponse();
     $receivedRequest = $this->_server->getReceivedRequestFromResponse($response[Corto_XmlToArray::ATTRIBUTE_PFX . 'InResponseTo']);
     $remainingProcessingEntities =& $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['RemainingEntities'];
     if (!empty($remainingProcessingEntities)) {
         // Moar processing!
         $nextProcessingEntity = array_shift($remainingProcessingEntities);
         $this->_server->setProcessingMode();
         $newResponse = $this->_server->createEnhancedResponse($receivedRequest, $response);
         // Change the destiny of the received response
         $newResponse[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID'] = $response[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID'];
         $newResponse[Corto_XmlToArray::ATTRIBUTE_PFX . 'Destination'] = $nextProcessingEntity['Location'];
         $newResponse[Corto_XmlToArray::PRIVATE_PFX]['ProtocolBinding'] = $nextProcessingEntity['Binding'];
         $newResponse[Corto_XmlToArray::PRIVATE_PFX]['Return'] = $this->_server->getCurrentEntityUrl('processedAssertionConsumerService');
         $newResponse[Corto_XmlToArray::PRIVATE_PFX]['paramname'] = 'SAMLResponse';
         $this->_server->getBindingsModule()->send($newResponse, $nextProcessingEntity);
         return;
     } else {
         // Done processing! Send off to SP
         $response[Corto_XmlToArray::ATTRIBUTE_PFX . 'Destination'] = $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['OriginalDestination'];
         $response[Corto_XmlToArray::PRIVATE_PFX]['ProtocolBinding'] = $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['OriginalBinding'];
         $response[Corto_XmlToArray::PRIVATE_PFX]['OriginalIssuer'] = $_SESSION['Processing'][$receivedRequest[Corto_XmlToArray::ATTRIBUTE_PFX . 'ID']]['OriginalIssuer'];
         $responseAssertionAttributes =& $response['saml:Assertion']['saml:AttributeStatement'][0]['saml:Attribute'];
         $attributes = Corto_XmlToArray::attributes2array($responseAssertionAttributes);
         unset($attributes['ServiceProvider']);
         $responseAssertionAttributes = Corto_XmlToArray::array2attributes($attributes);
         $this->_server->unsetProcessingMode();
         // Cache the response
         if ($this->_server->getCurrentEntitySetting('keepsession', false)) {
             $this->_cacheResponse($receivedRequest, $response, self::RESPONSE_CACHE_TYPE_OUT);
         }
         $sentResponse = $this->_server->createEnhancedResponse($receivedRequest, $response);
         $this->_server->sendResponseToRequestIssuer($receivedRequest, $sentResponse);
         return;
     }
 }