Development
This commit is contained in:
parent
e52fe9bf8a
commit
db837af548
9 changed files with 98 additions and 25 deletions
|
|
@ -25,8 +25,8 @@
|
|||
{ "type": "nav_item", "label": "VPN", "map_to": "vpn" },
|
||||
{ "type": "nav_item", "label": "Banned IPs", "map_to": "bannedips", "client_requirement": "client_is_administrator+" },
|
||||
{ "type": "nav_item", "label": "RADIUS", "map_to": "radius", "client_requirement": "client_is_administrator+" },
|
||||
{ "type": "nav_item", "label": "Client Credentials", "map_to": "clientcredentials", "client_requirement": "client_is_administrator+" },
|
||||
{ "type": "nav_item", "label": "Captive Portal", "map_to": "captiveportal", "client_requirement": "client_is_administrator+" }
|
||||
{ "type": "nav_item", "label": "Captive Portal", "map_to": "captiveportal", "client_requirement": "client_is_administrator+" },
|
||||
{ "type": "nav_item", "label": "Client Credentials", "map_to": "clientcredentials", "client_requirement": "client_is_administrator+" }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ def portal_save():
|
|||
require_upw = 'require_username_password' in request.form
|
||||
|
||||
try:
|
||||
dur_n = int(request.form.get('default_duration_value', '0').strip() or '0')
|
||||
dur_unit = request.form.get('default_duration_unit', 'hours')
|
||||
dur_n = int(request.form.get('default_session_value', '0').strip() or '0')
|
||||
dur_unit = request.form.get('default_session_unit', 'hours')
|
||||
mult = {'hours': 3600, 'days': 86400}.get(dur_unit, 3600)
|
||||
duration = dur_n * mult if dur_n > 0 else 0
|
||||
except (ValueError, TypeError):
|
||||
|
|
@ -68,7 +68,7 @@ def portal_save():
|
|||
'portal_splash_text': splash_text,
|
||||
'portal_terms': terms,
|
||||
'require_username_password': require_upw,
|
||||
'default_duration_seconds': duration,
|
||||
'default_session_seconds': duration,
|
||||
}
|
||||
vlan['captive_portal'] = after
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,11 @@
|
|||
"field": "portal_terms_display",
|
||||
"class": "col-narrow"
|
||||
},
|
||||
{
|
||||
"label": "Session",
|
||||
"field": "session_display",
|
||||
"class": "col-narrow"
|
||||
},
|
||||
{
|
||||
"label": "U/P Required",
|
||||
"field": "require_upw",
|
||||
|
|
@ -168,7 +173,7 @@
|
|||
{
|
||||
"type": "field",
|
||||
"label": "Default Session Duration",
|
||||
"name": "default_duration_value",
|
||||
"name": "default_session_value",
|
||||
"input_type": "number",
|
||||
"min": 0,
|
||||
"value": "0",
|
||||
|
|
@ -177,7 +182,7 @@
|
|||
{
|
||||
"type": "field",
|
||||
"label": "Unit",
|
||||
"name": "default_duration_unit",
|
||||
"name": "default_session_unit",
|
||||
"input_type": "select",
|
||||
"options": [
|
||||
{"value": "hours", "label": "Hours"},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@ import config_utils
|
|||
import factory
|
||||
|
||||
|
||||
def _format_session(secs):
|
||||
if not secs or secs <= 0:
|
||||
return 'No limit'
|
||||
if secs % 86400 == 0:
|
||||
d = secs // 86400
|
||||
return f'{d} day{"s" if d != 1 else ""}'
|
||||
h = secs / 3600
|
||||
return f'{h:g} h'
|
||||
|
||||
|
||||
def collect_tokens(cfg):
|
||||
tokens = config_utils.collect_layout_tokens(cfg)
|
||||
cp = cfg.get('captive_portal', {})
|
||||
|
|
@ -28,7 +38,7 @@ def collect_tokens(cfg):
|
|||
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))
|
||||
duration = cp.get('default_session_seconds', vlan.get('default_session_seconds', 0))
|
||||
n = len(terms)
|
||||
display_rows.append({
|
||||
'vlan_name': vlan['name'],
|
||||
|
|
@ -38,7 +48,8 @@ def collect_tokens(cfg):
|
|||
'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,
|
||||
'default_session_seconds': duration,
|
||||
'session_display': _format_session(duration),
|
||||
})
|
||||
|
||||
content = factory.load_json(f'{factory.PAGES_DIR}/captiveportal/content.json')
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@
|
|||
},
|
||||
{
|
||||
"type": "raw_html",
|
||||
"html": "<script id=\"captive-vlan-data\" type=\"application/json\">%CAPTIVE_VLAN_OPTIONS%</script><script id=\"page-flags\" type=\"application/json\">{\"pro\": %PRO_LICENSE_JS%}</script>"
|
||||
"html": "<script id=\"captive-vlan-data\" type=\"application/json\">%CAPTIVE_VLAN_OPTIONS%</script><script id=\"page-flags\" type=\"application/json\">{\"pro\": %PRO_LICENSE_JS%, \"radius_session_seconds\": %RADIUS_DEFAULT_SESSION_SECONDS_JS%}</script>"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ def collect_tokens(cfg):
|
|||
'Credentials can be viewed but not added or edited without a Pro license.</span></div>'
|
||||
)
|
||||
tokens['ADD_CREDENTIAL_DISABLED'] = 'true'
|
||||
tokens['RADIUS_DEFAULT_SESSION_SECONDS_JS'] = str(
|
||||
cfg.get('radius', {}).get('options', {}).get('default_session_seconds', 0) or 0
|
||||
)
|
||||
|
||||
vlans = [v for v in cfg.get('vlans', []) if not v.get('is_vpn')]
|
||||
tokens['VLAN_OPTIONS'] = json.dumps(
|
||||
|
|
@ -84,8 +87,8 @@ def collect_tokens(cfg):
|
|||
'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)),
|
||||
'default_session_seconds': v.get('captive_portal', {}).get('default_session_seconds',
|
||||
v.get('default_session_seconds', 0)),
|
||||
}
|
||||
for v in captive_vlans
|
||||
]
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ def auth_mode_save():
|
|||
if auth_mode == 'eap_password':
|
||||
after['eap_protocol'] = eap_protocol
|
||||
after['tunneled_reply'] = tunneled_reply and eap_protocol in ('eap_peap', 'eap_ttls')
|
||||
after['mab_first'] = mab_first
|
||||
after['mab_first'] = mab_first
|
||||
if eap_protocol in _valid_inner and inner_protocol in _valid_inner[eap_protocol]:
|
||||
after['inner_protocol'] = inner_protocol
|
||||
else:
|
||||
|
|
@ -94,18 +94,27 @@ def auth_mode_save():
|
|||
after['include_length'] = include_length
|
||||
else:
|
||||
after.pop('include_length', None)
|
||||
try:
|
||||
dur_n = int(request.form.get('default_session_value', '0').strip() or '0')
|
||||
dur_unit = request.form.get('default_session_unit', 'hours')
|
||||
mult = {'hours': 3600, 'days': 86400}.get(dur_unit, 3600)
|
||||
after['default_session_seconds'] = dur_n * mult if dur_n > 0 else 0
|
||||
except (ValueError, TypeError):
|
||||
after['default_session_seconds'] = 0
|
||||
elif auth_mode == 'eap_credential':
|
||||
after['include_length'] = include_length
|
||||
after['mab_first'] = mab_first
|
||||
after.pop('eap_protocol', None)
|
||||
after.pop('tunneled_reply', None)
|
||||
after.pop('inner_protocol', None)
|
||||
after['mab_first'] = mab_first
|
||||
after.pop('eap_protocol', None)
|
||||
after.pop('tunneled_reply', None)
|
||||
after.pop('inner_protocol', None)
|
||||
after.pop('default_session_seconds', None)
|
||||
else: # mab
|
||||
after.pop('eap_protocol', None)
|
||||
after.pop('tunneled_reply', None)
|
||||
after.pop('inner_protocol', None)
|
||||
after.pop('include_length', None)
|
||||
after.pop('mab_first', None)
|
||||
after.pop('eap_protocol', None)
|
||||
after.pop('tunneled_reply', None)
|
||||
after.pop('inner_protocol', None)
|
||||
after.pop('include_length', None)
|
||||
after.pop('mab_first', None)
|
||||
after.pop('default_session_seconds', None)
|
||||
cfg.setdefault('radius', {})['options'] = after
|
||||
|
||||
changes = config_utils.diff_fields(before, after)
|
||||
|
|
|
|||
|
|
@ -210,6 +210,40 @@
|
|||
"type": "raw_html",
|
||||
"html": "</div>"
|
||||
},
|
||||
{
|
||||
"type": "raw_html",
|
||||
"html": "<div id=\"eap-session-row\">"
|
||||
},
|
||||
{
|
||||
"type": "field_row",
|
||||
"cols": 2,
|
||||
"items": [
|
||||
{
|
||||
"type": "field",
|
||||
"label": "Default Session Duration",
|
||||
"name": "default_session_value",
|
||||
"input_type": "number",
|
||||
"min": 0,
|
||||
"value": "%RADIUS_DEFAULT_SESSION_VALUE%",
|
||||
"hint": "How long a client session lasts before reauthentication is required. 0 = no expiration."
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"label": "Unit",
|
||||
"name": "default_session_unit",
|
||||
"input_type": "select",
|
||||
"value": "%RADIUS_DEFAULT_SESSION_UNIT%",
|
||||
"options": [
|
||||
{"value": "hours", "label": "Hours"},
|
||||
{"value": "days", "label": "Days"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "raw_html",
|
||||
"html": "</div>"
|
||||
},
|
||||
{
|
||||
"type": "button_row",
|
||||
"items": [
|
||||
|
|
|
|||
|
|
@ -123,9 +123,20 @@ def collect_tokens(cfg):
|
|||
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_TUNNELED_REPLY'] = 'true' if fr_opts.get('tunneled_reply', False) else ''
|
||||
tokens['RADIUS_INCLUDE_LENGTH'] = 'true' if fr_opts.get('include_length', False) else ''
|
||||
tokens['RADIUS_MAB_FIRST'] = 'true' if fr_opts.get('mab_first', True) else ''
|
||||
tokens['RADIUS_TUNNELED_REPLY'] = 'true' if fr_opts.get('tunneled_reply', False) else ''
|
||||
tokens['RADIUS_INCLUDE_LENGTH'] = 'true' if fr_opts.get('include_length', False) else ''
|
||||
tokens['RADIUS_MAB_FIRST'] = 'true' if fr_opts.get('mab_first', True) else ''
|
||||
|
||||
secs = fr_opts.get('default_session_seconds', 0) or 0
|
||||
if secs >= 86400 and secs % 86400 == 0:
|
||||
tokens['RADIUS_DEFAULT_SESSION_VALUE'] = str(secs // 86400)
|
||||
tokens['RADIUS_DEFAULT_SESSION_UNIT'] = 'days'
|
||||
elif secs > 0:
|
||||
tokens['RADIUS_DEFAULT_SESSION_VALUE'] = str(max(1, round(secs / 3600)))
|
||||
tokens['RADIUS_DEFAULT_SESSION_UNIT'] = 'hours'
|
||||
else:
|
||||
tokens['RADIUS_DEFAULT_SESSION_VALUE'] = '0'
|
||||
tokens['RADIUS_DEFAULT_SESSION_UNIT'] = 'hours'
|
||||
|
||||
vlans = cfg.get('vlans', [])
|
||||
default_vlan = next((v['name'] for v in vlans if v.get('radius_default') is True), '')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue