Development
This commit is contained in:
parent
bb07e67d53
commit
69b5f00d5b
8 changed files with 165 additions and 26 deletions
|
|
@ -17,7 +17,7 @@ def options_save():
|
|||
before = copy.deepcopy(cfg.get('captive_portal', {}))
|
||||
|
||||
try:
|
||||
http_port = int(request.form.get('http_port', '8081'))
|
||||
http_port = int(request.form.get('http_port', '25328'))
|
||||
if not (1024 <= http_port <= 65535):
|
||||
raise ValueError
|
||||
except (ValueError, TypeError):
|
||||
|
|
@ -46,25 +46,32 @@ def portal_save():
|
|||
flash('Captive portal VLAN not found.', 'error')
|
||||
return redirect(f'/{_PAGE}')
|
||||
|
||||
before = {
|
||||
'portal_splash_title': vlan.get('portal_splash_title', ''),
|
||||
'portal_splash_text': vlan.get('portal_splash_text', ''),
|
||||
'portal_terms': vlan.get('portal_terms', []),
|
||||
}
|
||||
existing = vlan.get('captive_portal', {})
|
||||
before = dict(existing)
|
||||
|
||||
splash_title = sanitize.description(request.form.get('portal_splash_title', ''))
|
||||
splash_text = sanitize.description(request.form.get('portal_splash_text', ''))
|
||||
terms = [t.strip() for t in request.form.getlist('portal_terms') if t.strip()]
|
||||
require_upw = 'require_username_password' in request.form
|
||||
|
||||
vlan['portal_splash_title'] = splash_title
|
||||
vlan['portal_splash_text'] = splash_text
|
||||
vlan['portal_terms'] = terms
|
||||
try:
|
||||
dur_n = int(request.form.get('default_duration_value', '0').strip() or '0')
|
||||
dur_unit = request.form.get('default_duration_unit', 'hours')
|
||||
mult = {'hours': 3600, 'days': 86400}.get(dur_unit, 3600)
|
||||
duration = dur_n * mult if dur_n > 0 else 0
|
||||
except (ValueError, TypeError):
|
||||
duration = 0
|
||||
|
||||
after = {
|
||||
'portal_splash_title': splash_title,
|
||||
'portal_splash_text': splash_text,
|
||||
'portal_terms': terms,
|
||||
**existing,
|
||||
'portal_splash_title': splash_title,
|
||||
'portal_splash_text': splash_text,
|
||||
'portal_terms': terms,
|
||||
'require_username_password': require_upw,
|
||||
'default_duration_seconds': duration,
|
||||
}
|
||||
vlan['captive_portal'] = after
|
||||
|
||||
changes = config_utils.diff_fields(before, after)
|
||||
flash(config_utils.record_group(
|
||||
cfg, 'vlans', 'portal', vlan_name, changes, 'core apply'
|
||||
|
|
|
|||
|
|
@ -86,6 +86,12 @@
|
|||
"label": "Terms",
|
||||
"field": "portal_terms_display",
|
||||
"class": "col-narrow"
|
||||
},
|
||||
{
|
||||
"label": "U/P Required",
|
||||
"field": "require_upw",
|
||||
"class": "col-narrow",
|
||||
"render": "badge_yes_no"
|
||||
}
|
||||
],
|
||||
"row_actions": [
|
||||
|
|
@ -140,6 +146,41 @@
|
|||
"item_placeholder": "e.g. I agree to the acceptable use policy.",
|
||||
"hint": "Each term renders as a required checkbox the user must tick before submitting credentials. Leave empty for no terms."
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"label": "",
|
||||
"name": "require_username_password",
|
||||
"input_type": "checkbox",
|
||||
"checkbox_label": "Require username and password"
|
||||
},
|
||||
{
|
||||
"type": "field_row",
|
||||
"cols": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "field",
|
||||
"label": "Default Session Duration",
|
||||
"name": "default_duration_value",
|
||||
"input_type": "number",
|
||||
"min": 0,
|
||||
"value": "0",
|
||||
"hint": "How long portal access lasts after authentication. 0 = no expiration."
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"label": "Unit",
|
||||
"name": "default_duration_unit",
|
||||
"input_type": "select",
|
||||
"options": [
|
||||
{"value": "hours", "label": "Hours"},
|
||||
{"value": "days", "label": "Days"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "button_row",
|
||||
"items": [
|
||||
|
|
|
|||
|
|
@ -23,14 +23,22 @@ def collect_tokens(cfg):
|
|||
|
||||
display_rows = []
|
||||
for vlan in captive_vlans:
|
||||
terms = vlan.get('portal_terms', [])
|
||||
cp = vlan.get('captive_portal', {})
|
||||
title = cp.get('portal_splash_title', vlan.get('portal_splash_title', ''))
|
||||
text = cp.get('portal_splash_text', vlan.get('portal_splash_text', ''))
|
||||
terms = cp.get('portal_terms', vlan.get('portal_terms', []))
|
||||
require_upw = cp.get('require_username_password', vlan.get('require_username_password', False))
|
||||
duration = cp.get('default_duration_seconds', vlan.get('default_duration_seconds', 0))
|
||||
n = len(terms)
|
||||
display_rows.append({
|
||||
'vlan_name': vlan['name'],
|
||||
'portal_splash_title': vlan.get('portal_splash_title', ''),
|
||||
'portal_splash_text': vlan.get('portal_splash_text', ''),
|
||||
'portal_terms': terms,
|
||||
'portal_terms_display': f'{n} term{"s" if n != 1 else ""}' if n else '--',
|
||||
'vlan_name': vlan['name'],
|
||||
'portal_splash_title': title,
|
||||
'portal_splash_text': text,
|
||||
'portal_terms': terms,
|
||||
'portal_terms_display': f'{n} term{"s" if n != 1 else ""}' if n else '--',
|
||||
'require_upw': require_upw,
|
||||
'require_username_password': require_upw,
|
||||
'default_duration_seconds': duration,
|
||||
})
|
||||
|
||||
content = factory.load_json(f'{factory.PAGES_DIR}/captiveportal/content.json')
|
||||
|
|
|
|||
|
|
@ -126,6 +126,10 @@
|
|||
"type": "raw_html",
|
||||
"html": "</div>"
|
||||
},
|
||||
{
|
||||
"type": "raw_html",
|
||||
"html": "<div id=\"captive-portal-mode-note\" style=\"display:none\"></div>"
|
||||
},
|
||||
{
|
||||
"type": "hr"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -78,7 +78,17 @@ def collect_tokens(cfg):
|
|||
captive_vlans = [v for v in cfg.get('vlans', []) if v.get('restricted_vlan') == 'c']
|
||||
tokens['CAPTIVE_VLAN_OPTIONS'] = json.dumps(
|
||||
[{'value': '', 'label': '-- Select VLAN --'}] +
|
||||
[{'value': v['name'], 'label': f"{v['name']} (VLAN {v['vlan_id']})"} for v in captive_vlans]
|
||||
[
|
||||
{
|
||||
'value': v['name'],
|
||||
'label': f"{v['name']} (VLAN {v['vlan_id']})",
|
||||
'require_upw': v.get('captive_portal', {}).get('require_username_password',
|
||||
v.get('require_username_password', False)),
|
||||
'default_duration_seconds': v.get('captive_portal', {}).get('default_duration_seconds',
|
||||
v.get('default_duration_seconds', 0)),
|
||||
}
|
||||
for v in captive_vlans
|
||||
]
|
||||
)
|
||||
|
||||
raw_rows = _load_credentials()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue