drupalauth4ssp-8.x-1.1/src/SspHandler.php
src/SspHandler.php
<?php
namespace Drupal\drupalauth4ssp;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Path\PathMatcherInterface;
use SimpleSAML\Auth\State;
use SimpleSAML\Configuration;
use SimpleSAML\Module\drupalauth\Auth\Source\External;
use SimpleSAML\Session;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* SimpleSamlPHP handler service.
*/
final class SspHandler {
/**
* The configuration settings of this module.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
protected $config;
/**
* The path matcher service.
*
* @var \Drupal\Core\Path\PathMatcherInterface
*/
protected $pathMatcher;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* The user session.
*
* @var \SimpleSAML\Session
*/
protected $sspSession;
/**
* Constructs a config object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* Configuration factory.
* @param \Drupal\Core\Path\PathMatcherInterface $pathMatcher
* Path matcher service.
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* Request stack.
*/
public function __construct(ConfigFactoryInterface $configFactory, PathMatcherInterface $pathMatcher, RequestStack $requestStack) {
$this->config = $configFactory->get('drupalauth4ssp.settings');
$this->pathMatcher = $pathMatcher;
$this->request = $requestStack->getCurrentRequest();
}
/**
* Check if the path is allowed.
*
* @param string $path
* Path to check.
*
* @return bool
* Allowed or not.
*/
public function returnPathIsAllowed($path) {
$returnto_list = $this->config->get('returnto_list');
// Check the ReturnTo if it's in the allowed list.
return $this->pathMatcher->matchPath($path, implode(PHP_EOL, $returnto_list));
}
/**
* Get SimpleSAMLphp base path.
*/
public function getSspBasePath() {
return Configuration::getInstance()->getBasePath();
}
/**
* Log out from SimpleSAMLphp.
*/
public function logout() {
// Invalidate SimpleSAML session by expiring it.
$session = $this->getSspSession();
foreach ($session->getAuthorities() as $authority) {
$session->setAuthorityExpire($authority, 1);
}
$returnTo = $this->request->query->get('ReturnTo');
$destination = &drupal_static('drupalauth4ssp_user_logout');
// In any case below $destination is used to pass redirect destination to
// DrupalAuthForSSPSubscriber::checkRedirection().
if (empty($returnTo)) {
// IdP-initiated logout.
$idp_logout_returnto = $this->config->get('idp_logout_returnto');
if (empty($idp_logout_returnto)) {
$idp_logout_returnto = \base_path();
}
$destination = $this->getSspBasePath() . 'saml2/idp/SingleLogoutService.php?ReturnTo=' . $idp_logout_returnto;
}
else {
// If the ReturnTo URL is present, send the user to the URL.
// Check the ReturnTo if it's in the allowed list.
if ($this->returnPathIsAllowed($returnTo)) {
$destination = $returnTo;
}
}
}
/**
* Save account ID to SSP state.
*
* @param int $id
* Account ID.
* @param string $stateId
* SimpleSAMLphp state ID.
*/
public function saveIdToStat($id, $stateId) {
// We will let External::resume() deal with missing account ID.
if ($state = State::loadState($stateId, External::DRUPALAUTH_EXTERNAL, TRUE)) {
$state[External::DRUPALAUTH_EXTERNAL_USER_ID] = $id;
State::saveState($state, External::DRUPALAUTH_EXTERNAL);
}
}
/**
* Returns SSP session.
*
* @return \SimpleSAML\Session
* SimpleSAMLphp session.
*/
protected function getSspSession() {
if (!$this->sspSession instanceof Session) {
$this->sspSession = Session::getSessionFromRequest();
}
return $this->sspSession;
}
}
