Harden quarantine provisioning; enforce strict permissions and update Ansible and docs
This commit is contained in:
58
core/Services/FloodService.php
Normal file
58
core/Services/FloodService.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace UploadLogger\Core\Services;
|
||||
|
||||
use UploadLogger\Core\Config;
|
||||
|
||||
final class FloodService
|
||||
{
|
||||
private Config $config;
|
||||
|
||||
public function __construct(?Config $config = null)
|
||||
{
|
||||
$this->config = $config ?? new Config(['modules' => []]);
|
||||
}
|
||||
|
||||
public function check(string $ip): int
|
||||
{
|
||||
$window = (int)$this->config->get('limits.flood_window_sec', 60);
|
||||
$stateDir = (string)$this->config->get('paths.state_dir', __DIR__ . '/../../state');
|
||||
|
||||
$key = rtrim($stateDir, '/\\') . '/upl_' . md5('v3|' . $ip);
|
||||
|
||||
$now = time();
|
||||
$count = 0;
|
||||
$start = $now;
|
||||
|
||||
$fh = @fopen($key, 'c+');
|
||||
if ($fh === false) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (flock($fh, LOCK_EX)) {
|
||||
$raw = stream_get_contents($fh);
|
||||
if ($raw !== false) {
|
||||
if (preg_match('/^(\d+):(\d+)$/', trim($raw), $m)) {
|
||||
$start = (int)$m[1];
|
||||
$count = (int)$m[2];
|
||||
}
|
||||
}
|
||||
|
||||
if ((($now - $start) > $window)) {
|
||||
$start = $now;
|
||||
$count = 0;
|
||||
}
|
||||
|
||||
$count++;
|
||||
rewind($fh);
|
||||
ftruncate($fh, 0);
|
||||
fwrite($fh, $start . ':' . $count);
|
||||
fflush($fh);
|
||||
flock($fh, LOCK_UN);
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user