import copy from flask import Blueprint, request, redirect, flash import auth import config_utils import sanitize _PAGE = 'captiveportal' bp = Blueprint(_PAGE, __name__) @bp.route('/action/captiveportal/options_save', methods=['POST']) @auth.require_level('administrator') def options_save(): cfg = config_utils.load_config() before = copy.deepcopy(cfg.get('captive_portal', {})) try: http_port = int(request.form.get('http_port', '25328')) if not (1024 <= http_port <= 65535): raise ValueError except (ValueError, TypeError): flash('HTTP port must be between 1024 and 65535.', 'error') return redirect(f'/{_PAGE}') https_domain = sanitize.description(request.form.get('https_domain', '')) after = {**before, 'http_port': http_port, 'https_domain': https_domain} cfg.setdefault('captive_portal', {}).update(after) changes = config_utils.diff_fields(before, after) flash(config_utils.record_group( cfg, 'captive_portal', 'setting', 'captive_portal', changes, 'core apply' ), 'success') return redirect(f'/{_PAGE}') @bp.route('/action/captiveportal/portal_save', methods=['POST']) @auth.require_level('administrator') def portal_save(): cfg = config_utils.load_config() vlan_name = sanitize.name(request.form.get('vlan_name', '')) vlan = next((v for v in cfg.get('vlans', []) if v['name'] == vlan_name), None) if not vlan or vlan.get('restricted_vlan') != 'c': flash('Captive portal VLAN not found.', 'error') return redirect(f'/{_PAGE}') 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 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 = { **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' ), 'success') return redirect(f'/{_PAGE}')