65 lines
2.2 KiB
PHP
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]);
|