119 lines
3.6 KiB
PHP
119 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Auth;
|
|
|
|
use App\Http\Controllers\Api\Core\BaseApiController;
|
|
use App\Http\Requests\Security\IpBanIndexRequest;
|
|
use App\Http\Requests\Security\IpBanRequest;
|
|
use App\Http\Requests\Security\IpUnbanRequest;
|
|
use App\Http\Resources\Security\IpBanCollection;
|
|
use App\Http\Resources\Security\IpBanResource;
|
|
use App\Models\IpAttempt;
|
|
use App\Services\Security\IpBanCommandService;
|
|
use App\Services\Security\IpBanQueryService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class IpBanController extends BaseApiController
|
|
{
|
|
public function __construct(
|
|
private IpBanQueryService $queryService,
|
|
private IpBanCommandService $commandService
|
|
) {
|
|
parent::__construct();
|
|
}
|
|
|
|
public function index(IpBanIndexRequest $request): JsonResponse
|
|
{
|
|
$this->authorize('viewAny', IpAttempt::class);
|
|
|
|
$filters = $request->validated();
|
|
$page = (int) ($filters['page'] ?? 1);
|
|
$perPage = (int) ($filters['per_page'] ?? 20);
|
|
|
|
$bans = $this->queryService->paginate($filters, $page, $perPage);
|
|
$collection = new IpBanCollection($bans);
|
|
|
|
return $this->success([
|
|
'bans' => $collection->toArray($request),
|
|
'meta' => $collection->with($request)['meta'],
|
|
]);
|
|
}
|
|
|
|
public function show(int $id): JsonResponse
|
|
{
|
|
$ban = $this->queryService->find($id);
|
|
if (! $ban) {
|
|
return $this->error('IP record not found.', Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
$this->authorize('view', $ban);
|
|
|
|
return $this->success([
|
|
'ban' => new IpBanResource($ban),
|
|
]);
|
|
}
|
|
|
|
public function ban(IpBanRequest $request): JsonResponse
|
|
{
|
|
$this->authorize('create', IpAttempt::class);
|
|
|
|
$validated = $request->validated();
|
|
$id = $validated['id'] ?? null;
|
|
$ip = $validated['ip'] ?? null;
|
|
$hours = (int) ($validated['hours'] ?? 24);
|
|
|
|
try {
|
|
$ban = $this->commandService->banNow($id ? (int) $id : null, $ip ? (string) $ip : null, $hours);
|
|
} catch (\Throwable $e) {
|
|
Log::error('IP ban failed: '.$e->getMessage());
|
|
|
|
return $this->error('Unable to ban IP.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
if (! $ban) {
|
|
return $this->error('IP record not found.', Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
return $this->success([
|
|
'ban' => new IpBanResource($ban),
|
|
], 'IP banned.');
|
|
}
|
|
|
|
public function unban(IpUnbanRequest $request): JsonResponse
|
|
{
|
|
$this->authorize('update', IpAttempt::class);
|
|
|
|
$validated = $request->validated();
|
|
$all = filter_var($validated['all'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
|
|
|
try {
|
|
if ($all) {
|
|
$count = $this->commandService->unbanAll();
|
|
|
|
return $this->success([
|
|
'count' => $count,
|
|
], $count.' IP(s) unbanned.');
|
|
}
|
|
|
|
$ban = $this->commandService->unbanOne(
|
|
isset($validated['id']) ? (int) $validated['id'] : null,
|
|
$validated['ip'] ?? null
|
|
);
|
|
} catch (\Throwable $e) {
|
|
Log::error('IP unban failed: '.$e->getMessage());
|
|
|
|
return $this->error('Unable to unban IP.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
if (! $ban) {
|
|
return $this->error('IP record not found.', Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
return $this->success([
|
|
'ban' => new IpBanResource($ban),
|
|
], 'IP unbanned.');
|
|
}
|
|
}
|