add projet

This commit is contained in:
root
2026-03-05 12:29:37 -05:00
parent 8d1eef8ba8
commit 23b7db1107
9109 changed files with 1106501 additions and 73 deletions
+205
View File
@@ -0,0 +1,205 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\IpAttempt;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Symfony\Component\HttpFoundation\Response;
class IpBanController extends BaseApiController
{
protected IpAttempt $ipAttempt;
public function __construct()
{
parent::__construct();
$this->ipAttempt = model(IpAttempt::class);
}
public function index()
{
$page = max(1, (int) ($this->request->getGet('page') ?? 1));
$perPage = min(100, max(1, (int) ($this->request->getGet('per_page') ?? 20)));
$status = strtolower(trim((string) ($this->request->getGet('status') ?? 'all')));
$now = Carbon::now('UTC')->toDateTimeString();
$query = $this->ipAttempt->newQuery()->orderBy('updated_at', 'DESC');
if ($status === 'active') {
$query->where('blocked_until', '>', $now);
} elseif ($status === 'expired') {
$query->where('blocked_until', '<=', $now)
->whereNotNull('blocked_until');
}
$result = $this->paginate($query, $page, $perPage);
return $this->success($result, 'IP bans retrieved successfully');
}
public function show($id = null)
{
$ban = $this->ipAttempt->find($id);
if (!$ban) {
return $this->error('IP ban not found', Response::HTTP_NOT_FOUND);
}
return $this->success($ban, 'IP ban retrieved successfully');
}
public function unban()
{
$payload = $this->payloadData();
if (empty($payload)) {
return $this->error('Invalid request data', Response::HTTP_BAD_REQUEST);
}
$id = (int) ($payload['id'] ?? 0);
$ip = trim((string) ($payload['ip'] ?? ''));
$all = (int) ($payload['all'] ?? 0) === 1;
try {
if ($all) {
$now = Carbon::now('UTC')->toDateTimeString();
$builder = $this->ipAttempt->newQuery();
$count = $builder->where('blocked_until', '>', $now)
->update([
'blocked_until' => null,
'attempts' => 0,
]);
return $this->success(['count' => $count], $count . ' IP(s) unbanned.');
}
$row = null;
if ($id > 0) {
$row = $this->ipAttempt->find($id);
} elseif ($ip !== '') {
$row = $this->ipAttempt->newQuery()
->where('ip_address', $ip)
->first();
}
if (!$row) {
return $this->error('IP record not found', Response::HTTP_NOT_FOUND);
}
$ipAddress = $row['ip_address'] ?? $row->ip_address ?? '';
$this->ipAttempt->update($row->id ?? $row['id'], [
'blocked_until' => null,
'attempts' => 0,
]);
return $this->success(['ip' => $ipAddress], 'IP ' . $ipAddress . ' unbanned.');
} catch (\Throwable $e) {
log_message('error', 'IP unban error: ' . $e->getMessage());
return $this->respondError('Failed to unban IP', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function ban()
{
$payload = $this->payloadData();
if (empty($payload)) {
return $this->error('Invalid request data', Response::HTTP_BAD_REQUEST);
}
$rules = [
'ip' => 'required|ip',
'blocked_until' => 'required|date',
];
$errors = $this->validateRequest($payload, $rules);
if (!empty($errors)) {
return $this->respondValidationError($errors);
}
try {
$ip = trim($payload['ip']);
$blockedUntil = Carbon::parse($payload['blocked_until'])
->timezone('UTC')
->format('Y-m-d H:i:s');
$reason = $payload['reason'] ?? null;
$attempts = (int) ($payload['attempts'] ?? 5);
$existing = $this->ipAttempt->newQuery()
->where('ip_address', $ip)
->first();
if ($existing) {
$this->ipAttempt->update($existing->id ?? $existing['id'], [
'blocked_until' => $blockedUntil,
'attempts' => $attempts,
'reason' => $reason,
]);
$ban = $this->ipAttempt->find($existing->id ?? $existing['id']);
} else {
$ban = $this->ipAttempt->create([
'ip_address' => $ip,
'blocked_until' => $blockedUntil,
'attempts' => $attempts,
'reason' => $reason,
]);
}
$responseData = $ban instanceof Model ? $ban->toArray() : $ban;
return $this->success($responseData, 'IP banned successfully', Response::HTTP_CREATED);
} catch (\Throwable $e) {
log_message('error', 'IP ban error: ' . $e->getMessage());
return $this->respondError('Failed to ban IP', Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* POST /api/v1/ip-bans/ban-now
* Ban an IP immediately for a specified number of hours
*/
public function banNow()
{
$payload = $this->payloadData();
// Accept both POST and GET params
$id = (int) ($payload['id'] ?? $this->request->getGet('id') ?? 0);
$ip = trim((string) ($payload['ip'] ?? $this->request->getGet('ip') ?? ''));
$hours = (int) ($payload['hours'] ?? $this->request->getGet('hours') ?? 24);
if ($hours <= 0) {
$hours = 24;
}
try {
$row = null;
if ($id > 0) {
$row = $this->ipAttempt->find($id);
} elseif ($ip !== '') {
$row = $this->ipAttempt->newQuery()
->where('ip_address', $ip)
->first();
}
if (!$row) {
return $this->error('IP record not found', Response::HTTP_NOT_FOUND);
}
$blockedUntil = Carbon::now('UTC')->addHours($hours)->format('Y-m-d H:i:s');
$currentAttempts = (int) ($row['attempts'] ?? $row->attempts ?? 0);
$this->ipAttempt->update($row['id'] ?? $row->id, [
'blocked_until' => $blockedUntil,
// Optionally set attempts to threshold for clarity
'attempts' => max($currentAttempts, 10),
]);
$ipAddress = $row['ip_address'] ?? $row->ip_address;
return $this->success([
'ip' => $ipAddress,
'blocked_until' => $blockedUntil,
'hours' => $hours,
], "IP {$ipAddress} banned for {$hours}h.");
} catch (\Throwable $e) {
log_message('error', 'IP ban now error: ' . $e->getMessage());
return $this->respondError('Unable to ban: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
}