fix: update pass credentials to container

This commit is contained in:
2025-08-21 11:41:30 +02:00
parent 6c553bea8a
commit e96bcb7a94
4 changed files with 190 additions and 102 deletions

View File

@ -0,0 +1,85 @@
<?php
namespace App\Controllers;
use App\Services\LxdService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class HandoffController
{
public function post(ServerRequestInterface $req, ResponseInterface $res): ResponseInterface
{
// if (session_status() !== PHP_SESSION_ACTIVE) { session_start(); }
$q = $req->getQueryParams();
$name = (string)($q['name'] ?? '');
$id = (string)($q['handoff'] ?? '');
$path = (string)($q['path'] ?? '/login');
if (!$name || !$id) {
return $this->html($res, 400, '<h1>Bad request</h1>');
}
$lxd = new LxdService();
$ip = $lxd->getContainerIP($name);
if (!$ip) {
return $this->html($res, 503, '<h1>Container not ready</h1>');
}
$key = "handoff:$name:$id";
$data = $_SESSION[$key] ?? null;
unset($_SESSION[$key]); // one-time use
if (!$data || empty($data['username']) || empty($data['password'])) {
return $this->html($res, 410, '<h1>Handoff expired</h1>');
}
// Restrict to relative paths
$path = $this->sanitizePath($path);
// If your container has TLS, prefer https://
$action = 'http://' . $ip . $path;
$html = <<<HTML
<!doctype html>
<html>
<head><meta charset="utf-8"><title>Signing you in…</title></head>
<body>
<form id="f" method="POST" action="{$this->e($action)}">
<input type="hidden" name="username" value="{$this->e($data['username'])}">
<input type="hidden" name="password" value="{$this->e($data['password'])}">
</form>
<script>document.getElementById('f').submit();</script>
<noscript>
<p>JavaScript is required to continue. Click the button below.</p>
<button form="f" type="submit">Continue</button>
</noscript>
</body>
</html>
HTML;
return $this->html($res, 200, $html);
}
private function e(string $s): string
{
return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
private function html(ResponseInterface $res, int $code, string $html): ResponseInterface
{
$res->getBody()->write($html);
return $res->withHeader('Content-Type', 'text/html; charset=utf-8')->withStatus($code);
}
private function sanitizePath(string $raw): string
{
if (preg_match('#^https?://#i', $raw)) return '/login';
if (!str_starts_with($raw, '/')) return '/login';
$path = parse_url($raw, PHP_URL_PATH) ?? '/login';
$allow = ['/', '/login', '/signin'];
return in_array($path, $allow, true) ? $path : '/login';
}
}