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)