add projet
This commit is contained in:
Executable
+205
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user