CasLogout.php in CAS 8
File
src/Service/CasLogout.php
View source
<?php
namespace Drupal\cas\Service;
use Drupal\cas\Exception\CasSloException;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Psr\Log\LogLevel;
class CasLogout {
protected $casHelper;
protected $connection;
protected $settings;
public function __construct(CasHelper $cas_helper, Connection $database_connection, ConfigFactoryInterface $config_factory) {
$this->casHelper = $cas_helper;
$this->connection = $database_connection;
$this->settings = $config_factory
->get('cas.settings');
}
public function handleSlo($data) {
$this->casHelper
->log(LogLevel::DEBUG, "Attempting to handle single-log-out request.");
if (!$this->settings
->get('logout.enable_single_logout')) {
$this->casHelper
->log(LogLevel::DEBUG, "Aborting single-log-out handling; it's not enabled in the CAS settings.");
return;
}
$service_ticket = $this
->getServiceTicketFromData($data);
$this->casHelper
->log(LogLevel::DEBUG, 'Service ticket %ticket extracted from single-log-out request.', [
'%ticket' => $service_ticket,
]);
$sid = $this
->lookupSessionIdByServiceTicket($service_ticket);
if (!$sid) {
$this->casHelper
->log(LogLevel::DEBUG, 'No matching session found for %ticket', [
'%ticket' => $service_ticket,
]);
return;
}
$this
->destroySession($sid);
$this
->removeSessionMapping($sid);
$this->casHelper
->log(LogLevel::DEBUG, "Single-log-out request completed successfully.");
}
protected function destroySession($sid) {
session_id($sid);
session_start();
session_destroy();
session_write_close();
}
private function getServiceTicketFromData($data) {
$dom = new \DOMDocument();
$dom->preserveWhiteSpace = FALSE;
$dom->encoding = "utf-8";
if ($dom
->loadXML($data) === FALSE) {
throw new CasSloException("SLO data from CAS server is not valid.");
}
$session_elements = $dom
->getElementsByTagName('SessionIndex');
if ($session_elements->length == 0) {
throw new CasSloException("SLO data from CAS server is not valid.");
}
$session_element = $session_elements
->item(0);
return $session_element->nodeValue;
}
private function lookupSessionIdByServiceTicket($ticket) {
$result = $this->connection
->select('cas_login_data', 'c')
->fields('c', [
'plainsid',
])
->condition('ticket', $ticket)
->execute()
->fetch();
if (!empty($result)) {
return $result->plainsid;
}
else {
return NULL;
}
}
private function removeSessionMapping($sid) {
$this->connection
->delete('cas_login_data')
->condition('plainsid', $sid)
->execute();
}
}