ShieldMiddleware.php in Shield 8
File
src/ShieldMiddleware.php
View source
<?php
namespace Drupal\shield;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Path\PathMatcherInterface;
use Symfony\Component\HttpFoundation\IpUtils;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class ShieldMiddleware implements HttpKernelInterface {
protected $httpKernel;
protected $configFactory;
protected $entityTypeManager;
protected $pathMatcher;
public function __construct(HttpKernelInterface $http_kernel, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, PathMatcherInterface $path_matcher) {
$this->httpKernel = $http_kernel;
$this->configFactory = $config_factory;
$this->entityTypeManager = $entity_type_manager;
$this->pathMatcher = $path_matcher;
}
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
$config = $this->configFactory
->get('shield.settings');
$allow_cli = $config
->get('allow_cli');
$user = NULL;
switch ($config
->get('credential_provider')) {
case 'shield':
$user = $config
->get('credentials.shield.user');
$pass = $config
->get('credentials.shield.pass');
break;
case 'key':
$user = $config
->get('credentials.key.user');
$storage = $this->entityTypeManager
->getStorage('key');
$pass_key = $storage
->load($config
->get('credentials.key.pass_key'));
if ($pass_key) {
$pass = $pass_key
->getKeyValue();
}
break;
case 'multikey':
$storage = $this->entityTypeManager
->getStorage('key');
$user_pass_key = $storage
->load($config
->get('credentials.multikey.user_pass_key'));
if ($user_pass_key) {
$values = $user_pass_key
->getKeyValues();
$user = $values['username'];
$pass = $values['password'];
}
break;
}
$shield_enabled = $config
->get('shield_enable') && !empty($user);
if (!$shield_enabled || $type != self::MASTER_REQUEST || PHP_SAPI === 'cli' && $allow_cli) {
return $this->httpKernel
->handle($request, $type, $catch);
}
else {
$in_whitelist = FALSE;
if ($whitelist = $config
->get('whitelist')) {
$whitelist = array_filter(array_map('trim', explode("\n", $whitelist)));
$in_whitelist = IpUtils::checkIp($request
->getClientIp(), $whitelist);
}
$allow_domain = FALSE;
if ($domains = $config
->get('domains')) {
if (!empty($domains)) {
$allow_domain = $this->pathMatcher
->matchPath($request
->getHost(), $domains);
}
}
if ($request->server
->has('PHP_AUTH_USER') && $request->server
->has('PHP_AUTH_PW')) {
$input_user = $request->server
->get('PHP_AUTH_USER');
$input_pass = $request->server
->get('PHP_AUTH_PW');
}
elseif (!empty($request->server
->get('HTTP_AUTHORIZATION'))) {
list($input_user, $input_pass) = explode(':', base64_decode(substr($request->server
->get('HTTP_AUTHORIZATION'), 6)), 2);
}
elseif (!empty($request->server
->get('REDIRECT_HTTP_AUTHORIZATION'))) {
list($input_user, $input_pass) = explode(':', base64_decode(substr($request->server
->get('REDIRECT_HTTP_AUTHORIZATION'), 6)), 2);
}
$authenticated = isset($input_user) && $input_user === $user && hash_equals($pass, $input_pass);
if ($in_whitelist || $authenticated || $allow_domain) {
return $this->httpKernel
->handle($request, $type, $catch);
}
}
$response = new Response();
$response->headers
->add([
'WWW-Authenticate' => 'Basic realm="' . strtr($config
->get('print'), [
'[user]' => $user,
'[pass]' => $pass,
]) . '"',
]);
$response
->setStatusCode(401);
return $response;
}
}