113 lines
4.1 KiB
PHP
113 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Domovoy\Repositories;
|
|
|
|
use Domovoy\Models\DiscoveredHost;
|
|
use PDO;
|
|
|
|
class DiscoveredHostRepository
|
|
{
|
|
private PDO $pdo;
|
|
|
|
public function __construct(PDO $pdo)
|
|
{
|
|
$this->pdo = $pdo;
|
|
}
|
|
|
|
public function findById(int $id): ?DiscoveredHost
|
|
{
|
|
$stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts WHERE id = :id');
|
|
$stmt->execute(['id' => $id]);
|
|
$row = $stmt->fetch();
|
|
return $row ? DiscoveredHost::fromArray($row) : null;
|
|
}
|
|
|
|
public function findByStatus(string $status, int $limit = 100): array
|
|
{
|
|
$stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts WHERE status = :status ORDER BY last_seen DESC LIMIT :limit');
|
|
$stmt->bindValue('status', $status);
|
|
$stmt->bindValue('limit', $limit, PDO::PARAM_INT);
|
|
$stmt->execute();
|
|
$results = [];
|
|
while ($row = $stmt->fetch()) {
|
|
$results[] = DiscoveredHost::fromArray($row);
|
|
}
|
|
return $results;
|
|
}
|
|
|
|
public function findByScanJob(int $scanJobId): array
|
|
{
|
|
$stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts WHERE scan_job_id = :scan_job_id ORDER BY ip_address ASC');
|
|
$stmt->execute(['scan_job_id' => $scanJobId]);
|
|
$results = [];
|
|
while ($row = $stmt->fetch()) {
|
|
$results[] = DiscoveredHost::fromArray($row);
|
|
}
|
|
return $results;
|
|
}
|
|
|
|
public function findAll(int $limit = 100): array
|
|
{
|
|
$stmt = $this->pdo->prepare('SELECT * FROM discovered_hosts ORDER BY last_seen DESC LIMIT :limit');
|
|
$stmt->bindValue('limit', $limit, PDO::PARAM_INT);
|
|
$stmt->execute();
|
|
$results = [];
|
|
while ($row = $stmt->fetch()) {
|
|
$results[] = DiscoveredHost::fromArray($row);
|
|
}
|
|
return $results;
|
|
}
|
|
|
|
public function save(DiscoveredHost $host): void
|
|
{
|
|
$now = (new \DateTimeImmutable())->format('Y-m-d H:i:s');
|
|
if ($host->id === null) {
|
|
$stmt = $this->pdo->prepare(
|
|
'INSERT INTO discovered_hosts
|
|
(scan_job_id, ip_address, mac_address, hostname, vendor, detected_os,
|
|
open_ports_json, protocols_json, fingerprint_json, confidence, status,
|
|
matched_device_id, first_seen, last_seen, created_at, updated_at)
|
|
VALUES
|
|
(:scan_job_id, :ip_address, :mac_address, :hostname, :vendor, :detected_os,
|
|
:open_ports_json, :protocols_json, :fingerprint_json, :confidence, :status,
|
|
:matched_device_id, :first_seen, :last_seen, :created_at, :updated_at)'
|
|
);
|
|
$stmt->execute([
|
|
'scan_job_id' => $host->scanJobId,
|
|
'ip_address' => $host->ipAddress,
|
|
'mac_address' => $host->macAddress,
|
|
'hostname' => $host->hostname,
|
|
'vendor' => $host->vendor,
|
|
'detected_os' => $host->detectedOs,
|
|
'open_ports_json' => json_encode($host->openPorts),
|
|
'protocols_json' => json_encode($host->protocols),
|
|
'fingerprint_json' => json_encode($host->fingerprint),
|
|
'confidence' => $host->confidence,
|
|
'status' => $host->status,
|
|
'matched_device_id' => $host->matchedDeviceId,
|
|
'first_seen' => $now,
|
|
'last_seen' => $now,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
$host->id = (int)$this->pdo->lastInsertId();
|
|
} else {
|
|
$stmt = $this->pdo->prepare(
|
|
'UPDATE discovered_hosts SET
|
|
status = :status, matched_device_id = :matched_device_id,
|
|
last_seen = :last_seen, updated_at = :updated_at
|
|
WHERE id = :id'
|
|
);
|
|
$stmt->execute([
|
|
'id' => $host->id,
|
|
'status' => $host->status,
|
|
'matched_device_id' => $host->matchedDeviceId,
|
|
'last_seen' => $now,
|
|
'updated_at' => $now,
|
|
]);
|
|
}
|
|
}
|
|
}
|