Files
daynivo-kiosk-os/src/voxip_kiosk/web/__init__.py
T
rothmanandClaude Opus 5.5 a33c4822bf
CI / test-bookworm (push) Failing after 11s
CI / test-latest (push) Successful in 1m27s
VoxIP Kiosk OS 1.0.0: Raspberry Pi kiosk with web management
Chromium kiosk without a desktop for the Raspberry Pi 3, a Flask web
interface on port 8080 (kiosk, system and network management), a
restricted root helper, network changes with automatic rollback, a
healthcheck timer, install/update/uninstall scripts and a pi-gen image
build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 21:38:49 +01:00

74 lines
1.9 KiB
Python

"""VoxIP Kiosk Manager — Flask application factory."""
from __future__ import annotations
import os
import secrets
from dataclasses import dataclass
from datetime import timedelta
from typing import Any
from flask import Flask
from ..cdp import CDP
from ..config import load_config
from ..helper_client import HelperClient
from ..paths import Paths, load_paths, read_version
from .auth import CredentialStore, LoginThrottle
@dataclass
class Services:
paths: Paths
credentials: CredentialStore
throttle: LoginThrottle
helper: Any
cdp: Any
version: str
def _secret_key(paths: Paths) -> bytes:
path = paths.secret_key_file
try:
key = path.read_bytes()
if len(key) >= 32:
return key
except FileNotFoundError:
pass
key = secrets.token_bytes(64)
fd = os.open(str(path), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
with os.fdopen(fd, "wb") as fh:
fh.write(key)
return key
def create_app(paths: Paths | None = None, *, helper: Any = None, cdp: Any = None) -> Flask:
paths = paths or load_paths()
config = load_config(paths.config_file)
app = Flask(__name__)
app.secret_key = _secret_key(paths)
app.config.update(
SESSION_COOKIE_NAME="voxip_session",
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE="Strict",
SESSION_COOKIE_SECURE=config["admin_https"],
PERMANENT_SESSION_LIFETIME=timedelta(hours=12),
MAX_CONTENT_LENGTH=64 * 1024,
TEMPLATES_AUTO_RELOAD=False,
)
credentials = CredentialStore(paths.admin_file, paths.setup_code_file)
credentials.ensure_setup_code()
app.extensions["voxip"] = Services(
paths=paths,
credentials=credentials,
throttle=LoginThrottle(),
helper=helper or HelperClient(paths.helper),
cdp=cdp or CDP(timeout=5),
version=read_version(paths),
)
from .views import bp
app.register_blueprint(bp)
return app