added network specs request

This commit is contained in:
Luca Haid
2026-02-02 13:33:27 +01:00
parent f8e36a1d05
commit 3391c74586
4 changed files with 500 additions and 23 deletions

View File

@@ -3,6 +3,11 @@ use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class RadiusController extends mfBaseController {
// FritzBox API configuration
private const FRITZBOX_API_URL = "http://acs.xinon.at:5000";
private const FRITZBOX_API_KEY = "2H9zWrgxPEJL9MZ1yTGtWh16cPCu0AsQ";
private const FRITZBOX_PORT = "9090";
private User $me;
private bool $isApiCall = false;
@@ -113,15 +118,14 @@ class RadiusController extends mfBaseController {
$ip = $externalIp ?: $managementIp;
if (!$ip) self::sendError("Could not determine device IP");
$url = "http://acs.xinon.at:5000/run-speedtest";
$apiKey = "2H9zWrgxPEJL9MZ1yTGtWh16cPCu0AsQ";
$url = self::FRITZBOX_API_URL . "/run-speedtest";
$data = json_encode(['ip' => $ip]);
$opts = [
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\n" .
"X-API-Key: " . $apiKey . "\r\n" .
"X-API-Key: " . self::FRITZBOX_API_KEY . "\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
"content" => $data
]
@@ -445,12 +449,11 @@ class RadiusController extends mfBaseController {
$creds = $acs->createRemoteUser($resolvedId);
if (!$creds) self::sendError("Could not obtain credentials for FritzBox");
$url = "http://acs.xinon.at:5000/read-fritz-eventlog";
$apiKey = "2H9zWrgxPEJL9MZ1yTGtWh16cPCu0AsQ";
$url = self::FRITZBOX_API_URL . "/read-fritz-eventlog";
$data = json_encode([
'fritz_ip' => $creds['ip'],
'fritz_port' => "9090",
'fritz_port' => self::FRITZBOX_PORT,
'fritz_user' => $creds['username'],
'fritz_pass' => $creds['password']
]);
@@ -459,7 +462,7 @@ class RadiusController extends mfBaseController {
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\n" .
"X-API-Key: " . $apiKey . "\r\n" .
"X-API-Key: " . self::FRITZBOX_API_KEY . "\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
"content" => $data,
"timeout" => 60
@@ -484,11 +487,12 @@ class RadiusController extends mfBaseController {
}
}
protected function genieacsNetworkStructureAction() {
protected function genieacsFritzboxWlanKeyAction() {
try {
$input = json_decode(file_get_contents('php://input'), true);
$deviceId = $input['deviceId'] ?? null;
$this->log->debug("genieacsNetworkStructureAction", ['deviceId' => $deviceId]);
$forceRefresh = $input['forceRefresh'] ?? false;
$this->log->debug("genieacsFritzboxWlanKeyAction", ['deviceId' => $deviceId, 'forceRefresh' => $forceRefresh]);
if (!$deviceId) self::sendError("Device ID is required");
@@ -497,15 +501,98 @@ class RadiusController extends mfBaseController {
$resolvedId = $this->resolveDeviceId($deviceId, $acs);
if (!$resolvedId) self::sendError("Device not found in GenieACS");
// Check cache first (1 hour TTL = 3600s)
$cacheKey = "fritzbox_wlan_" . $resolvedId;
if (!$forceRefresh) {
$cached = $acs->getCachePublic($cacheKey, 3600);
if ($cached) {
$this->log->debug("WLAN Key: returning cached data");
self::returnJson(['success' => true, 'wlan' => $cached, 'cached' => true]);
return;
}
}
$creds = $acs->createRemoteUser($resolvedId);
if (!$creds) self::sendError("Could not obtain credentials for FritzBox");
$url = "http://acs.xinon.at:5000/read-fritz";
$apiKey = "2H9zWrgxPEJL9MZ1yTGtWh16cPCu0AsQ";
$url = self::FRITZBOX_API_URL . "/read-fritz-wlan-key";
$data = json_encode([
'fritz_ip' => $creds['ip'],
'fritz_port' => "9090",
'fritz_port' => self::FRITZBOX_PORT,
'fritz_user' => $creds['username'],
'fritz_pass' => $creds['password']
]);
$opts = [
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\n" .
"X-API-Key: " . self::FRITZBOX_API_KEY . "\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
"content" => $data,
"timeout" => 60
]
];
$context = stream_context_create($opts);
$response = file_get_contents($url, false, $context);
if ($response) {
$json = json_decode($response, true);
if ($json && isset($json['wlan'])) {
// Also fetch LAN/DHCP config from GenieACS device data
$device = $acs->getDevice($resolvedId);
$lanConfig = $this->extractLanConfig($device);
$result = array_merge($json['wlan'], ['lan' => $lanConfig]);
// Cache the response
$acs->setCachePublic($cacheKey, $result);
self::returnJson(['success' => true, 'wlan' => $result, 'cached' => false]);
return;
}
}
self::sendError("Failed to fetch WLAN key data");
} catch (Exception $e) {
$this->log->debug("WLAN Key Error", ['error' => $e->getMessage()]);
self::sendError("Error: " . $e->getMessage());
}
}
protected function genieacsNetworkStructureAction() {
try {
$input = json_decode(file_get_contents('php://input'), true);
$deviceId = $input['deviceId'] ?? null;
$forceRefresh = $input['forceRefresh'] ?? false;
$this->log->debug("genieacsNetworkStructureAction", ['deviceId' => $deviceId, 'forceRefresh' => $forceRefresh]);
if (!$deviceId) self::sendError("Device ID is required");
$acs = $this->getGenieACS();
$resolvedId = $this->resolveDeviceId($deviceId, $acs);
if (!$resolvedId) self::sendError("Device not found in GenieACS");
// Check cache first (15 min TTL = 900s)
$cacheKey = "fritzbox_network_" . $resolvedId;
if (!$forceRefresh) {
$cached = $acs->getCachePublic($cacheKey, 900);
if ($cached) {
self::returnJson(['root' => $cached, 'cached' => true]);
return;
}
}
$creds = $acs->createRemoteUser($resolvedId);
if (!$creds) self::sendError("Could not obtain credentials for FritzBox");
$url = self::FRITZBOX_API_URL . "/read-fritz";
$data = json_encode([
'fritz_ip' => $creds['ip'],
'fritz_port' => self::FRITZBOX_PORT,
'fritz_user' => $creds['username'],
'fritz_pass' => $creds['password'],
'page' => 'netDev'
@@ -515,7 +602,7 @@ class RadiusController extends mfBaseController {
"http" => [
"method" => "POST",
"header" => "Content-Type: application/json\r\n" .
"X-API-Key: " . $apiKey . "\r\n" .
"X-API-Key: " . self::FRITZBOX_API_KEY . "\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
"content" => $data,
"timeout" => 60
@@ -623,7 +710,10 @@ class RadiusController extends mfBaseController {
$sortChildren($fbox);
self::returnJson(['root' => $fbox]);
// Cache the processed result
$acs->setCachePublic($cacheKey, $fbox);
self::returnJson(['root' => $fbox, 'cached' => false]);
}
}
@@ -653,9 +743,31 @@ class RadiusController extends mfBaseController {
}
}
/**
* Extract LAN/DHCP configuration from GenieACS device data
*/
private function extractLanConfig($device) {
if (!is_array($device)) return null;
$getParam = function($key) use ($device) {
if (isset($device[$key]['value'][0])) {
return $device[$key]['value'][0];
}
return null;
};
return [
// LAN IP Configuration
'ip' => $getParam('InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.IPInterfaceIPAddress'),
'subnet' => $getParam('InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.IPInterface.1.IPInterfaceSubnetMask'),
// DHCP Configuration
'dhcp_start' => $getParam('InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.MinAddress'),
'dhcp_end' => $getParam('InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.MaxAddress'),
'dns_servers' => $getParam('InternetGatewayDevice.LANDevice.1.LANHostConfigManagement.DNSServers'),
];
}
private function getVendor($mac) {
$mac = strtoupper(str_replace([':', '-', '.'], '', $mac));