93 lines
3.6 KiB
Python
93 lines
3.6 KiB
Python
from flask import Blueprint, request, redirect, flash
|
|
from auth import require_level
|
|
from config_utils import load_core, save_core, verify_core_hash, apply_msg, _APPLY_CMD_VPN
|
|
import sanitize
|
|
import validate
|
|
|
|
bp = Blueprint('action_apply_vpn', __name__)
|
|
|
|
_VIEW = '/view/view_vpn'
|
|
_MTU_MIN = 576
|
|
_MTU_MAX = 9000
|
|
|
|
|
|
@bp.route('/action/apply_vpn', methods=['POST'])
|
|
@require_level('administrator')
|
|
def apply_vpn():
|
|
listen_port_raw = request.form.get('vpn_listen_port', '').strip()
|
|
gateway_raw = request.form.get('vpn_gateway', '').strip()
|
|
domain = sanitize.hostname(request.form.get('vpn_domain', ''))
|
|
dns_raw = request.form.get('vpn_dns_server', '').strip()
|
|
mtu_raw = request.form.get('vpn_mtu', '').strip()
|
|
|
|
# -- Listen port -----------------------------------------------------------
|
|
if not listen_port_raw:
|
|
flash('The configuration has not been saved because the listen port is required.', 'error')
|
|
return redirect(_VIEW)
|
|
try:
|
|
listen_port = int(listen_port_raw)
|
|
if not (1 <= listen_port <= 65535):
|
|
raise ValueError
|
|
except (ValueError, TypeError):
|
|
flash(f'The configuration has not been saved because "{listen_port_raw}" is not a valid port number (1-65535).', 'error')
|
|
return redirect(_VIEW)
|
|
|
|
# -- Gateway (required) ----------------------------------------------------
|
|
if not gateway_raw:
|
|
flash('The configuration has not been saved because a gateway IP address is required.', 'error')
|
|
return redirect(_VIEW)
|
|
gateway = validate.ip(gateway_raw)
|
|
if not gateway:
|
|
flash(f'The configuration has not been saved because "{gateway_raw}" is not a valid IP address.', 'error')
|
|
return redirect(_VIEW)
|
|
|
|
# -- DNS server (optional) -------------------------------------------------
|
|
dns_server = ''
|
|
if dns_raw:
|
|
dns_server = validate.ip(dns_raw)
|
|
if not dns_server:
|
|
flash(f'The configuration has not been saved because "{dns_raw}" is not a valid IP address for DNS server.', 'error')
|
|
return redirect(_VIEW)
|
|
|
|
# -- MTU (optional) --------------------------------------------------------
|
|
mtu = None
|
|
if mtu_raw:
|
|
try:
|
|
mtu = int(mtu_raw)
|
|
if not (_MTU_MIN <= mtu <= _MTU_MAX):
|
|
raise ValueError
|
|
except (ValueError, TypeError):
|
|
flash(f'The configuration has not been saved because "{mtu_raw}" is not a valid MTU '
|
|
f'(must be a number between {_MTU_MIN} and {_MTU_MAX}).', 'error')
|
|
return redirect(_VIEW)
|
|
|
|
# -- Hash check and save ---------------------------------------------------
|
|
if not verify_core_hash(request.form.get('config_hash', '')):
|
|
flash('Configuration was modified by another session. Please refresh and try again.', 'error')
|
|
return redirect(_VIEW)
|
|
|
|
core = load_core()
|
|
vpn_vlan = next((v for v in core.get('vlans', []) if 'vpn_information' in v), None)
|
|
if vpn_vlan is None:
|
|
flash('The configuration has not been saved because no VPN VLAN was found in the configuration.', 'error')
|
|
return redirect(_VIEW)
|
|
|
|
info = vpn_vlan.setdefault('vpn_information', {})
|
|
info['listen_port'] = listen_port
|
|
info['gateway'] = gateway
|
|
info['domain'] = domain
|
|
|
|
overrides = info.setdefault('explicit_overrides', {})
|
|
if dns_server:
|
|
overrides['dns_server'] = dns_server
|
|
else:
|
|
overrides.pop('dns_server', None)
|
|
if mtu is not None:
|
|
overrides['mtu'] = mtu
|
|
else:
|
|
overrides.pop('mtu', None)
|
|
|
|
save_core(core)
|
|
|
|
flash(apply_msg(_APPLY_CMD_VPN), 'success')
|
|
return redirect(_VIEW)
|