1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
<?php
if (!isset($_REQUEST['id'])) {
throw new \SimpleSAML\Error\BadRequest('Missing required parameter: id');
}
/** @psalm-var array $state */
$state = \SimpleSAML\Auth\State::loadState($_REQUEST['id'], 'core:Logout-IFrame');
$idp = \SimpleSAML\IdP::getByState($state);
$associations = $idp->getAssociations();
if (!isset($_REQUEST['cancel'])) {
\SimpleSAML\Logger::stats('slo-iframe done');
\SimpleSAML\Stats::log('core:idp:logout-iframe:page', ['type' => 'done']);
$SPs = $state['core:Logout-IFrame:Associations'];
} else {
// user skipped global logout
\SimpleSAML\Logger::stats('slo-iframe skip');
\SimpleSAML\Stats::log('core:idp:logout-iframe:page', ['type' => 'skip']);
$SPs = []; // no SPs should have been logged out
$state['core:Failed'] = true; // mark as partial logout
}
// find the status of all SPs
foreach ($SPs as $assocId => &$sp) {
$spId = 'logout-iframe-' . sha1($assocId);
if (isset($_REQUEST[$spId])) {
$spStatus = $_REQUEST[$spId];
if ($spStatus === 'completed' || $spStatus === 'failed') {
$sp['core:Logout-IFrame:State'] = $spStatus;
}
}
if (!isset($associations[$assocId])) {
$sp['core:Logout-IFrame:State'] = 'completed';
}
}
// terminate the associations
foreach ($SPs as $assocId => $sp) {
if ($sp['core:Logout-IFrame:State'] === 'completed') {
$idp->terminateAssociation($assocId);
} else {
\SimpleSAML\Logger::warning('Unable to terminate association with ' . var_export($assocId, true) . '.');
if (isset($sp['saml:entityID'])) {
$spId = $sp['saml:entityID'];
} else {
$spId = $assocId;
}
\SimpleSAML\Logger::stats('slo-iframe-fail ' . $spId);
\SimpleSAML\Stats::log('core:idp:logout-iframe:spfail', ['sp' => $spId]);
$state['core:Failed'] = true;
}
}
// we are done
$idp->finishLogout($state);
|