Writing down what each endpoint actually guarantees made the places it didn't obvious — shell arguments reaching a crontab or a bash -c unescaped, master.conf written without tmp+rename, and conf edits that could be saved without ever being parsed.
90 lines
4.5 KiB
PHP
90 lines
4.5 KiB
PHP
<?php
|
|
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
|
// PURPOSE
|
|
// Docker folder endpoint. GET returns the full container inventory with folder assignments;
|
|
// POST performs one folder operation — create, rename, delete, move a container, or sync
|
|
// the folder store against master.conf in either direction.
|
|
//
|
|
// OPERATIONAL MODEL
|
|
// Read and write share one URL, split on HTTP method. GET is the docker tab's poll and is
|
|
// always safe. POST carries an `action` naming exactly one library call. Anything that is
|
|
// neither GET nor POST is refused with 405 before a parameter is read.
|
|
//
|
|
// DESIGN PRINCIPLES
|
|
// The action list is a closed match expression, not a dispatch table.
|
|
// Six named actions map to six library functions. An unrecognised action falls to the
|
|
// default arm and returns an error — it cannot resolve to a callable, because no part
|
|
// of the request is ever used to build a function name.
|
|
//
|
|
// Grouping is metadata, never container control.
|
|
// This endpoint moves containers between folders in a JSON store. It does not start,
|
|
// stop, or recreate anything — that is docker_action.php, deliberately a separate file
|
|
// with a separate confirmation path in the UI.
|
|
//
|
|
// Validation belongs to the library.
|
|
// Folder ids and names are trimmed here and checked in include/docker.php, so the same
|
|
// rules apply whether a call arrives from this endpoint or from the conf sync.
|
|
//
|
|
// OPERATIONAL SAFEGUARDS
|
|
// Wrong method is refused with a status code, not just a body.
|
|
// 405 is set alongside the JSON error so a mistaken caller fails visibly rather than
|
|
// parsing an error object as data.
|
|
//
|
|
// Every parameter is optional and defaults to empty.
|
|
// ?? '' on all four inputs means a malformed POST reaches the library as blank strings
|
|
// and is rejected there, rather than raising an undefined-index warning into the JSON
|
|
// body and corrupting the response.
|
|
//
|
|
// The folder store is written atomically by the library.
|
|
// vv_dk_write_json() writes to .vv.tmp and rename()s, so a delete or move interrupted
|
|
// mid-write cannot leave a truncated store — which would scatter every container back
|
|
// to ungrouped.
|
|
//
|
|
// REQUEST
|
|
// GET full inventory, no parameters
|
|
// POST action=move_container container, folder_id
|
|
// POST action=create_folder name
|
|
// POST action=rename_folder folder_id, name
|
|
// POST action=delete_folder folder_id
|
|
// POST action=sync_conf_to_json | sync_json_to_conf no further parameters
|
|
//
|
|
// RESPONSE
|
|
// GET vv_dk_all() verbatim — containers, folders, icons, WebUI links
|
|
// POST {"ok":bool,"error":string|null} as returned by the invoked library call
|
|
//
|
|
// DEPENDS ON
|
|
// include/docker.php vv_dk_all(), vv_dk_move_container(), vv_dk_create_folder(),
|
|
// vv_dk_rename_folder(), vv_dk_delete_folder(),
|
|
// vv_dk_sync_conf_to_json(), vv_dk_sync_json_to_conf()
|
|
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
|
header('Content-Type: application/json');
|
|
require_once dirname(__DIR__) . '/include/docker.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
echo json_encode(vv_dk_all());
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode(['ok' => false, 'error' => 'GET or POST only']);
|
|
exit;
|
|
}
|
|
|
|
$action = trim($_POST['action'] ?? '');
|
|
$container = trim($_POST['container'] ?? '');
|
|
$folderId = trim($_POST['folder_id'] ?? '');
|
|
$name = trim($_POST['name'] ?? '');
|
|
|
|
$result = match ($action) {
|
|
'move_container' => vv_dk_move_container($container, $folderId),
|
|
'create_folder' => vv_dk_create_folder($name),
|
|
'rename_folder' => vv_dk_rename_folder($folderId, $name),
|
|
'delete_folder' => vv_dk_delete_folder($folderId),
|
|
'sync_conf_to_json'=> vv_dk_sync_conf_to_json(),
|
|
'sync_json_to_conf'=> vv_dk_sync_json_to_conf(),
|
|
default => ['ok' => false, 'error' => 'Unknown action: ' . $action],
|
|
};
|
|
|
|
echo json_encode($result);
|