Document the PHP api layer and fix what documenting it exposed
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.
This commit is contained in:
@@ -1,4 +1,68 @@
|
||||
<?php
|
||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||
// PURPOSE
|
||||
// Unraid API key provisioning. Runs unraid_api_key_renew.sh for this host and reports a
|
||||
// masked preview of the key that ended up in the conf — the "create key" action on the
|
||||
// setup and partnership tabs.
|
||||
//
|
||||
// OPERATIONAL MODEL
|
||||
// Provisioning for the local host only. There is no host parameter: the target is whatever
|
||||
// vv_detect_host() resolves to, because a key can only be created on the machine that owns
|
||||
// the API it authenticates against. A partner's key is created on the partner.
|
||||
//
|
||||
// Repair, not just creation. The underlying script is the same one the array-start and
|
||||
// 15-minute watchdog runs call, because the registry it writes can be cleared by a service
|
||||
// restart rather than only by a reboot. Running it against a host that already has a valid
|
||||
// key is a no-op that re-registers, which is why this endpoint is safe to press twice.
|
||||
//
|
||||
// DESIGN PRINCIPLES
|
||||
// Idempotent by delegation.
|
||||
// This file contains no key logic at all. Whether a key needs creating, renewing, or
|
||||
// leaving alone is decided in one place — the shell script — so the UI path and the
|
||||
// scheduled path can never diverge on that judgement.
|
||||
//
|
||||
// The key is never returned.
|
||||
// Only a masked preview (first 8, last 4) leaves the server. The full value lives in
|
||||
// host*.conf, which is the only place anything reads it from. There is no workflow that
|
||||
// needs the key in a browser, so it is not sent to one.
|
||||
//
|
||||
// OPERATIONAL SAFEGUARDS
|
||||
// The host slot is validated before it is used to compose a conf filename.
|
||||
// vv_detect_host() can return 'unknown' when hostname matching fails, and 'unknown.conf'
|
||||
// is not a file that should be read or written. ^host\d+$ is enforced first, so a host
|
||||
// this plugin cannot identify gets a clear error instead of a confusing failure deeper
|
||||
// in the script.
|
||||
//
|
||||
// A missing script is reported, not executed.
|
||||
// vv_auto_create_api_key() checks file_exists() before exec(), so a partial deploy
|
||||
// returns a named error rather than a shell failure surfacing as an empty key.
|
||||
//
|
||||
// The script run is externally time-boxed.
|
||||
// `timeout 120` wraps it inside the library — PHP's own limit does not cover exec()
|
||||
// time on Linux, so a stalled unraid-api call would otherwise hold a php-fpm worker
|
||||
// open indefinitely. Exit 124 is reported as a timeout, distinctly from a script error.
|
||||
//
|
||||
// Never cached.
|
||||
// Cache-Control: no-store, no-cache. A cached provisioning response would report an old
|
||||
// key preview after a genuine renewal — the one moment the preview matters.
|
||||
//
|
||||
// Known gap: this is a state-changing action served over GET.
|
||||
// Both callers (pages/setup.php, pages/partnership.php) fetch it, and POST bodies are
|
||||
// unreliable on this nginx/PHP setup. It is guarded by the Unraid WebGUI session rather
|
||||
// than by method or token. Documented rather than silently accepted — see the CSRF note
|
||||
// in README-unraid.md.
|
||||
//
|
||||
// REQUEST
|
||||
// GET, no parameters (the target host is the local host, by construction)
|
||||
//
|
||||
// RESPONSE
|
||||
// {"ok":true,"key_preview":"abcd1234...wxyz"} or "registered" when the key is not readable
|
||||
// {"ok":false,"error":string} unknown host, missing script, or timeout
|
||||
//
|
||||
// DEPENDS ON
|
||||
// include/config.php vv_detect_host(), vv_auto_create_api_key()
|
||||
// System_Essentials/unraid_api_key_renew.sh
|
||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||
header('Content-Type: application/json');
|
||||
header('Cache-Control: no-store, no-cache');
|
||||
require_once dirname(__DIR__) . '/include/config.php';
|
||||
|
||||
Reference in New Issue
Block a user