simplify ban fetching code
This commit is contained in:
parent
56b8d88ca4
commit
3ed3ea7234
8
composer.lock
generated
8
composer.lock
generated
@ -388,12 +388,12 @@
|
|||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/shish/microcrud.git",
|
"url": "https://github.com/shish/microcrud.git",
|
||||||
"reference": "41a8aea2af6441c212467670776dc182518c5ff4"
|
"reference": "6471a4c7445e872282f12d1de3730db55d5c06e2"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/shish/microcrud/zipball/41a8aea2af6441c212467670776dc182518c5ff4",
|
"url": "https://api.github.com/repos/shish/microcrud/zipball/6471a4c7445e872282f12d1de3730db55d5c06e2",
|
||||||
"reference": "41a8aea2af6441c212467670776dc182518c5ff4",
|
"reference": "6471a4c7445e872282f12d1de3730db55d5c06e2",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -429,7 +429,7 @@
|
|||||||
"crud",
|
"crud",
|
||||||
"generator"
|
"generator"
|
||||||
],
|
],
|
||||||
"time": "2019-11-28T15:23:53+00:00"
|
"time": "2019-11-28T15:53:53+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "shish/microhtml",
|
"name": "shish/microhtml",
|
||||||
|
@ -260,140 +260,68 @@ class IPBan extends Extension
|
|||||||
private function check_ip_ban()
|
private function check_ip_ban()
|
||||||
{
|
{
|
||||||
$remote = $_SERVER['REMOTE_ADDR'];
|
$remote = $_SERVER['REMOTE_ADDR'];
|
||||||
$bans = $this->get_active_bans_sorted();
|
list($ips, $networks) = $this->get_active_bans_grouped();
|
||||||
|
if (isset($ips[$remote])) {
|
||||||
// bans[0] = IPs
|
$this->block($ips[$remote]); // never returns
|
||||||
if (isset($bans[0][$remote])) {
|
|
||||||
$this->block($remote); // never returns
|
|
||||||
}
|
}
|
||||||
|
foreach ($networks as $range => $ban_id) {
|
||||||
// bans[1] = CIDR nets
|
if (ip_in_range($remote, $range)) {
|
||||||
foreach ($bans[1] as $ip => $true) {
|
$this->block($ban_id); // never returns
|
||||||
if (ip_in_range($remote, $ip)) {
|
|
||||||
$this->block($remote); // never returns
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function block(string $remote)
|
private function block(int $ban_id)
|
||||||
{
|
{
|
||||||
global $config, $database;
|
global $config, $database;
|
||||||
|
|
||||||
$prefix = ($database->get_driver_name() == DatabaseDriver::SQLITE ? "bans." : "");
|
$row = $database->get_row("SELECT * FROM bans WHERE id=:id", ["id"=>$ban_id]);
|
||||||
|
|
||||||
$bans = $this->get_bans(false, null);
|
$msg = $config->get_string("ipban_message");
|
||||||
|
$msg = str_replace('$IP', $row["ip"], $msg);
|
||||||
foreach ($bans as $row) {
|
$msg = str_replace('$DATE', $row['expires'], $msg);
|
||||||
$ip = $row[$prefix."ip"];
|
$msg = str_replace('$ADMIN', User::by_id($row['banner_id'])->name, $msg);
|
||||||
if (
|
$msg = str_replace('$REASON', $row['reason'], $msg);
|
||||||
(strstr($ip, '/') && ip_in_range($remote, $ip)) ||
|
$contact_link = contact_link();
|
||||||
($ip == $remote)
|
if (!empty($contact_link)) {
|
||||||
) {
|
$msg = str_replace('$CONTACT', "<a href='$contact_link'>Contact the staff (be sure to include this message)</a>", $msg);
|
||||||
$reason = $row[$prefix.'reason'];
|
} else {
|
||||||
$admin = User::by_id($row[$prefix.'banner_id']);
|
$msg = str_replace('$CONTACT', "", $msg);
|
||||||
$date = $row['expires'];
|
|
||||||
$msg = $config->get_string("ipban_message");
|
|
||||||
$msg = str_replace('$IP', $ip, $msg);
|
|
||||||
$msg = str_replace('$DATE', $date, $msg);
|
|
||||||
$msg = str_replace('$ADMIN', $admin->name, $msg);
|
|
||||||
$msg = str_replace('$REASON', $reason, $msg);
|
|
||||||
$contact_link = contact_link();
|
|
||||||
if (!empty($contact_link)) {
|
|
||||||
$msg = str_replace('$CONTACT', "<a href='$contact_link'>Contact the staff (be sure to include this message)</a>", $msg);
|
|
||||||
} else {
|
|
||||||
$msg = str_replace('$CONTACT', "", $msg);
|
|
||||||
}
|
|
||||||
header("HTTP/1.0 403 Forbidden");
|
|
||||||
print "$msg";
|
|
||||||
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
log_error("ipban", "block($remote) called but no bans matched");
|
|
||||||
|
header("HTTP/1.0 403 Forbidden");
|
||||||
|
print "$msg";
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function get_bans(bool $all, ?int $page)
|
|
||||||
{
|
|
||||||
global $database;
|
|
||||||
|
|
||||||
$size = 100;
|
|
||||||
if (@$_GET['limit']) {
|
|
||||||
$size = int_escape($_GET['limit']);
|
|
||||||
}
|
|
||||||
$filters = ["1=1"];
|
|
||||||
$args = [];
|
|
||||||
|
|
||||||
if (!$all) {
|
|
||||||
$filters[] = "((expires > CURRENT_TIMESTAMP) OR (expires IS NULL))";
|
|
||||||
}
|
|
||||||
if (@$_GET['s_ip']) {
|
|
||||||
$filters[] = "(ip = :ip)";
|
|
||||||
$args['ip'] = $_GET['s_ip'];
|
|
||||||
}
|
|
||||||
if (@$_GET['s_reason']) {
|
|
||||||
$filters[] = "(reason LIKE :reason)";
|
|
||||||
$args['reason'] = '%' . $_GET['s_reason'] . "%";
|
|
||||||
}
|
|
||||||
if (@$_GET['s_banner']) {
|
|
||||||
$filters[] = "(banner_id = :banner_id)";
|
|
||||||
$args['banner_id'] = User::by_name($_GET['s_banner'])->id;
|
|
||||||
}
|
|
||||||
if (@$_GET['s_added']) {
|
|
||||||
$filters[] = "(added LIKE :added)";
|
|
||||||
$args['added'] = '%' . $_GET['s_added'] . "%";
|
|
||||||
}
|
|
||||||
if (@$_GET['s_expires']) {
|
|
||||||
$filters[] = "(expires LIKE :expires)";
|
|
||||||
$args['expires'] = '%' . $_GET['s_expires'] . "%";
|
|
||||||
}
|
|
||||||
if (@$_GET['s_mode']) {
|
|
||||||
$filters[] = "(mode = :mode)";
|
|
||||||
$args['mode'] = $_GET['s_mode'];
|
|
||||||
}
|
|
||||||
$filter = implode(" AND ", $filters);
|
|
||||||
|
|
||||||
if (is_null($page)) {
|
|
||||||
$pager = "";
|
|
||||||
} else {
|
|
||||||
$pager = "LIMIT :limit OFFSET :offset";
|
|
||||||
$args["offset"] = ($page-1)*$size;
|
|
||||||
$args['limit'] = $size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $database->get_all("
|
|
||||||
SELECT bans.*, users.name as banner_name
|
|
||||||
FROM bans
|
|
||||||
JOIN users ON banner_id = users.id
|
|
||||||
WHERE $filter
|
|
||||||
ORDER BY expires, bans.id
|
|
||||||
$pager
|
|
||||||
", $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns [ips, nets]
|
// returns [ips, nets]
|
||||||
private function get_active_bans_sorted()
|
private function get_active_bans_grouped()
|
||||||
{
|
{
|
||||||
global $cache;
|
global $cache, $database;
|
||||||
|
|
||||||
$cached = $cache->get("ip_bans_sorted");
|
$cached = $cache->get("ip_to_ban_id_grouped");
|
||||||
if ($cached) {
|
if ($cached) {
|
||||||
return $cached;
|
return $cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
$bans = $this->get_bans(false, null);
|
$rows = $database->get_pairs("
|
||||||
$ips = []; # "0.0.0.0" => false);
|
SELECT ip, id
|
||||||
$nets = []; # "0.0.0.0/32" => false);
|
FROM bans
|
||||||
foreach ($bans as $row) {
|
WHERE ((expires > CURRENT_TIMESTAMP) OR (expires IS NULL))
|
||||||
if (strstr($row['ip'], '/')) {
|
");
|
||||||
$nets[$row['ip']] = true;
|
|
||||||
|
$ips = []; # "0.0.0.0" => 123;
|
||||||
|
$nets = []; # "0.0.0.0/32" => 456;
|
||||||
|
foreach ($rows as $ip => $id) {
|
||||||
|
if (strstr($ip, '/')) {
|
||||||
|
$nets[$ip] = $id;
|
||||||
} else {
|
} else {
|
||||||
$ips[$row['ip']] = true;
|
$ips[$ip] = $id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sorted = [$ips, $nets];
|
$sorted = [$ips, $nets];
|
||||||
$cache->set("ip_bans_sorted", $sorted, 600);
|
$cache->set("ip_to_ban_id_grouped", $sorted, 600);
|
||||||
return $sorted;
|
return $sorted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user