import * as plugins from '../../plugins.js'; import type { OpsServer } from '../classes.opsserver.js'; import * as interfaces from '../../../ts_interfaces/index.js'; export class RadiusHandler { public typedrouter = new plugins.typedrequest.TypedRouter(); constructor(private opsServerRef: OpsServer) { // Add this handler's router to the parent this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter); this.registerHandlers(); } private registerHandlers(): void { // ======================================================================== // RADIUS Client Management // ======================================================================== // Get all RADIUS clients this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getRadiusClients', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { clients: [] }; } const clients = radiusServer.getClients(); return { clients: clients.map(c => ({ name: c.name, ipRange: c.ipRange, description: c.description, enabled: c.enabled, })), }; } ) ); // Add or update a RADIUS client this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'setRadiusClient', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { success: false, message: 'RADIUS server not configured' }; } try { await radiusServer.addClient(dataArg.client); return { success: true }; } catch (error) { return { success: false, message: error.message }; } } ) ); // Remove a RADIUS client this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'removeRadiusClient', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { success: false, message: 'RADIUS server not configured' }; } const removed = radiusServer.removeClient(dataArg.name); return { success: removed, message: removed ? undefined : 'Client not found', }; } ) ); // ======================================================================== // VLAN Mapping Management // ======================================================================== // Get all VLAN mappings this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getVlanMappings', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { mappings: [], config: { defaultVlan: 1, allowUnknownMacs: true }, }; } const vlanManager = radiusServer.getVlanManager(); const mappings = vlanManager.getAllMappings(); const config = vlanManager.getConfig(); return { mappings: mappings.map(m => ({ mac: m.mac, vlan: m.vlan, description: m.description, enabled: m.enabled, createdAt: m.createdAt, updatedAt: m.updatedAt, })), config: { defaultVlan: config.defaultVlan, allowUnknownMacs: config.allowUnknownMacs, }, }; } ) ); // Add or update a VLAN mapping this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'setVlanMapping', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { success: false, message: 'RADIUS server not configured' }; } try { const vlanManager = radiusServer.getVlanManager(); const mapping = await vlanManager.addMapping(dataArg.mapping); return { success: true, mapping: { mac: mapping.mac, vlan: mapping.vlan, description: mapping.description, enabled: mapping.enabled, createdAt: mapping.createdAt, updatedAt: mapping.updatedAt, }, }; } catch (error) { return { success: false, message: error.message }; } } ) ); // Remove a VLAN mapping this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'removeVlanMapping', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { success: false, message: 'RADIUS server not configured' }; } const vlanManager = radiusServer.getVlanManager(); const removed = await vlanManager.removeMapping(dataArg.mac); return { success: removed, message: removed ? undefined : 'Mapping not found', }; } ) ); // Update VLAN configuration this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'updateVlanConfig', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { success: false, config: { defaultVlan: 1, allowUnknownMacs: true }, }; } const vlanManager = radiusServer.getVlanManager(); vlanManager.updateConfig({ defaultVlan: dataArg.defaultVlan, allowUnknownMacs: dataArg.allowUnknownMacs, }); const config = vlanManager.getConfig(); return { success: true, config: { defaultVlan: config.defaultVlan, allowUnknownMacs: config.allowUnknownMacs, }, }; } ) ); // Test VLAN assignment this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'testVlanAssignment', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { assigned: false, vlan: 0, isDefault: false }; } const vlanManager = radiusServer.getVlanManager(); const result = vlanManager.assignVlan(dataArg.mac); return { assigned: result.assigned, vlan: result.vlan, isDefault: result.isDefault, matchedRule: result.matchedRule ? { mac: result.matchedRule.mac, vlan: result.matchedRule.vlan, description: result.matchedRule.description, } : undefined, }; } ) ); // ======================================================================== // Accounting / Session Management // ======================================================================== // Get active sessions this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getRadiusSessions', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { sessions: [], totalCount: 0 }; } const accountingManager = radiusServer.getAccountingManager(); let sessions = accountingManager.getActiveSessions(); // Apply filters if (dataArg.filter) { if (dataArg.filter.username) { sessions = sessions.filter(s => s.username === dataArg.filter!.username); } if (dataArg.filter.nasIpAddress) { sessions = sessions.filter(s => s.nasIpAddress === dataArg.filter!.nasIpAddress); } if (dataArg.filter.vlanId !== undefined) { sessions = sessions.filter(s => s.vlanId === dataArg.filter!.vlanId); } } return { sessions: sessions.map(s => ({ sessionId: s.sessionId, username: s.username, macAddress: s.macAddress, nasIpAddress: s.nasIpAddress, nasIdentifier: s.nasIdentifier, vlanId: s.vlanId, framedIpAddress: s.framedIpAddress, startTime: s.startTime, lastUpdateTime: s.lastUpdateTime, status: s.status, inputOctets: s.inputOctets, outputOctets: s.outputOctets, sessionTime: s.sessionTime, })), totalCount: sessions.length, }; } ) ); // Disconnect a session this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'disconnectRadiusSession', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { success: false, message: 'RADIUS server not configured' }; } const accountingManager = radiusServer.getAccountingManager(); const disconnected = await accountingManager.disconnectSession( dataArg.sessionId, dataArg.reason || 'AdminReset' ); return { success: disconnected, message: disconnected ? undefined : 'Session not found', }; } ) ); // Get accounting summary this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getRadiusAccountingSummary', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { summary: { periodStart: dataArg.startTime, periodEnd: dataArg.endTime, totalSessions: 0, activeSessions: 0, totalInputBytes: 0, totalOutputBytes: 0, totalSessionTime: 0, averageSessionDuration: 0, uniqueUsers: 0, sessionsByVlan: {}, topUsersByTraffic: [], }, }; } const accountingManager = radiusServer.getAccountingManager(); const summary = await accountingManager.getSummary(dataArg.startTime, dataArg.endTime); return { summary }; } ) ); // ======================================================================== // Statistics // ======================================================================== // Get RADIUS statistics this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getRadiusStatistics', async (dataArg, toolsArg) => { const radiusServer = this.opsServerRef.dcRouterRef.radiusServer; if (!radiusServer) { return { stats: { running: false, uptime: 0, authRequests: 0, authAccepts: 0, authRejects: 0, accountingRequests: 0, activeSessions: 0, vlanMappings: 0, clients: 0, }, vlanStats: { totalMappings: 0, enabledMappings: 0, exactMatches: 0, ouiPatterns: 0, wildcardPatterns: 0, }, accountingStats: { activeSessions: 0, totalSessionsStarted: 0, totalSessionsStopped: 0, totalInputBytes: 0, totalOutputBytes: 0, interimUpdatesReceived: 0, }, }; } const stats = radiusServer.getStats(); const vlanStats = radiusServer.getVlanManager().getStats(); const accountingStats = radiusServer.getAccountingManager().getStats(); return { stats, vlanStats, accountingStats, }; } ) ); } }