| 
<?php
 if (!isset($_REQUEST['id'])) {
 throw new SimpleSAML_Error_BadRequest('Missing required parameter: id');
 }
 $id = (string)$_REQUEST['id'];
 
 if (isset($_REQUEST['type'])) {
 $type = (string)$_REQUEST['type'];
 if (!in_array($type, array('init', 'js', 'nojs', 'embed'), TRUE)) {
 throw new SimpleSAML_Error_BadRequest('Invalid value for type.');
 }
 } else {
 $type = 'init';
 }
 
 if ($type !== 'embed' && $type !== 'async') {
 SimpleSAML_Logger::stats('slo-iframe ' . $type);
 SimpleSAML_Stats::log('core:idp:logout-iframe:page', array('type' => $type));
 }
 
 // sanitize the input
 $sid = SimpleSAML_Utilities::parseStateID($id);
 if (!is_null($sid['url'])) {
 SimpleSAML_Utilities::checkURLAllowed($sid['url']);
 }
 
 $state = SimpleSAML_Auth_State::loadState($id, 'core:Logout-IFrame');
 $idp = SimpleSAML_IdP::getByState($state);
 
 if ($type !== 'init') {
 /* Update association state. */
 
 $associations = $idp->getAssociations();
 
 foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {
 
 $spId = sha1($assocId);
 
 /* Move SPs from 'onhold' to 'inprogress'. */
 if ($sp['core:Logout-IFrame:State'] === 'onhold') {
 $sp['core:Logout-IFrame:State'] = 'inprogress';
 }
 
 /* Check for update through request. */
 if (isset($_REQUEST[$spId])) {
 $s = $_REQUEST[$spId];
 if ($s == 'completed' || $s == 'failed') {
 $sp['core:Logout-IFrame:State'] = $s;
 }
 }
 
 /* Check for timeout. */
 if (isset($sp['core:Logout-IFrame:Timeout']) && $sp['core:Logout-IFrame:Timeout'] < time()) {
 if ($sp['core:Logout-IFrame:State'] === 'inprogress') {
 $sp['core:Logout-IFrame:State'] = 'failed';
 }
 }
 
 /* In case we are refreshing a page. */
 if (!isset($associations[$assocId])) {
 $sp['core:Logout-IFrame:State'] = 'completed';
 }
 
 /* Update the IdP. */
 if ($sp['core:Logout-IFrame:State'] === 'completed') {
 $idp->terminateAssociation($assocId);
 }
 
 if (!isset($sp['core:Logout-IFrame:Timeout'])) {
 if (method_exists($sp['Handler'], 'getAssociationConfig')) {
 $assocIdP = SimpleSAML_IdP::getByState($sp);
 $assocConfig = call_user_func(array($sp['Handler'], 'getAssociationConfig'), $assocIdP, $sp);
 $sp['core:Logout-IFrame:Timeout'] = $assocConfig->getInteger('core:logout-timeout', 5) + time();
 } else {
 $sp['core:Logout-IFrame:Timeout'] = time() + 5;
 }
 }
 }
 }
 
 if ($type === 'js' || $type === 'nojs') {
 foreach ($state['core:Logout-IFrame:Associations'] as $assocId => &$sp) {
 
 if ($sp['core:Logout-IFrame:State'] !== 'inprogress') {
 /* This SP isn't logging out. */
 continue;
 }
 
 try {
 $assocIdP = SimpleSAML_IdP::getByState($sp);
 $url = call_user_func(array($sp['Handler'], 'getLogoutURL'), $assocIdP, $sp, NULL);
 $sp['core:Logout-IFrame:URL'] = $url;
 } catch (Exception $e) {
 $sp['core:Logout-IFrame:State'] = 'failed';
 }
 }
 }
 
 $id = SimpleSAML_Auth_State::saveState($state, 'core:Logout-IFrame');
 
 $globalConfig = SimpleSAML_Configuration::getInstance();
 
 if ($type === 'nojs') {
 $t = new SimpleSAML_XHTML_Template($globalConfig, 'core:logout-iframe-wrapper.php');
 $t->data['id'] = $id;
 $t->data['SPs'] = $state['core:Logout-IFrame:Associations'];
 $t->show();
 exit(0);
 }
 
 $t = new SimpleSAML_XHTML_Template($globalConfig, 'core:logout-iframe.php');
 $t->data['id'] = $id;
 $t->data['type'] = $type;
 $t->data['from'] = $state['core:Logout-IFrame:From'];
 $t->data['SPs'] = $state['core:Logout-IFrame:Associations'];
 $t->show();
 exit(0);
 
 |