class AutobanController in Automatic IP ban (Autoban) 8
Provides an Autoban functional.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\autoban\Controller\AutobanController
Expanded class hierarchy of AutobanController
7 files declare their use of AutobanController
- AutobanAnalyzeForm.php in src/
Form/ AutobanAnalyzeForm.php - AutobanBanForm.php in src/
Form/ AutobanBanForm.php - AutobanDbLogController.php in modules/
autoban_dblog/ src/ Controller/ AutobanDbLogController.php - Contains \Drupal\autoban_dblog\Controller\AutobanDbLogController.php .
- AutobanDeleteAllForm.php in src/
Form/ AutobanDeleteAllForm.php - AutobanFormBase.php in src/
Form/ AutobanFormBase.php - Class AutobanFormBase.
1 string reference to 'AutobanController'
1 service uses AutobanController
File
- src/
Controller/ AutobanController.php, line 16
Namespace
Drupal\autoban\ControllerView source
class AutobanController extends ControllerBase {
/**
* Retrieve IP addresses for autoban rule.
*
* @param string $rule
* Autoban rule ID.
* @param array $params
* Params (type, message) for special query.
*
* @return array
* IP addresses as query result.
*/
public function getBannedIp($rule, array $params = []) {
$query_mode = $this
->config('autoban.settings')
->get('autoban_query_mode');
$use_wildcards = $this
->config('autoban.settings')
->get('autoban_use_wildcards') ?: FALSE;
$regexp_query_mode = $query_mode == 'regexp';
$from_analyze = AutobanUtils::isFromAnalyze($rule) && !empty($params);
if ($from_analyze) {
$entity = NULL;
$message = Html::decodeEntities(trim($params['message']));
$type = trim($params['type']);
$threshold = 1;
$referer = NULL;
$user_type = AutobanUtils::AUTOBAN_USER_ANY;
}
else {
$entity = Autoban::load($rule);
$message = trim($entity->message);
$type = trim($entity->type);
$threshold = (int) $entity->threshold;
$referer = trim($entity->referer);
$user_type = (int) $entity->user_type;
}
$connection = Database::getConnection();
$query = $connection
->select('watchdog', 'log');
$query
->fields('log', [
'hostname',
]);
$group = $query
->orConditionGroup();
// Checking for multiple messages divided by separator.
$message_items = explode('|', $message);
if (count($message_items) > 1) {
foreach ($message_items as $message_item) {
if ($from_analyze) {
$group
->condition('log.message', trim($message_item))
->condition('log.variables', trim($message_item));
}
else {
if ($regexp_query_mode) {
$group
->condition('log.message', trim($message_item), 'REGEXP')
->condition('log.variables', trim($message_item), 'REGEXP');
}
else {
if (!$use_wildcards) {
$group
->condition('log.message', '%' . $query
->escapeLike(trim($message_item)) . '%', 'LIKE')
->condition('log.variables', '%' . $query
->escapeLike(trim($message_item)) . '%', 'LIKE');
}
else {
$group
->condition('log.message', trim($message_item), 'LIKE')
->condition('log.variables', trim($message_item), 'LIKE');
}
}
}
}
}
else {
if ($from_analyze) {
$group
->condition('log.message', $message)
->condition('log.variables', $message);
}
else {
if ($regexp_query_mode) {
$group
->condition('log.message', $message, 'REGEXP')
->condition('log.variables', $message, 'REGEXP');
}
else {
if (!$use_wildcards) {
$group
->condition('log.message', '%' . $query
->escapeLike($message) . '%', 'LIKE')
->condition('log.variables', '%' . $query
->escapeLike($message) . '%', 'LIKE');
}
else {
$group
->condition('log.message', $message, 'LIKE')
->condition('log.variables', $message, 'LIKE');
}
}
}
}
$query
->condition('log.type', $type)
->condition($group);
if (!empty($referer)) {
$query
->condition('log.referer', '%' . $query
->escapeLike($referer) . '%', 'LIKE');
}
if ($user_type > 0) {
switch ($user_type) {
case AutobanUtils::AUTOBAN_USER_ANONYMOUS:
// Anonymous.
$query
->condition('log.uid', 0);
break;
case AutobanUtils::AUTOBAN_USER_AUTHENTICATED:
// Authenticated.
$query
->condition('log.uid', 0, '>');
break;
}
}
$query
->groupBy('log.hostname');
$query
->addExpression('COUNT(log.hostname)', 'hcount');
$query
->having('COUNT(log.hostname) >= :cnt', [
':cnt' => $threshold,
]);
$result = $query
->execute()
->fetchAll();
return $result;
}
/**
* Get IP Ban Manager data from provider name.
*
* @param string $provider
* Ban provider ID.
*
* @return array
* Ban manager object, ban_name, ban_type.
*/
public function getBanManagerData($provider) {
// Retrieve Ban provider data for the current provider.
$banProvider = $this
->getBanProvidersList($provider);
if ($banProvider) {
// Get Ban Manager object from AutobanProviderInterface implementation.
$service = $banProvider['service'];
if ($service) {
$connection = Database::getConnection();
// Return Ban Provider's Ban IP Manager and Ban Type.
return [
'ban_manager' => $service
->getBanIpManager($connection),
'ban_name' => $service
->getName(),
'ban_type' => $service
->getBanType(),
];
}
}
return NULL;
}
/**
* Get IP Ban Manager data from autoban rule.
*
* @param string $rule
* Autoban rule ID.
*
* @return array
* Ban manager object and ban_type.
*/
public function getBanManagerDataRule($rule) {
$entity = Autoban::load($rule);
return $this
->getBanManagerData($entity->provider);
}
/**
* Get Ban providers list.
*
* @param string $provider_id
* Ban provider ID.
*
* @return array
* List ban providers or provider's data.
*/
public function getBanProvidersList($provider_id = NULL) {
$banProvidersList = [];
$container = \Drupal::getContainer();
$kernel = $container
->get('kernel');
// Get all services list.
$services = $kernel
->getCachedContainerDefinition()['services'];
foreach ($services as $service_id => $value) {
$service_def = unserialize($value);
if (!empty($service_def['properties']) && !empty($service_def['properties']['_serviceId'])) {
$service_id = $service_def['properties']['_serviceId'];
$aservices = explode('.', $service_id);
// Filter for services with ban_provider.
if (!empty($aservices[1]) && $aservices[1] == 'ban_provider') {
$service = $container
->get($service_id);
$id = $service
->getId();
$name = $service
->getName();
$banProvidersList[$id] = [
'name' => $name,
'service' => $service,
];
}
}
}
if (!empty($provider_id)) {
return isset($banProvidersList[$provider_id]) ? $banProvidersList[$provider_id] : NULL;
}
else {
return $banProvidersList;
}
}
/**
* Direct ban controller.
*
* @param string $ips
* IP addresses (comma delimited).
* @param string $provider
* Ban provider name.
*
* @return bool
* IP banned status.
*/
public function banIpAction($ips, $provider) {
$banManagerData = $this
->getBanManagerData($provider);
$ips_arr = explode(',', $ips);
foreach ($ips_arr as $ip) {
$banned = $this
->banIp($ip, $banManagerData, TRUE);
if ($banned) {
$this
->messenger()
->addMessage($this
->t('IP %ip has been banned (@provider).', [
'%ip' => $ip,
'@provider' => $banManagerData['ban_name'],
]));
}
else {
$this
->messenger()
->addMessage($this
->t('IP %ip has not been banned', [
'%ip' => $ip,
]), 'warning');
}
}
$destination = $this
->getDestinationArray();
if (!empty($destination)) {
$url = Url::fromUserInput($destination['destination']);
return new RedirectResponse($url
->toString());
}
}
/**
* Ban address.
*
* @param string $ip
* IP address.
* @param array $banManagerData
* Ban manager data.
* @param bool $debug
* Show debug message.
*
* @return bool
* IP banned status.
*/
public function banIp($ip, array $banManagerData, $debug = FALSE) {
if (empty($banManagerData)) {
if ($debug) {
$this
->messenger()
->addMessage($this
->t('Empty banManagerData.'), 'warning');
}
return FALSE;
}
$banManager = $banManagerData['ban_manager'];
if (!$this
->canIpBan($ip)) {
if ($debug) {
$this
->messenger()
->addMessage($this
->t('Cannot ban this IP.'), 'warning');
}
return FALSE;
}
if ($banManager
->isBanned($ip)) {
if ($debug) {
$this
->messenger()
->addMessage($this
->t('This IP already banned.'), 'warning');
}
return FALSE;
}
$banType = $banManagerData['ban_type'];
switch ($banType) {
case 'single':
$banManager
->banIp($ip);
break;
case 'range':
$ip_range = $this
->createIpRange($ip);
if (empty($ip_range)) {
// If cannot create IP range banned single IP.
$banManager
->banIp($ip);
}
else {
$banManager
->banIp($ip_range['ip_start'], $ip_range['ip_end']);
}
break;
}
return TRUE;
}
/**
* Ban addresses.
*
* @param array $ip_list
* IP addresses list.
* @param string $rule
* Autoban rule ID.
*
* @return int
* IP banned count.
*/
public function banIpList(array $ip_list, $rule) {
$count = 0;
if (!empty($ip_list) && $rule) {
// Retrieve Ban manager object for current rule.
$banManagerData = $this
->getBanManagerDataRule($rule);
if ($banManagerData) {
foreach ($ip_list as $item) {
$banStatus = $this
->banIp($item->hostname, $banManagerData);
if ($banStatus) {
$count++;
$this
->messenger()
->addMessage($this
->t('IP %ip has been banned (@provider).', [
'%ip' => $item->hostname,
'@provider' => $banManagerData['ban_name'],
]));
}
}
}
else {
$this
->messenger()
->addMessage($this
->t('No ban manager for rule %rule', [
'%rule' => $rule,
]), 'error');
}
}
return $count;
}
/**
* Check IP address for ban.
*
* @param string $ip
* IP candidate for ban.
*
* @return bool
* Can ban.
*/
public function canIpBan($ip) {
// You cannot ban your current IP address.
if ($ip == \Drupal::request()
->getClientIp()) {
return FALSE;
}
// The IP address must not be whitelisted.
if ($this
->whitelistIp($ip)) {
return FALSE;
}
return TRUE;
}
/**
* Is IP address in subnet?
*
* @param string $ip
* IP address for match check.
* @param string $network
* IP subnet.
* @param string $cidr
* CIDR.
*
* @return bool
* IP mathes for subnet.
*/
private function cidrMatch($ip, $network, $cidr) {
return (ip2long($ip) & ~((1 << 32 - $cidr) - 1)) == ip2long($network);
}
/**
* Is IP address in whitelist?
*
* @param string $ip
* IP address for check.
*
* @return bool
* IP address in whitelist.
*/
private function whitelistIp($ip) {
$autoban_whitelist = $this
->config('autoban.settings')
->get('autoban_whitelist');
if (!empty($autoban_whitelist)) {
$real_host = gethostbyaddr($ip);
$autoban_whitelist_arr = explode("\n", $autoban_whitelist);
foreach ($autoban_whitelist_arr as $whitelist_ip) {
$whitelist_ip = trim($whitelist_ip);
if (empty($whitelist_ip)) {
continue;
}
// Block comment.
if (substr($whitelist_ip, 0, 1) == '#') {
continue;
}
// Inline comment.
$whitelist_ip_arr = explode('#', $whitelist_ip);
if (count($whitelist_ip_arr) > 1) {
$whitelist_ip = trim($whitelist_ip_arr[0]);
}
$whitelist_ip_arr = explode('/', $whitelist_ip);
// CIDR match.
if (count($whitelist_ip_arr) > 1) {
$in_list = $this
->cidrMatch($ip, $whitelist_ip_arr[0], (int) $whitelist_ip_arr[1]);
}
else {
$in_list = $whitelist_ip == $ip;
}
if ($in_list) {
return TRUE;
}
// Check for domain.
if ($real_host) {
$real_host_arr = explode($whitelist_ip, $real_host);
if (count($real_host_arr) == 2 && empty($real_host_arr[1])) {
return TRUE;
}
}
}
}
return FALSE;
}
/**
* Create IP range from single IP.
*
* @param string $hostname
* IP address for ban.
*
* @return array
* IP range string for insert to ban table.
*/
private function createIpRange($hostname) {
// Make range IP from aaa.bbb.ccc.ddd to aaa.bbb.ccc.0 - aaa.bbb.ccc.255 .
if (!ip2long($hostname)) {
// Only IPV4 is available for IP range.
return NULL;
}
$parts = explode('.', $hostname);
if (count($parts) == 4) {
$parts[3] = '0';
$ip_start = implode('.', $parts);
$parts[3] = '255';
$ip_end = implode('.', $parts);
return [
'ip_start' => $ip_start,
'ip_end' => $ip_end,
];
}
return NULL;
}
/**
* Get user type names list.
*
* @param int $index
* User type index (optional).
*
* @return string|array
* User type name or user type names list.
*/
public function userTypeList($index = NULL) {
$user_types = [
AutobanUtils::AUTOBAN_USER_ANY => $this
->t('Any'),
AutobanUtils::AUTOBAN_USER_ANONYMOUS => $this
->t('Anonymous'),
AutobanUtils::AUTOBAN_USER_AUTHENTICATED => $this
->t('Authenticated'),
];
if ($index === NULL) {
return $user_types;
}
else {
if (!isset($user_types[$index])) {
$index = AutobanUtils::AUTOBAN_USER_ANY;
}
return $user_types[$index];
}
}
/**
* Get rule type names list.
*
* @param int $index
* Rule type index (optional).
*
* @return string|array
* User rule name or rule type names list.
*/
public function ruleTypeList($index = NULL) {
$rule_types = [
AutobanUtils::AUTOBAN_RULE_ANY => $this
->t('Any'),
AutobanUtils::AUTOBAN_RULE_MANUAL => $this
->t('Manual'),
AutobanUtils::AUTOBAN_RULE_AUTO => $this
->t('Automatic'),
];
if ($index === NULL) {
return $rule_types;
}
else {
if (!isset($rule_types[$index])) {
$index = AutobanUtils::AUTOBAN_RULE_ANY;
}
return $rule_types[$index];
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AutobanController:: |
public | function | Ban address. | |
AutobanController:: |
public | function | Direct ban controller. | |
AutobanController:: |
public | function | Ban addresses. | |
AutobanController:: |
public | function | Check IP address for ban. | |
AutobanController:: |
private | function | Is IP address in subnet? | |
AutobanController:: |
private | function | Create IP range from single IP. | |
AutobanController:: |
public | function | Get IP Ban Manager data from provider name. | |
AutobanController:: |
public | function | Get IP Ban Manager data from autoban rule. | |
AutobanController:: |
public | function | Retrieve IP addresses for autoban rule. | |
AutobanController:: |
public | function | Get Ban providers list. | |
AutobanController:: |
public | function | Get rule type names list. | |
AutobanController:: |
public | function | Get user type names list. | |
AutobanController:: |
private | function | Is IP address in whitelist? | |
ControllerBase:: |
protected | property | The configuration factory. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The module handler. | 2 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
public static | function |
Instantiates a new instance of this class. Overrides ContainerInjectionInterface:: |
40 |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |