Make the Auth tab explain a number instead of only showing it
A low uptime figure, a refused login and a certificate that stopped renewing all looked the same from the row: a number, with the reason split across NPM, an Authelia config and the directory. The why-check goes and looks — TCP to the forward target, HTTP through the proxy, a second handshake with verification off to tell a broken certificate from a broken service. Forward hosts are docker names that only resolve on NPM's network, so an unresolvable one is redirected to the container address and the substitution is reported; a check that could not be made must never read as a check that failed. The access simulator walks the rules the way Authelia does and shows the ones it stepped over, reading whichever instance the chosen host points at rather than the one conf names — there are two here. Cert triage counts runs rather than log lines and orders by rotation suffix rather than mtime, both of which change the answer.
This commit is contained in:
@@ -66,7 +66,10 @@
|
||||
// actions are reads and are deliberately outside it. See README-unraid.md.
|
||||
//
|
||||
// REQUEST
|
||||
// GET ?action=npm_proxies | npm_certs | lldap_users | lldap_groups | authelia_rules
|
||||
// GET ?action=npm_proxies | npm_certs | npm_stats | npm_uptime | lldap_users | lldap_groups
|
||||
// | authelia_rules
|
||||
// GET ?action=npm_why id
|
||||
// GET ?action=access_check domain, uid, path
|
||||
// POST action=npm_create data=<JSON>
|
||||
// POST action=npm_update id, data=<JSON>
|
||||
// POST action=npm_delete id
|
||||
@@ -103,8 +106,9 @@ require_once dirname(__DIR__) . '/include/auth.php';
|
||||
const VV_AUTH_ACTION_PANEL = [
|
||||
// GET
|
||||
'npm_proxies' => 'proxies', 'npm_certs' => 'proxies', 'npm_stats' => 'proxies', 'npm_uptime' => 'proxies',
|
||||
'npm_why' => 'proxies',
|
||||
'lldap_users' => 'users', 'lldap_groups' => 'users', 'lldap_avatar' => 'users',
|
||||
'authelia_rules' => 'acl',
|
||||
'authelia_rules' => 'acl', 'access_check' => 'acl',
|
||||
// POST
|
||||
'npm_create' => 'proxies', 'npm_update' => 'proxies',
|
||||
'npm_delete' => 'proxies', 'npm_toggle' => 'proxies',
|
||||
@@ -115,14 +119,11 @@ const VV_AUTH_ACTION_PANEL = [
|
||||
'authelia_save' => 'acl',
|
||||
];
|
||||
|
||||
// Same windowing rule as uptime_probe.php: buckets are keyed by time, so "the last N" is a key
|
||||
// sort rather than an assumption that every period produced a sample.
|
||||
// The windowing rule lives in include/auth.php and is shared with Tools/uptime_probe.php. It was
|
||||
// three separate copies of the same six lines, which is three places for the definition of "the
|
||||
// last 24 hours" to drift apart while every one of them keeps returning a plausible number.
|
||||
function vv_uptime_window_api(array $buckets, int $n): ?float {
|
||||
if (!$buckets) return null;
|
||||
krsort($buckets);
|
||||
$u = $t = 0;
|
||||
foreach (array_slice($buckets, 0, $n, true) as $b) { $u += $b['u'] ?? 0; $t += $b['t'] ?? 0; }
|
||||
return $t > 0 ? round($u / $t * 100, 2) : null;
|
||||
return vv_auth_uptime_window($buckets, $n);
|
||||
}
|
||||
|
||||
function vv_auth_action_allowed(string $action): bool {
|
||||
@@ -195,6 +196,28 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Why one host is not at 100%. The only read here that goes and looks rather than serving a
|
||||
// stored figure: it opens a socket to the forward target, asks the domain itself, and inspects
|
||||
// the containers. Slow by the standards of this file — several seconds — which is why it is one
|
||||
// host on demand and never part of the list load.
|
||||
//
|
||||
// A read, so it stays in the GET arm with the other reads. It is worth being explicit that this
|
||||
// is safe to leave outside the CSRF guard: every call it makes is a GET, a HEAD, a TCP connect
|
||||
// or a file read, so the worst a forged request achieves is making this machine look at itself.
|
||||
if ($action === 'npm_why') {
|
||||
echo json_encode(vv_npm_why((int) ($_GET['id'] ?? 0)));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Can this user open this URL, and what decided it. Reads NPM, the Authelia instance that this
|
||||
// particular host talks to, and the directory — the three places the answer is split across.
|
||||
if ($action === 'access_check') {
|
||||
echo json_encode(vv_auth_access_check((string) ($_GET['domain'] ?? ''),
|
||||
(string) ($_GET['uid'] ?? ''),
|
||||
(string) ($_GET['path'] ?? '/')));
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = match ($action) {
|
||||
'npm_proxies' => vv_npm_list_proxies(),
|
||||
'npm_certs' => ['ok' => true, 'certs' => vv_npm_list_certs()],
|
||||
|
||||
@@ -308,5 +308,14 @@ if (!file_exists($cacheFile)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── Why renewals failed ───────────────────────────────────────────────────────
|
||||
// Reads certbot's own logs and names the categories the failures fall into. A read, so GET: it
|
||||
// opens files and nothing else. Bounded inside vv_cert_triage() by file count and bytes per file,
|
||||
// because the log directory here is 639 MB and a page request must not depend on its size.
|
||||
if ($action === 'triage') {
|
||||
echo json_encode(vv_cert_triage());
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents($cacheFile), true) ?: [];
|
||||
echo json_encode(array_merge(['ok' => true], $data));
|
||||
|
||||
Reference in New Issue
Block a user