Add URL whitelist enforcement for Kiosk-mode and enhance configuration management

- Introduced `allowed_urls` in configuration to specify whitelisted domains/patterns.
- Implemented `RestrictedWebEngineView` to enforce URL restrictions in the web view.
- Updated `MainWindow` to utilize the new restricted web view and added navigation toolbar.
- Enhanced unit tests for configuration and restricted web view to cover new functionality.
This commit is contained in:
claudi 2026-01-28 11:33:37 +01:00
parent 6bef2f6119
commit 86034358b7
6 changed files with 529 additions and 33 deletions

View file

@ -3,13 +3,14 @@
from pathlib import Path
from typing import Optional
from PySide6.QtCore import Qt, QUrl
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWidgets import QMainWindow, QVBoxLayout, QWidget
from PySide6.QtCore import QSize, Qt, QUrl
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QMainWindow, QToolBar, QVBoxLayout, QWidget
from webdrop_bridge.config import Config
from webdrop_bridge.core.drag_interceptor import DragInterceptor
from webdrop_bridge.core.validator import PathValidator
from webdrop_bridge.ui.restricted_web_view import RestrictedWebEngineView
class MainWindow(QMainWindow):
@ -43,7 +44,10 @@ class MainWindow(QMainWindow):
)
# Create web engine view
self.web_view = QWebEngineView()
self.web_view = RestrictedWebEngineView(config.allowed_urls)
# Create navigation toolbar (Kiosk-mode navigation)
self._create_navigation_toolbar()
# Create drag interceptor
self.drag_interceptor = DragInterceptor()
@ -135,6 +139,54 @@ class MainWindow(QMainWindow):
# Can be extended with logging or user notification
pass
def _create_navigation_toolbar(self) -> None:
"""Create navigation toolbar with Home, Back, Forward, Refresh buttons.
In Kiosk-mode, users can navigate history but cannot freely browse.
"""
toolbar = QToolBar("Navigation")
toolbar.setMovable(False)
toolbar.setIconSize(QSize(24, 24))
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, toolbar)
# Back button
back_action = self.web_view.pageAction(
self.web_view.WebAction.Back
)
toolbar.addAction(back_action)
# Forward button
forward_action = self.web_view.pageAction(
self.web_view.WebAction.Forward
)
toolbar.addAction(forward_action)
# Separator
toolbar.addSeparator()
# Home button
home_action = toolbar.addAction("Home")
home_action.triggered.connect(self._navigate_home)
# Refresh button
refresh_action = self.web_view.pageAction(
self.web_view.WebAction.Reload
)
toolbar.addAction(refresh_action)
def _navigate_home(self) -> None:
"""Navigate to the home (start) URL."""
home_url = self.config.webapp_url
if home_url.startswith("http://") or home_url.startswith("https://"):
self.web_view.load(QUrl(home_url))
else:
try:
file_path = Path(home_url).resolve()
file_url = file_path.as_uri()
self.web_view.load(QUrl(file_url))
except (OSError, ValueError):
pass
def closeEvent(self, event) -> None:
"""Handle window close event.