View source
<?php
namespace Drupal\ldap_sso;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Routing\RedirectDestinationInterface;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\Url;
use Drupal\Core\Session\AccountInterface;
use Drupal\ldap_servers\Logger\LdapDetailLog;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
class LdapSsoBootSubscriber implements EventSubscriberInterface {
private $config;
private $logger;
private $frontpage;
private $currentPath;
private $detailLog;
protected $account;
protected $redirectDestination;
public function __construct(LoggerInterface $logger, ConfigFactory $configFactory, CurrentPathStack $currentPath, LdapDetailLog $detailLog, AccountInterface $account, RedirectDestinationInterface $redirect_destination) {
$this->logger = $logger;
$this->config = $configFactory
->get('ldap_sso.settings');
$this->frontpage = $configFactory
->get('system.site')
->get('frontpage');
$this->currentPath = $currentPath;
$this->detailLog = $detailLog;
$this->account = $account;
$this->redirectDestination = $redirect_destination;
}
public function checkSsoLoad(GetResponseEvent $event) {
if (PHP_SAPI === 'cli' || $this->account
->isAnonymous() == FALSE) {
$this->detailLog
->log('CLI or logged in user, no SSO.', [], 'ldap_sso');
return;
}
elseif (!$this->config
->get('seamlessLogin')) {
$this->detailLog
->log('Automated SSO not active.', [], 'ldap_sso');
return;
}
elseif ($this
->checkExcludePath()) {
$this->detailLog
->log('Excluded path', [], 'ldap_sso');
return;
}
elseif (isset($_COOKIE['sso_login_running'])) {
$this->detailLog
->log('SSO login running cookie present, aborting.', [], 'ldap_sso');
exit(0);
}
elseif (isset($_COOKIE['sso_stop'])) {
$this->detailLog
->log('Anonymous user with cookie to not continue SSO login', [], 'ldap_sso');
return;
}
else {
$this->detailLog
->log('Transferring to login controller', [], 'ldap_sso');
$this
->transferSsoLoginController();
exit(0);
}
}
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = [
'checkSsoLoad',
20,
];
return $events;
}
private function transferSsoLoginController() {
$original_path = $this->redirectDestination
->get();
$pathWithDestination = Url::fromRoute('ldap_sso.login_controller')
->toString() . '?destination=' . $original_path;
$cookies[] = new Cookie('sso_login_running', 'true', 0, base_path());
$response = new RedirectResponseWithCookie($pathWithDestination, 302, $cookies);
$response
->send();
}
private function defaultPathsToExclude() {
return [
'/admin/config/search/clean-urls/check',
'/user/login/sso',
'/user/login',
'/user/logout',
'/user',
];
}
private function checkExcludePath($path = FALSE) {
$result = FALSE;
if ($path) {
}
elseif ($_SERVER['PHP_SELF'] == '/index.php') {
$path = $this->currentPath
->getPath();
}
else {
$path = ltrim($_SERVER['PHP_SELF'], '/');
}
if (in_array($path, $this
->defaultPathsToExclude())) {
return TRUE;
}
if (is_array($this->config
->get('ssoExcludedHosts'))) {
$host = $_SERVER['SERVER_NAME'];
foreach ($this->config
->get('ssoExcludedHosts') as $host_to_check) {
if ($host_to_check == $host) {
return TRUE;
}
}
}
if ($this->config
->get('ssoExcludedPaths')) {
$patterns = implode("\r\n", $this->config
->get('ssoExcludedPaths'));
if ($patterns) {
if (function_exists('drupal_get_path_alias')) {
$path = drupal_get_path_alias($path);
}
$path = mb_strtolower($path);
$to_replace = [
'/(\\r\\n?|\\n)/',
'/\\\\\\*/',
'/(^|\\|)\\\\<front\\\\>($|\\|)/',
];
$replacements = [
'|',
'.*',
'\\1' . preg_quote($this->frontpage, '/') . '\\2',
];
$patterns_quoted = preg_quote($patterns, '/');
$regex = '/^(' . preg_replace($to_replace, $replacements, $patterns_quoted) . ')$/';
$result = (bool) preg_match($regex, $path);
}
}
return $result;
}
}