domovoy/app/Controllers/DiscoveryController.php

140 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Domovoy\Controllers;
use Domovoy\Models\NetworkRange;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class DiscoveryController
{
private \Domovoy\Repositories\NetworkRangeRepository $networkRangeRepository;
private \Domovoy\Repositories\ScanJobRepository $scanJobRepository;
private \Domovoy\Repositories\DiscoveredHostRepository $discoveredHostRepository;
public function __construct(
\Domovoy\Repositories\NetworkRangeRepository $networkRangeRepository,
\Domovoy\Repositories\ScanJobRepository $scanJobRepository,
\Domovoy\Repositories\DiscoveredHostRepository $discoveredHostRepository
) {
$this->networkRangeRepository = $networkRangeRepository;
$this->scanJobRepository = $scanJobRepository;
$this->discoveredHostRepository = $discoveredHostRepository;
}
public function index(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
ob_start();
$username = $_SESSION['username'] ?? 'User';
$ranges = $this->networkRangeRepository->findAll();
$activeJobs = $this->scanJobRepository->findActive();
$scanJobs = $this->scanJobRepository->findRecent(10);
require dirname(__DIR__, 2) . '/templates/discovery/index.php';
$body = ob_get_clean();
$response->getBody()->write($body);
return $response;
}
public function startScan(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$data = $request->getParsedBody();
$rangeId = $data['range_id'] ?? null;
// Create scan job(s)
if ($rangeId !== null) {
$range = $this->networkRangeRepository->findById((int)$rangeId);
if ($range === null || !$range->enabled) {
return $response->withStatus(404)->write('Range not found');
}
$this->createScanJob('network_discovery', $range->id);
} else {
// Scan all enabled ranges
$ranges = $this->networkRangeRepository->findEnabled();
foreach ($ranges as $range) {
$this->createScanJob('network_discovery', $range->id);
}
}
return $response
->withHeader('Location', '/discovery')
->withStatus(302);
}
public function ignoreHost(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$data = $request->getParsedBody();
$hostId = $data['host_id'] ?? null;
if ($hostId !== null) {
$host = $this->discoveredHostRepository->findById((int)$hostId);
if ($host !== null) {
$host->status = 'ignored';
$this->discoveredHostRepository->save($host);
}
}
return $response
->withHeader('Location', '/discovery')
->withStatus(302);
}
public function activeJobs(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$activeJobs = $this->scanJobRepository->findActive();
ob_start();
require dirname(__DIR__, 2) . '/templates/discovery/_active_jobs.php';
$body = ob_get_clean();
$response->getBody()->write($body);
return $response;
}
public function scanHistory(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
$scanJobs = $this->scanJobRepository->findRecent(10);
ob_start();
require dirname(__DIR__, 2) . '/templates/discovery/_scan_history.php';
$body = ob_get_clean();
$response->getBody()->write($body);
return $response;
}
public function pauseJob(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$job = $this->scanJobRepository->findById((int)$args['id']);
if ($job !== null && $job->status === 'running') {
$this->scanJobRepository->updateStatus($job->id, 'paused');
}
return $this->activeJobs($request, $response);
}
public function resumeJob(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$job = $this->scanJobRepository->findById((int)$args['id']);
if ($job !== null && $job->status === 'paused') {
$this->scanJobRepository->updateStatus($job->id, 'pending');
}
return $this->activeJobs($request, $response);
}
public function cancelJob(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$job = $this->scanJobRepository->findById((int)$args['id']);
if ($job !== null && in_array($job->status, ['pending', 'running', 'paused'], true)) {
$this->scanJobRepository->updateStatus($job->id, 'cancelled');
}
return $this->activeJobs($request, $response);
}
private function createScanJob(string $type, int $rangeId): void
{
$job = new \Domovoy\Models\ScanJob();
$job->type = $type;
$job->status = 'pending';
$job->networkRangeId = $rangeId;
$job->createdBy = $_SESSION['user_id'] ?? null;
$this->scanJobRepository->save($job);
}
}