domovoy/public/index.php

217 lines
11 KiB
PHP

<?php
declare(strict_types=1);
session_start();
require dirname(__DIR__) . '/vendor/autoload.php';
use DI\ContainerBuilder;
use Slim\Factory\AppFactory;
$dotenv = \Dotenv\Dotenv::createImmutable(dirname(__DIR__));
$dotenv->safeLoad();
// Build container
$containerBuilder = new ContainerBuilder();
$containerBuilder->addDefinitions([
'settings' => [
'db' => [
'host' => getenv('DB_HOST') ?: 'db',
'port' => (int)(getenv('DB_PORT') ?: 3306),
'database' => getenv('DB_DATABASE') ?: 'domovoy',
'username' => getenv('DB_USERNAME') ?: 'domovoy',
'password' => getenv('DB_PASSWORD') ?: 'domovoy',
],
'app' => [
'env' => getenv('APP_ENV') ?: 'development',
'secret' => getenv('APP_SECRET') ?: 'change-me',
'encryption_key' => getenv('ENCRYPTION_KEY') ?: '',
],
'ssh' => [
'connect_timeout' => (int)(getenv('SSH_CONNECT_TIMEOUT_SECONDS') ?: 5),
'auth_timeout' => (int)(getenv('SSH_AUTH_TIMEOUT_SECONDS') ?: 10),
'command_timeout' => (int)(getenv('SSH_COMMAND_TIMEOUT_SECONDS') ?: 8),
'total_scan_timeout' => (int)(getenv('SSH_TOTAL_SCAN_TIMEOUT_SECONDS') ?: 60),
'retry_count' => (int)(getenv('SSH_RETRY_COUNT') ?: 0),
],
],
'logger' => function () {
$logger = new \Monolog\Logger('domovoy');
$logger->pushHandler(new \Monolog\Handler\StreamHandler(
dirname(__DIR__) . '/storage/logs/app.log',
\Monolog\Level::Debug
));
return $logger;
},
PDO::class => function ($c) {
$db = $c->get('settings')['db'];
$dsn = sprintf(
'mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4',
$db['host'],
$db['port'],
$db['database']
);
return new PDO($dsn, $db['username'], $db['password'], [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
},
// Repositories
\Domovoy\Repositories\UserRepository::class => function ($c) {
return new \Domovoy\Repositories\UserRepository($c->get(PDO::class));
},
\Domovoy\Repositories\NetworkRangeRepository::class => function ($c) {
return new \Domovoy\Repositories\NetworkRangeRepository($c->get(PDO::class));
},
\Domovoy\Repositories\ScanJobRepository::class => function ($c) {
return new \Domovoy\Repositories\ScanJobRepository($c->get(PDO::class));
},
\Domovoy\Repositories\DiscoveredHostRepository::class => function ($c) {
return new \Domovoy\Repositories\DiscoveredHostRepository($c->get(PDO::class));
},
\Domovoy\Repositories\AuditLogRepository::class => function ($c) {
return new \Domovoy\Repositories\AuditLogRepository($c->get(PDO::class));
},
// Discovery services
\Domovoy\Services\Discovery\PingScanner::class => function () {
return new \Domovoy\Services\Discovery\PingScanner();
},
\Domovoy\Services\Discovery\TcpPortScanner::class => function () {
return new \Domovoy\Services\Discovery\TcpPortScanner();
},
\Domovoy\Services\Discovery\ArpTableReader::class => function () {
return new \Domovoy\Services\Discovery\ArpTableReader();
},
\Domovoy\Services\Discovery\HostFingerprintService::class => function () {
return new \Domovoy\Services\Discovery\HostFingerprintService();
},
\Domovoy\Services\Discovery\NetworkScanner::class => function ($c) {
return new \Domovoy\Services\Discovery\NetworkScanner(
$c->get(\Domovoy\Services\Discovery\PingScanner::class),
$c->get(\Domovoy\Services\Discovery\TcpPortScanner::class),
$c->get(\Domovoy\Services\Discovery\ArpTableReader::class),
$c->get(\Domovoy\Services\Discovery\HostFingerprintService::class),
$c->get(\Domovoy\Repositories\DiscoveredHostRepository::class)
);
},
// Job runner
\Domovoy\Services\Jobs\ScanJobRunner::class => function ($c) {
return new \Domovoy\Services\Jobs\ScanJobRunner(
$c->get(\Domovoy\Repositories\ScanJobRepository::class),
$c->get(\Domovoy\Services\Discovery\NetworkScanner::class),
$c->get(\Domovoy\Repositories\NetworkRangeRepository::class)
);
},
// Auth
\Domovoy\Services\AuthService::class => function ($c) {
return new \Domovoy\Services\AuthService($c->get(\Domovoy\Repositories\UserRepository::class));
},
// Controllers
\Domovoy\Controllers\AuthController::class => function ($c) {
return new \Domovoy\Controllers\AuthController($c->get(\Domovoy\Services\AuthService::class));
},
\Domovoy\Controllers\SetupController::class => function ($c) {
return new \Domovoy\Controllers\SetupController($c->get(\Domovoy\Services\AuthService::class));
},
\Domovoy\Controllers\DashboardController::class => function ($c) {
return new \Domovoy\Controllers\DashboardController(
$c->get(\Domovoy\Repositories\DeviceRepository::class),
$c->get(\Domovoy\Repositories\ScanJobRepository::class)
);
},
\Domovoy\Controllers\DiscoveryController::class => function ($c) {
return new \Domovoy\Controllers\DiscoveryController(
$c->get(\Domovoy\Repositories\NetworkRangeRepository::class),
$c->get(\Domovoy\Repositories\ScanJobRepository::class),
$c->get(\Domovoy\Repositories\DiscoveredHostRepository::class)
);
},
\Domovoy\Controllers\NetworkRangeController::class => function ($c) {
return new \Domovoy\Controllers\NetworkRangeController(
$c->get(\Domovoy\Repositories\NetworkRangeRepository::class)
);
},
// Inventory
\Domovoy\Repositories\DeviceRepository::class => function ($c) {
return new \Domovoy\Repositories\DeviceRepository($c->get(PDO::class));
},
\Domovoy\Services\Inventory\DeviceService::class => function ($c) {
return new \Domovoy\Services\Inventory\DeviceService(
$c->get(\Domovoy\Repositories\DeviceRepository::class),
$c->get(\Domovoy\Repositories\DiscoveredHostRepository::class)
);
},
\Domovoy\Services\Inventory\MergeSuggestionService::class => function ($c) {
return new \Domovoy\Services\Inventory\MergeSuggestionService($c->get(\Domovoy\Repositories\DeviceRepository::class));
},
\Domovoy\Controllers\DeviceController::class => function ($c) {
return new \Domovoy\Controllers\DeviceController(
$c->get(\Domovoy\Services\Inventory\DeviceService::class),
$c->get(\Domovoy\Repositories\DiscoveredHostRepository::class)
);
},
\Domovoy\Controllers\DiscoveriesController::class => function ($c) {
return new \Domovoy\Controllers\DiscoveriesController(
$c->get(\Domovoy\Repositories\DiscoveredHostRepository::class),
$c->get(\Domovoy\Repositories\NetworkRangeRepository::class),
$c->get(\Domovoy\Services\Inventory\DeviceService::class)
);
},
]);
$container = $containerBuilder->build();
// Build Slim app
AppFactory::setContainer($container);
$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->addBodyParsingMiddleware();
$app->add(new \Domovoy\Middleware\AuthMiddleware());
$app->addErrorMiddleware(true, true, true);
// Public routes
$app->get('/login', [\Domovoy\Controllers\AuthController::class, 'loginForm'])->setName('login');
$app->post('/login', [\Domovoy\Controllers\AuthController::class, 'login'])->setName('login.post');
$app->get('/setup', [\Domovoy\Controllers\SetupController::class, 'form'])->setName('setup');
$app->post('/setup', [\Domovoy\Controllers\SetupController::class, 'create'])->setName('setup.post');
// Protected routes
$app->group('', function (\Slim\Routing\RouteCollectorProxy $group) {
$group->get('/dashboard', [\Domovoy\Controllers\DashboardController::class, 'index'])->setName('dashboard');
$group->post('/logout', [\Domovoy\Controllers\AuthController::class, 'logout'])->setName('logout');
// Discovery
$group->get('/discovery', [\Domovoy\Controllers\DiscoveryController::class, 'index'])->setName('discovery');
$group->post('/discovery/scan', [\Domovoy\Controllers\DiscoveryController::class, 'startScan'])->setName('discovery.scan');
$group->post('/discovery/hosts/ignore', [\Domovoy\Controllers\DiscoveryController::class, 'ignoreHost'])->setName('discovery.hosts.ignore');
$group->get('/discovery/jobs/active', [\Domovoy\Controllers\DiscoveryController::class, 'activeJobs'])->setName('discovery.jobs.active');
$group->get('/discovery/jobs/history', [\Domovoy\Controllers\DiscoveryController::class, 'scanHistory'])->setName('discovery.jobs.history');
$group->post('/discovery/jobs/{id}/pause', [\Domovoy\Controllers\DiscoveryController::class, 'pauseJob'])->setName('discovery.jobs.pause');
$group->post('/discovery/jobs/{id}/resume', [\Domovoy\Controllers\DiscoveryController::class, 'resumeJob'])->setName('discovery.jobs.resume');
$group->post('/discovery/jobs/{id}/cancel', [\Domovoy\Controllers\DiscoveryController::class, 'cancelJob'])->setName('discovery.jobs.cancel');
// Discoveries
$group->get('/discoveries', [\Domovoy\Controllers\DiscoveriesController::class, 'index'])->setName('discoveries');
$group->get('/discoveries/table', [\Domovoy\Controllers\DiscoveriesController::class, 'table'])->setName('discoveries.table');
$group->post('/discoveries/merge', [\Domovoy\Controllers\DiscoveriesController::class, 'merge'])->setName('discoveries.merge');
// Network ranges CRUD
$group->post('/discovery/ranges/create', [\Domovoy\Controllers\NetworkRangeController::class, 'create'])->setName('discovery.ranges.create');
$group->post('/discovery/ranges/toggle', [\Domovoy\Controllers\NetworkRangeController::class, 'toggle'])->setName('discovery.ranges.toggle');
$group->post('/discovery/ranges/delete', [\Domovoy\Controllers\NetworkRangeController::class, 'delete'])->setName('discovery.ranges.delete');
// Devices CRUD
$group->get('/devices', [\Domovoy\Controllers\DeviceController::class, 'index'])->setName('devices');
$group->get('/devices/create', [\Domovoy\Controllers\DeviceController::class, 'createForm'])->setName('devices.create');
$group->post('/devices/create', [\Domovoy\Controllers\DeviceController::class, 'create'])->setName('devices.create.post');
$group->get('/devices/{id}', [\Domovoy\Controllers\DeviceController::class, 'show'])->setName('devices.show');
$group->get('/devices/{id}/edit', [\Domovoy\Controllers\DeviceController::class, 'editForm'])->setName('devices.edit');
$group->post('/devices/{id}/update', [\Domovoy\Controllers\DeviceController::class, 'update'])->setName('devices.update');
$group->post('/devices/{id}/delete', [\Domovoy\Controllers\DeviceController::class, 'delete'])->setName('devices.delete');
$group->post('/devices/from-host', [\Domovoy\Controllers\DeviceController::class, 'createFromHost'])->setName('devices.from_host');
});
$app->run();