include cert.pem for SSL verification in frozen builds and update build process to handle CA bundles
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user