domovoy/app/Controllers/CredentialController.php

98 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
namespace Domovoy\Controllers;
use Domovoy\Models\Credential;
use Domovoy\Repositories\CredentialRepository;
use Domovoy\Services\Inventory\DeviceService;
use Domovoy\Services\Security\CredentialVault;
use Domovoy\Services\Ssh\SshCredentialTester;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class CredentialController
{
public function __construct(
private DeviceService $deviceService,
private CredentialRepository $credentialRepository,
private CredentialVault $vault,
private SshCredentialTester $sshCredentialTester
) {
}
public function create(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$deviceId = (int)$args['id'];
if ($this->deviceService->getDevice($deviceId) === null) {
$response->getBody()->write('Device not found');
return $response->withStatus(404);
}
$data = $request->getParsedBody();
$authMethod = ($data['auth_method'] ?? 'password') === 'private_key' ? 'private_key' : 'password';
$credential = new Credential();
$credential->deviceId = $deviceId;
$credential->type = 'ssh';
$credential->name = trim($data['name'] ?? '') ?: 'SSH';
$credential->username = trim($data['username'] ?? '');
$credential->port = max(1, min(65535, (int)($data['port'] ?? 22)));
$credential->authMethod = $authMethod;
if ($authMethod === 'private_key') {
$privateKey = trim($data['private_key'] ?? '');
if ($privateKey !== '') {
$credential->encryptedPrivateKey = $this->vault->encrypt($privateKey);
}
} else {
$secret = (string)($data['secret'] ?? '');
if ($secret !== '') {
$credential->encryptedSecret = $this->vault->encrypt($secret);
}
}
if ($credential->username === '') {
return $response
->withHeader('Location', '/devices/' . $deviceId)
->withStatus(302);
}
$this->credentialRepository->save($credential);
return $response
->withHeader('Location', '/devices/' . $deviceId)
->withStatus(302);
}
public function test(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$deviceId = (int)$args['deviceId'];
$credential = $this->credentialRepository->findById((int)$args['id']);
$device = $this->deviceService->getDevice($deviceId);
if ($credential === null || $device === null || $credential->deviceId !== $deviceId) {
$response->getBody()->write('Credential not found');
return $response->withStatus(404);
}
$host = $device->primaryIp ?: ($device->hostname ?? '');
$result = $this->sshCredentialTester->test($credential, $host);
$this->credentialRepository->updateTestResult((int)$credential->id, $result['status']);
return $response
->withHeader('Location', '/devices/' . $deviceId)
->withStatus(302);
}
public function delete(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
{
$deviceId = (int)$args['deviceId'];
$this->credentialRepository->deleteForDevice((int)$args['id'], $deviceId);
return $response
->withHeader('Location', '/devices/' . $deviceId)
->withStatus(302);
}
}