diff --git a/docker/routlin-dash/app/pages/captiveportal/view.py b/docker/routlin-dash/app/pages/captiveportal/view.py index 5173384..5fedfb9 100644 --- a/docker/routlin-dash/app/pages/captiveportal/view.py +++ b/docker/routlin-dash/app/pages/captiveportal/view.py @@ -18,7 +18,7 @@ def collect_tokens(cfg): 'Set Restricted VLAN = Captive Portal on the Network Layout page.' ) - tokens['CAPTIVE_HTTP_PORT'] = str(cp.get('http_port', 8081)) + tokens['CAPTIVE_HTTP_PORT'] = str(cp.get('http_port', 25328)) tokens['CAPTIVE_HTTPS_DOMAIN'] = cp.get('https_domain', '') display_rows = [] diff --git a/docker/routlin-portal/Dockerfile b/docker/routlin-portal/Dockerfile new file mode 100644 index 0000000..c03a8a7 --- /dev/null +++ b/docker/routlin-portal/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11-slim +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY app/ . +CMD ["python", "main.py"] diff --git a/docker/routlin-portal/app/config_utils.py b/docker/routlin-portal/app/config_utils.py new file mode 100644 index 0000000..58de7d0 --- /dev/null +++ b/docker/routlin-portal/app/config_utils.py @@ -0,0 +1,23 @@ +import copy, json, os + +CONFIGS_DIR = '/routlin_location' +CONFIG_FILE = f'{CONFIGS_DIR}/config.json' +CAPTIVE_QUEUE = f'{CONFIGS_DIR}/.captive-queue' + +_config_cache = None +_config_mtime = None + + +def load_config(): + global _config_cache, _config_mtime + try: + mtime = os.path.getmtime(CONFIG_FILE) + if _config_cache is not None and mtime == _config_mtime: + return copy.deepcopy(_config_cache) + with open(CONFIG_FILE) as f: + data = json.load(f) + _config_cache = data + _config_mtime = mtime + return copy.deepcopy(data) + except Exception: + return {} diff --git a/docker/routlin-portal/app/main.py b/docker/routlin-portal/app/main.py new file mode 100644 index 0000000..ccd8638 --- /dev/null +++ b/docker/routlin-portal/app/main.py @@ -0,0 +1,10 @@ +from flask import Flask +from pages.portal.page import bp as portal_bp + +app = Flask(__name__) +app.register_blueprint(portal_bp) + +if __name__ == '__main__': + import config_utils + port = config_utils.load_config().get('captive_portal', {}).get('http_port', 25328) + app.run(host='0.0.0.0', port=port) diff --git a/docker/routlin-portal/app/pages/portal/__init__.py b/docker/routlin-portal/app/pages/portal/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/docker/routlin-portal/app/pages/portal/page.py b/docker/routlin-portal/app/pages/portal/page.py new file mode 100644 index 0000000..982dc9c --- /dev/null +++ b/docker/routlin-portal/app/pages/portal/page.py @@ -0,0 +1,89 @@ +import ipaddress +from flask import Blueprint, request, redirect +import config_utils + +bp = Blueprint('portal', __name__) + +PORTAL_HTML = """\ + + +
+ + +No terms required.
' + return PORTAL_HTML.format( + title=vlan.get('portal_splash_title', 'Guest Portal'), + splash_html=f'{vlan["portal_splash_text"]}
' if vlan.get('portal_splash_text') else '', + error_html=f'{error}
' if error else '', + terms_html=terms_html, + next_url=next_url, + ) + + +@bp.route('/', defaults={'path': ''}, methods=['GET', 'POST']) +@bp.route('/