Development

This commit is contained in:
Matthew Grotke 2026-06-05 02:23:08 -04:00
parent b307461d44
commit 4734eb41a0
3 changed files with 32 additions and 16 deletions

View file

@ -1,7 +1,6 @@
import copy import copy
import gzip import gzip
import io import io
import ipaddress
import os import os
import re import re
from pathlib import Path from pathlib import Path
@ -40,7 +39,7 @@ def regenerate():
def options_save(): def options_save():
mac_format = request.form.get('mac_format', 'aabbccddeeff') mac_format = request.form.get('mac_format', 'aabbccddeeff')
apply_to = request.form.get('apply_to', 'all') apply_to = request.form.get('apply_to', 'all')
ap_ips_raw = request.form.get('ap_ips', '') ap_ips = request.form.getlist('ap_ips')
if mac_format not in VALID_MAC_FORMATS: if mac_format not in VALID_MAC_FORMATS:
flash('Invalid MAC format.', 'error') flash('Invalid MAC format.', 'error')
@ -49,15 +48,17 @@ def options_save():
flash('Invalid apply_to value.', 'error') flash('Invalid apply_to value.', 'error')
return redirect(f'/{_PAGE}') return redirect(f'/{_PAGE}')
ap_ips = [line.strip() for line in ap_ips_raw.splitlines() if line.strip()] cfg = load_config()
valid_ips = {
r['ip'] for r in cfg.get('dhcp_reservations', [])
if r.get('radius_client') is True
and r.get('ip') and r.get('ip') not in ('', 'dynamic')
}
for ip in ap_ips: for ip in ap_ips:
try: if ip not in valid_ips:
ipaddress.IPv4Address(ip) flash(f'Invalid AP selection: {ip}', 'error')
except ValueError:
flash(f'Invalid IP address: {ip}', 'error')
return redirect(f'/{_PAGE}') return redirect(f'/{_PAGE}')
cfg = load_config()
before = copy.deepcopy(cfg.get('radius', {}).get('options', {})) before = copy.deepcopy(cfg.get('radius', {}).get('options', {}))
after = {'mac_format': mac_format, 'apply_to': apply_to, 'ap_ips': ap_ips} after = {'mac_format': mac_format, 'apply_to': apply_to, 'ap_ips': ap_ips}
cfg.setdefault('radius', {})['options'] = after cfg.setdefault('radius', {})['options'] = after

View file

@ -85,13 +85,12 @@
}, },
{ {
"type": "field", "type": "field",
"label": "Access Point IPs", "label": "Which of the following RADIUS Clients are Wireless Access Points that you wish to add to the huntgroup?",
"name": "ap_ips", "name": "ap_ips",
"input_type": "textarea", "input_type": "checkbox_group",
"options": "%RADIUS_AP_IPS_OPTIONS%",
"value": "%RADIUS_AP_IPS%", "value": "%RADIUS_AP_IPS%",
"rows": 4, "hint": "Used when Apply DEFAULT Rule To is set to huntgroup."
"hint": "One IP address per line. Used when Apply DEFAULT Rule To is set to huntgroup.",
"placeholder": "192.168.1.10\n192.168.1.11"
}, },
{ {
"type": "button_row", "type": "button_row",
@ -117,6 +116,9 @@
"type": "p", "type": "p",
"text": "Unknown or unregistered devices are assigned to this VLAN. For wired switch ports, also set the fallback network in the switch configuration." "text": "Unknown or unregistered devices are assigned to this VLAN. For wired switch ports, also set the fallback network in the switch configuration."
}, },
{
"type": "hr"
},
{ {
"type": "form", "type": "form",
"action": "/action/radius/default_vlan_save", "action": "/action/radius/default_vlan_save",
@ -153,6 +155,9 @@
"type": "p", "type": "p",
"text": "These settings are required for MAC-based 802.1X authentication on managed switches." "text": "These settings are required for MAC-based 802.1X authentication on managed switches."
}, },
{
"type": "hr"
},
{ {
"type": "form", "type": "form",
"action": "/action/radius/eap_save", "action": "/action/radius/eap_save",

View file

@ -64,9 +64,19 @@ def collect_tokens(cfg):
fr = cfg.get('radius', {}) fr = cfg.get('radius', {})
fr_opts = fr.get('options', {}) fr_opts = fr.get('options', {})
fr_gen = fr.get('general', {}) fr_gen = fr.get('general', {})
tokens['RADIUS_MAC_FORMAT'] = fr_opts.get('mac_format', 'aabbccddeeff') tokens['RADIUS_MAC_FORMAT'] = fr_opts.get('mac_format', 'aabbccddeeff')
tokens['RADIUS_APPLY_TO'] = fr_opts.get('apply_to', 'all') tokens['RADIUS_APPLY_TO'] = fr_opts.get('apply_to', 'all')
tokens['RADIUS_AP_IPS'] = '\n'.join(fr_opts.get('ap_ips', [])) tokens['RADIUS_AP_IPS'] = json.dumps(fr_opts.get('ap_ips', []))
radius_client_reservations = [
r for r in cfg.get('dhcp_reservations', [])
if r.get('radius_client') is True
and r.get('ip') and r.get('ip') not in ('', 'dynamic')
]
tokens['RADIUS_AP_IPS_OPTIONS'] = json.dumps([
{'value': r['ip'], 'label': f"{r.get('description', r['ip'])} ({r['ip']})"}
for r in radius_client_reservations
])
tokens['RADIUS_LOGGING'] = 'true' if fr_gen.get('logging', False) else '' tokens['RADIUS_LOGGING'] = 'true' if fr_gen.get('logging', False) else ''
tokens['RADIUS_LOGGING_HINT'] = 'Unchecking will clear logs.' if fr_gen.get('logging', False) else '' tokens['RADIUS_LOGGING_HINT'] = 'Unchecking will clear logs.' if fr_gen.get('logging', False) else ''
tokens['RADIUS_GEN_LOG_MAX_KB'] = str(fr_gen.get('log_max_kb', 1024)) tokens['RADIUS_GEN_LOG_MAX_KB'] = str(fr_gen.get('log_max_kb', 1024))