Issue #1794754 by rootatwc, Lars Toomre: Convert ban_boot() to an event listener.
parent
7bd2274ba4
commit
d798223e32
|
@ -6,11 +6,14 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Page callback; Displays banned IP addresses.
|
||||
* Page callback: Displays banned IP addresses.
|
||||
*
|
||||
* @param string $default_ip
|
||||
* (optional) IP address to be passed on to drupal_get_form() for
|
||||
* use as the default value of the IP address form field.
|
||||
* (optional) IP address to be passed on to drupal_get_form() for use as the
|
||||
* default value of the IP address form field.
|
||||
*
|
||||
* @return array
|
||||
* A render array.
|
||||
*/
|
||||
function ban_admin_page($default_ip = '') {
|
||||
$rows = array();
|
||||
|
@ -53,7 +56,6 @@ function ban_admin_page($default_ip = '') {
|
|||
*
|
||||
* @see ban_ip_form_validate()
|
||||
* @see ban_ip_form_submit()
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function ban_ip_form($form, &$form_state, $default_ip) {
|
||||
|
@ -119,7 +121,7 @@ function ban_ip_delete_form($form, &$form_state, array $ban_ip) {
|
|||
'#value' => $ban_ip,
|
||||
);
|
||||
return confirm_form($form,
|
||||
t('Are you sure you want to delete %ip?', array('%ip' => $ban_ip['ip'])),
|
||||
t('Are you sure you want to unblock %ip?', array('%ip' => $ban_ip['ip'])),
|
||||
'admin/config/people/ban',
|
||||
NULL,
|
||||
t('Delete')
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Enables banning of IP addresses.
|
||||
* Allows to ban individual IP addresses.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,7 @@ function ban_help($path, $arg) {
|
|||
case 'admin/help#ban':
|
||||
$output = '';
|
||||
$output .= '<h3>' . t('About') . '</h3>';
|
||||
$output .= '<p>' . t('The Ban module allows administrators to ban visits to their site from given IP addresses.') . '</p>';
|
||||
$output .= '<p>' . t('The Ban module allows administrators to ban visits to their site from individual IP addresses.') . '</p>';
|
||||
$output .= '<h3>' . t('Uses') . '</h3>';
|
||||
$output .= '<dl>';
|
||||
$output .= '<dt>' . t('Banning IP addresses') . '</dt>';
|
||||
|
@ -59,61 +59,6 @@ function ban_menu() {
|
|||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_boot().
|
||||
*/
|
||||
function ban_boot() {
|
||||
ban_block_denied(ip_address());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an IP address is blocked.
|
||||
*
|
||||
* Blocked IP addresses are stored in the database by default. However, for
|
||||
* performance reasons we allow an override in variables.
|
||||
*
|
||||
* @param string $ip
|
||||
* The IP address to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if access is denied, FALSE if access is allowed.
|
||||
*/
|
||||
function ban_is_denied($ip) {
|
||||
$denied = FALSE;
|
||||
// Because this function is called on every page request, we first check
|
||||
// for an array of IP addresses in settings.php before querying the
|
||||
// database.
|
||||
$blocked_ips = variable_get('ban_ips');
|
||||
if (isset($blocked_ips) && is_array($blocked_ips)) {
|
||||
$denied = in_array($ip, $blocked_ips);
|
||||
}
|
||||
// If $conf['page_cache_without_database'] = TRUE; is set in settings.php,
|
||||
// then the database is not available yet, so IPs recorded in the database
|
||||
// won't be denied. However, the user asked explicitly not to use the
|
||||
// database, and in this case it's also quite likely that the user relies
|
||||
// on higher performance solutions like a firewall.
|
||||
elseif (class_exists('Drupal\Core\Database\Database', FALSE) && function_exists('db_query')) {
|
||||
$denied = (bool) db_query("SELECT 1 FROM {ban_ip} WHERE ip = :ip", array(':ip' => $ip))->fetchField();
|
||||
}
|
||||
return $denied;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message and exits if access from a given IP address is denied.
|
||||
*
|
||||
* @param string $ip
|
||||
* The IP address to check.
|
||||
*/
|
||||
function ban_block_denied($ip) {
|
||||
// Check whether the given IP address has been blocked.
|
||||
if (ban_is_denied($ip)) {
|
||||
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
|
||||
// t() is not yet available.
|
||||
print 'Sorry, ' . check_plain($ip) . ' has been banned.';
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a banned IP address record from the database.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\ban\BanBundle.
|
||||
*/
|
||||
|
||||
namespace Drupal\ban;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
/**
|
||||
* Defines the Ban bundle.
|
||||
*/
|
||||
class BanBundle extends Bundle {
|
||||
|
||||
/**
|
||||
* Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
|
||||
*/
|
||||
public function build(ContainerBuilder $container) {
|
||||
$container->register('ban.ip_manager', 'Drupal\ban\BanIpManager')
|
||||
->addArgument(new Reference('database'));
|
||||
$container->register('ban.subscriber', 'Drupal\ban\EventSubscriber\BanSubscriber')
|
||||
->addArgument(new Reference('ban.ip_manager'))
|
||||
->addTag('event_subscriber');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\ban\BanIpManager.
|
||||
*/
|
||||
|
||||
namespace Drupal\ban;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
|
||||
/**
|
||||
* Ban IP manager.
|
||||
*/
|
||||
class BanIpManager {
|
||||
|
||||
/**
|
||||
* The database connection used to check the IP against.
|
||||
*
|
||||
* @var Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Construct the BanSubscriber.
|
||||
*
|
||||
* @param Drupal\Core\Database\Connection $connection
|
||||
* The database connection which will be used to check the IP against.
|
||||
*/
|
||||
public function __construct(Connection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an IP address is blocked.
|
||||
*
|
||||
* @param string $ip
|
||||
* The IP address to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if access is denied, FALSE if access is allowed.
|
||||
*/
|
||||
public function isDenied($ip) {
|
||||
$denied = $this->connection
|
||||
->query('SELECT 1 FROM {ban_ip} WHERE ip = :ip', array(':ip' => $ip))
|
||||
->fetchField();
|
||||
return (bool) $denied;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\ban\EventSubscriber\BanSubscriber.
|
||||
*/
|
||||
|
||||
namespace Drupal\ban\EventSubscriber;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
use Drupal\ban\BanIpManager;
|
||||
|
||||
/**
|
||||
* Ban subscriber for controller requests.
|
||||
*/
|
||||
class BanSubscriber implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* The manager used to check the IP against.
|
||||
*
|
||||
* @var Drupal\ban\BanIpManager
|
||||
*/
|
||||
protected $manager;
|
||||
|
||||
/**
|
||||
* Construct the BanSubscriber.
|
||||
*
|
||||
* @param Drupal\ban\BanIpManager $manager
|
||||
* The manager used to check the IP against.
|
||||
*/
|
||||
public function __construct(BanIpManager $manager) {
|
||||
$this->manager = $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Response with 403 if the visitor's IP adress is banned.
|
||||
*
|
||||
* @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
|
||||
* The Event to process.
|
||||
*/
|
||||
public function onKernelRequestBannedIpCheck(GetResponseEvent $event) {
|
||||
// @todo convert this to Request::getClientIP().
|
||||
$ip = ip_address();
|
||||
if ($this->manager->isDenied($ip)) {
|
||||
$response = new Response('Sorry, ' . check_plain($ip) . ' has been banned.', 403);
|
||||
$event->setResponse($response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the methods in this class that should be listeners.
|
||||
*
|
||||
* @return array
|
||||
* An array of event listener definitions.
|
||||
*/
|
||||
static function getSubscribedEvents() {
|
||||
$events[KernelEvents::REQUEST][] = array('onKernelRequestBannedIpCheck', 40);
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
|
@ -50,7 +50,7 @@ class StatisticsBlockVisitorsTest extends StatisticsTestBase {
|
|||
|
||||
// Unblock the IP address.
|
||||
$this->clickLink('unban IP address');
|
||||
$this->assertRaw(t('Are you sure you want to delete %ip?', array('%ip' => $test_ip_address)), 'IP address deletion confirmation found.');
|
||||
$this->assertRaw(t('Are you sure you want to unblock %ip?', array('%ip' => $test_ip_address)), 'IP address deletion confirmation found.');
|
||||
$edit = array();
|
||||
$this->drupalPost('admin/config/people/ban/delete/1', NULL, t('Delete'));
|
||||
$this->assertRaw(t('The IP address %ip was deleted.', array('%ip' => $test_ip_address)), 'IP address deleted.');
|
||||
|
|
|
@ -475,25 +475,6 @@ ini_set('session.cookie_lifetime', 2000000);
|
|||
# '@count min' => '@count minutes',
|
||||
# );
|
||||
|
||||
/**
|
||||
* IP blocking (Ban module).
|
||||
*
|
||||
* To bypass database queries for denied IP addresses, use this setting.
|
||||
* Ban module queries the {ban_ip} table by default on every page request
|
||||
* for both authenticated and anonymous users. This allows the system to
|
||||
* block IP addresses from within the administrative interface and before any
|
||||
* modules are loaded. However on high traffic websites you may want to avoid
|
||||
* this query, allowing you to bypass database access altogether for anonymous
|
||||
* users under certain caching configurations.
|
||||
*
|
||||
* If using this setting, you will need to add back any IP addresses which
|
||||
* you may have blocked via the administrative interface. Each element of this
|
||||
* array represents a blocked IP address.
|
||||
*
|
||||
* Remove the leading hash signs to enable.
|
||||
*/
|
||||
# $conf['ban_ips'][] = 'a.b.c.d';
|
||||
|
||||
/**
|
||||
* Fast 404 pages:
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue