include cert.pem for SSL verification in frozen builds and update build process to handle CA bundles

This commit is contained in:
Ross
2025-11-24 15:30:48 +00:00
parent 84d18f25e1
commit 377be258de
4 changed files with 100 additions and 5 deletions
+65 -4
View File
@@ -14,6 +14,7 @@ from datetime import datetime
from loguru import logger
import sys
import os
from anonymiser import Anonymizer
import pydicom
@@ -41,7 +42,11 @@ import importlib.util
# traceback was previously imported for debugging but is unused
# TODO fix ssl
# SSL verification setting. Can be a boolean (True/False) or a path to
# a CA bundle (PEM file) used by requests' 'verify' parameter.
# Default is True. It can be overridden via CLI options (--ca-bundle,
# --insecure) or environment variables: NICE_UPLOADER_CA_BUNDLE,
# REQUESTS_CA_BUNDLE or SSL_CERT_FILE.
VERIFY_SSL = True
SOCKET_PATH = "tcp://localhost:9976"
@@ -79,8 +84,14 @@ logging.getLogger('niceGUI').setLevel(logging.INFO)
# application is frozen into a single executable (PyInstaller --onefile).
try:
if getattr(sys, "frozen", False):
# When frozen, place logs next to the executable
base_path = Path(sys.executable).resolve().parent
# When frozen by PyInstaller, data files are extracted to a temporary
# folder available as sys._MEIPASS. Fall back to the executable
# directory when _MEIPASS is not present.
meipass = getattr(sys, "_MEIPASS", None)
if meipass:
base_path = Path(meipass)
else:
base_path = Path(sys.executable).resolve().parent
else:
base_path = Path(__file__).resolve().parent
except Exception:
@@ -707,7 +718,11 @@ def launch_app(
work_dir: Path = typer.Option(WORK_DIR, help="Working directory"),
nng: bool = typer.Option(True, help="Use nng"),
native_mode: bool = typer.Option(False, help="Use native mode"),
debug: bool = typer.Option(False, help="Debug mode")
debug: bool = typer.Option(False, help="Debug mode"),
ca_bundle: Optional[Path] = typer.Option(
None, help="Path to a CA bundle (PEM file) to verify HTTPS connections"
),
insecure: bool = typer.Option(False, help="Disable SSL verification (insecure)"),
):
global WORK_DIR, EXPORT_PATH, PROCESS_PATH, ANON_PATH, DEBUG
@@ -719,6 +734,52 @@ def launch_app(
logger.debug(f"Work dir: {WORK_DIR}")
# Configure SSL verification behaviour. VERIFY_SSL can be:
# - True (default): use system certs
# - False: disable verification (insecure)
# - path (str): path to CA bundle PEM file used by requests
global VERIFY_SSL
env_ca = (
os.environ.get("NICE_UPLOADER_CA_BUNDLE")
or os.environ.get("REQUESTS_CA_BUNDLE")
or os.environ.get("SSL_CERT_FILE")
)
if insecure:
VERIFY_SSL = False
logger.warning(
"SSL verification disabled (insecure). Only use for troubleshooting in trusted networks."
)
elif ca_bundle is not None:
VERIFY_SSL = str(ca_bundle)
logger.info(f"Using CA bundle from CLI: {VERIFY_SSL}")
elif env_ca:
VERIFY_SSL = env_ca
logger.info(f"Using CA bundle from environment: {VERIFY_SSL}")
else:
VERIFY_SSL = True
# If verification is disabled, suppress urllib3 insecure warnings to keep logs clean
if VERIFY_SSL is False:
try:
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
except Exception:
pass
# If a bundled cert.pem was included in the frozen app, prefer that
# when the user hasn't explicitly provided a CA bundle or disabled
# verification. This lets builders ship a corporate CA with the app.
try:
bundled = base_path / "cert.pem"
if bundled.exists() and VERIFY_SSL is True:
VERIFY_SSL = str(bundled)
logger.info(f"Using bundled CA bundle at {VERIFY_SSL}")
except Exception:
pass
# When running as a frozen executable, the native/webview backend
# (which depends on pythonnet) can fail to load inside the bundled
# runtime. Disable native mode automatically for frozen builds so the