Files
reflector-dashboard/auth/node_admins_api.php
T

65 lines
2.2 KiB
PHP

<?php
/*
* Reflector Dashboard — web front-end for SvxReflector
* Copyright (C) 2026 SA7AUX (Björn)
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version. See the LICENSE file for details.
*/
declare(strict_types=1);
// Manage a node's admin list (Redis set node_admins:<CALL>). The node's sysop is
// always the implicit default admin; this stores ADDITIONAL admins.
//
// Owners (user_owns_node) may LIST the admins of their nodes; only site admins
// (admin_level >= 2) may add or remove entries — users must not grant
// themselves or others admin rights.
require __DIR__ . '/lib.php';
$uuid = require_login();
csrf_check();
$in = json_in();
$action = strtolower(trim((string)($in['action'] ?? 'list')));
function na_valid_call(string $cs): bool {
return (bool)preg_match('/^[A-Z0-9]{1,3}[0-9][A-Z0-9]{0,3}[A-Z](-[A-Z0-9]{1,10})?$/', $cs);
}
$node = strtoupper(trim((string)($in['node'] ?? '')));
$admin = strtoupper(trim((string)($in['admin'] ?? '')));
if ($node === '' || !node_callsign_valid($node)) {
json_out(['ok' => false, 'error' => 'invalid_node'], 400);
}
$r = redis();
$key = rkey("node_admins:$node");
// Listing requires ownership (callsign/email/node-admin — user_owns_node).
if (!user_owns_node($uuid, $node)) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
$stored = $r->sMembers($key) ?: [];
if ($action === 'add' || $action === 'remove') {
// Changing the list is site-admin only.
if (acct_admin_level($uuid) < 2) {
json_out(['ok' => false, 'error' => 'forbidden'], 403);
}
if ($admin === '' || !na_valid_call($admin)) {
json_out(['ok' => false, 'error' => 'invalid_admin'], 400);
}
if ($action === 'add') {
$r->sAdd($key, $admin);
} else {
$r->sRem($key, $admin);
}
$stored = $r->sMembers($key) ?: [];
} elseif ($action !== 'list') {
json_out(['ok' => false, 'error' => 'invalid_action'], 400);
}
sort($stored);
json_out(['ok' => true, 'node' => $node, 'admins' => $stored]);