Files
rigdoctor/src/rigdoctor/core/elevation.py
T
jessey 54c0971ac3
release / release (push) Successful in 14s
refactor(gui): one-time launch elevation instead of "Run with admin"
Remove the per-page "Run with admin" buttons. At launch the GUI asks for the
password once (pkexec) and collects root-only data (SMART + dmidecode board/
BIOS/RAM) via the internal `collect-priv` command, caching it for the session;
Health and Inventory read that cache so they always show the full picture.

- core/elevation.py: pkexec collect + session cache
- cli: hidden `collect-priv` command (SMART + dmidecode -> JSON)
- health/inventory: use the elevation cache when present, else non-root
- main_window: collect at launch (config elevate_on_launch), then refresh
  Health/Inventory; falls back silently if cancelled/unavailable
- config: elevate_on_launch (default true)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:11:15 +02:00

52 lines
1.5 KiB
Python

"""Session privilege elevation.
At GUI launch the app asks for the password once (pkexec) and collects the data that
needs root — SMART health + dmidecode (board/BIOS/RAM) — caching it for the session so
Health and Inventory can always show the full picture without per-action prompts.
"""
from __future__ import annotations
import json
import os
import shutil
import subprocess
import sys
_privileged: dict | None = None
def privileged() -> dict | None:
"""Cached root-collected data ({"smart": [...], "dmidecode": {...}}), or None."""
return _privileged
def set_privileged(data: dict | None) -> None:
global _privileged
_privileged = data
def available() -> bool:
return shutil.which("pkexec") is not None and os.geteuid() != 0
def _cli() -> list[str]:
candidate = os.path.join(os.path.dirname(sys.executable), "rigdoctor")
return [candidate] if os.path.exists(candidate) else [sys.executable, "-m", "rigdoctor"]
def collect_via_pkexec(timeout: float = 120.0) -> dict | None:
"""Run one elevated collection (single password prompt). None if unavailable/cancelled."""
if not available():
return None
try:
proc = subprocess.run(
["pkexec", *_cli(), "collect-priv"],
capture_output=True, text=True, timeout=timeout,
)
if proc.returncode == 0 and proc.stdout.strip():
return json.loads(proc.stdout)
except (subprocess.SubprocessError, OSError, ValueError):
pass
return None