mirror of
https://github.com/phpbb/phpbb.git
synced 2025-07-31 05:50:42 +02:00
[ticket/9687] Introduce new ban manager (WIP)
PHPBB3-9687
This commit is contained in:
committed by
Marc Alexander
parent
caddc73e06
commit
5ae1d9eac6
20
phpBB/phpbb/ban/exception/invalid_length_exception.php
Normal file
20
phpBB/phpbb/ban/exception/invalid_length_exception.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\exception;
|
||||
|
||||
use phpbb\exception\runtime_exception;
|
||||
|
||||
class invalid_length_exception extends runtime_exception
|
||||
{
|
||||
}
|
20
phpBB/phpbb/ban/exception/type_not_found_exception.php
Normal file
20
phpBB/phpbb/ban/exception/type_not_found_exception.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\exception;
|
||||
|
||||
use phpbb\exception\runtime_exception;
|
||||
|
||||
class type_not_found_exception extends runtime_exception
|
||||
{
|
||||
}
|
160
phpBB/phpbb/ban/manager.php
Normal file
160
phpBB/phpbb/ban/manager.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban;
|
||||
|
||||
use phpbb\ban\exception\invalid_length_exception;
|
||||
use phpbb\ban\exception\type_not_found_exception;
|
||||
|
||||
class manager
|
||||
{
|
||||
protected $ban_table;
|
||||
|
||||
protected $db;
|
||||
|
||||
protected $log;
|
||||
|
||||
protected $sessions_keys_table;
|
||||
|
||||
protected $sessions_table;
|
||||
|
||||
protected $types;
|
||||
|
||||
protected $user;
|
||||
|
||||
protected $users_table;
|
||||
|
||||
public function __construct($types, \phpbb\db\driver\driver_interface $db, \phpbb\log\log_interface $log, \phpbb\user $user, $ban_table, $users_table = '', $sessions_table = '', $sessions_keys_table = '')
|
||||
{
|
||||
$this->ban_table = $ban_table;
|
||||
$this->db = $db;
|
||||
$this->log = $log;
|
||||
$this->sessions_keys_table = $sessions_keys_table;
|
||||
$this->sessions_table = $sessions_table;
|
||||
$this->types = $types;
|
||||
$this->user = $user;
|
||||
$this->users_table = $users_table;
|
||||
}
|
||||
|
||||
public function ban($mode, array $items, \DateTimeInterface $start, \DateTimeInterface $end, $reason, $display_reason = '', $logging = true)
|
||||
{
|
||||
if (!isset($this->types[$mode]))
|
||||
{
|
||||
throw new type_not_found_exception(); // TODO
|
||||
}
|
||||
if ($start > $end && $end->getTimestamp() !== 0)
|
||||
{
|
||||
throw new invalid_length_exception(); // TODO
|
||||
}
|
||||
|
||||
/** @var \phpbb\ban\type\type_interface $ban_mode */
|
||||
$ban_mode = $this->types[$mode];
|
||||
$ban_items = $ban_mode->prepare_for_storage($items);
|
||||
|
||||
// Prevent duplicate bans
|
||||
$sql = 'DELETE FROM ' . $this->ban_table . "
|
||||
WHERE ban_mode = '" . $this->db->sql_escape($mode) . "'
|
||||
AND " . $this->db->sql_in_set('ban_item', $ban_items);
|
||||
$this->db->sql_query($sql);
|
||||
|
||||
$insert_array = [];
|
||||
foreach ($ban_items as $ban_item)
|
||||
{
|
||||
$insert_array[] = [
|
||||
'ban_mode' => $mode,
|
||||
'ban_item' => $ban_item,
|
||||
'ban_start' => $start->getTimestamp(),
|
||||
'ban_end' => $end->getTimestamp(),
|
||||
'ban_reason' => $reason,
|
||||
'ban_reason_display' => $display_reason,
|
||||
];
|
||||
}
|
||||
|
||||
if (empty($insert_array))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->db->sql_multi_insert($this->ban_table, $insert_array);
|
||||
if ($result === false)
|
||||
{
|
||||
// Something went wrong
|
||||
// TODO throw exception
|
||||
}
|
||||
|
||||
if ($logging)
|
||||
{
|
||||
// TODO logging
|
||||
}
|
||||
|
||||
if (!$ban_mode->after_ban())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$user_column = $ban_mode->get_user_column();
|
||||
if (!empty($user_column) && !empty($this->users_table))
|
||||
{
|
||||
$ban_items_sql = [];
|
||||
$ban_or_like = '';
|
||||
foreach ($ban_items as $ban_item)
|
||||
{
|
||||
if (stripos($ban_item, '*') === false)
|
||||
{
|
||||
$ban_items_sql[] = $ban_item;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ban_or_like .= ' OR ' . $user_column . ' ' . $this->db->sql_like_expression(str_replace('*', $this->db->get_any_char(), $ban_item));
|
||||
}
|
||||
}
|
||||
|
||||
$sql = 'SELECT user_id
|
||||
FROM ' . $this->users_table . '
|
||||
WHERE ' . $this->db->sql_in_set('u.' . $user_column, $ban_items) . $ban_or_like;
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$user_ids = [];
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$user_ids[] = (int)$row['user_id'];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
if (!empty($user_ids) && !empty($this->sessions_table))
|
||||
{
|
||||
$sql = 'DELETE FROM ' . $this->sessions_table . '
|
||||
WHERE ' . $this->db->sql_in_set('session_user_id', $user_ids);
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
if (!empty($user_ids) && !empty($this->sessions_keys_table))
|
||||
{
|
||||
$sql = 'DELETE FROM ' . $this->sessions_keys_table . '
|
||||
WHERE ' . $this->db->sql_in_set('user_id', $user_ids);
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function unban($mode, array $items, $reason, $logging = true)
|
||||
{
|
||||
}
|
||||
|
||||
public function check(array $user_data = [])
|
||||
{
|
||||
}
|
||||
|
||||
public function tidy()
|
||||
{
|
||||
}
|
||||
}
|
95
phpBB/phpbb/ban/type/base.php
Normal file
95
phpBB/phpbb/ban/type/base.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\type;
|
||||
|
||||
abstract class base implements type_interface
|
||||
{
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var array */
|
||||
protected $excluded;
|
||||
|
||||
/** @var string */
|
||||
protected $users_table;
|
||||
|
||||
public function __construct(\phpbb\db\driver\driver_interface $db, $users_table)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->users_table = $users_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_user_column()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function after_ban()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function after_unban()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function check(array $data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function tidy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries users that are excluded from banning (like founders)
|
||||
* from the database and saves them in $this->excluded array.
|
||||
* Returns true on success and false on failure
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function get_excluded()
|
||||
{
|
||||
$user_column = $this->get_user_column();
|
||||
if (empty($user_column))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->excluded = [];
|
||||
|
||||
$sql = "SELECT user_id, {$user_column}
|
||||
FROM {$this->users_table}
|
||||
WHERE user_type = " . USER_FOUNDER;
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$this->excluded[(int) $row['user_id']] = $row[$user_column];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
63
phpBB/phpbb/ban/type/email.php
Normal file
63
phpBB/phpbb/ban/type/email.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\type;
|
||||
|
||||
class email extends base
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_type()
|
||||
{
|
||||
return 'email';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function get_user_column()
|
||||
{
|
||||
return 'user_email';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare_for_storage(array $items)
|
||||
{
|
||||
if (!$this->get_excluded())
|
||||
{
|
||||
// TODO throw exception
|
||||
}
|
||||
$regex = get_preg_expression('email');
|
||||
|
||||
$ban_items = [];
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$item = trim($item);
|
||||
if (strlen($item) > 100 || preg_match($regex, $item) || in_array($item, $this->excluded))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$ban_items[] = $item;
|
||||
}
|
||||
|
||||
if (empty($ban_items))
|
||||
{
|
||||
// TODO throw exception - no valid emails defined
|
||||
}
|
||||
|
||||
return $ban_items;
|
||||
}
|
||||
}
|
73
phpBB/phpbb/ban/type/type_interface.php
Normal file
73
phpBB/phpbb/ban/type/type_interface.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\type;
|
||||
|
||||
/**
|
||||
* Interface implemented by all ban types
|
||||
*/
|
||||
interface type_interface
|
||||
{
|
||||
/**
|
||||
* Returns the type identifier for this ban type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_type();
|
||||
|
||||
/**
|
||||
* Returns the column in the users table which contains
|
||||
* the values that should be looked for when checking a ban.
|
||||
* If it returns null, the check method will be called when
|
||||
* checking for bans.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_user_column();
|
||||
|
||||
/**
|
||||
* Gives the possibility to do some clean up after banning
|
||||
* Returns true if affected users should be logged out and
|
||||
* false otherwise
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function after_ban();
|
||||
|
||||
public function after_unban(); // ???
|
||||
|
||||
/**
|
||||
* In the case that get_user_column() returns null, this method
|
||||
* is called when checking the ban status.
|
||||
* Please note, that this method is basically called on every page,
|
||||
* so the check should perform rather fast.
|
||||
*
|
||||
* Returns true if the person is banned and false otherwise.
|
||||
*
|
||||
* @param array $data The user data array
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function check(array $data);
|
||||
|
||||
/**
|
||||
* Prepares the given ban items before saving them in the database
|
||||
*
|
||||
* @param array $items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function prepare_for_storage(array $items);
|
||||
|
||||
public function tidy(); // ???
|
||||
}
|
78
phpBB/phpbb/ban/type/user.php
Normal file
78
phpBB/phpbb/ban/type/user.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\ban\type;
|
||||
|
||||
class user extends base
|
||||
{
|
||||
public function get_type()
|
||||
{
|
||||
return 'user';
|
||||
}
|
||||
|
||||
public function get_user_column()
|
||||
{
|
||||
return 'user_id';
|
||||
}
|
||||
|
||||
public function prepare_for_storage(array $items)
|
||||
{
|
||||
if (!$this->get_excluded())
|
||||
{
|
||||
// TODO throw exception
|
||||
}
|
||||
|
||||
$sql_usernames = [];
|
||||
$sql_or_like = [];
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$cleaned_username = utf8_clean_string($item);
|
||||
if (stripos($cleaned_username, '*') === false)
|
||||
{
|
||||
$sql_usernames[] = $cleaned_username;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql_or_like[] = ['username_clean', 'LIKE', str_replace('*', $this->db->get_any_char(), $cleaned_username)];
|
||||
}
|
||||
}
|
||||
|
||||
$sql_array = [
|
||||
'SELECT' => 'user_id',
|
||||
'FROM' => [
|
||||
$this->users_table => '',
|
||||
],
|
||||
'WHERE' => ['AND',
|
||||
[
|
||||
['OR',
|
||||
array_merge([
|
||||
['username_clean', 'IN', $sql_usernames]
|
||||
], $sql_or_like),
|
||||
],
|
||||
['user_id', 'NOT_IN', array_map('intval', $this->excluded)],
|
||||
],
|
||||
],
|
||||
];
|
||||
$sql = $this->db->sql_build_query('SELECT', $sql_array);
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$ban_items = [];
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$ban_items[] = (int) $row['user_id'];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $ban_items;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user