NODEDC_MISSION_CORE/src/k1link/macos_credentials.py

49 lines
1.7 KiB
Python

from __future__ import annotations
import platform
import shutil
import subprocess
class CredentialDialogError(RuntimeError):
"""Raised when the local macOS credential dialog cannot return a value."""
def _dialog_text(prompt: str, hidden: bool) -> str:
if platform.system() != "Darwin":
raise CredentialDialogError("Secure credential dialogs are supported only on macOS")
osascript = shutil.which("osascript")
if osascript is None:
raise CredentialDialogError("osascript is unavailable")
hidden_clause = " with hidden answer" if hidden else ""
script = (
f'text returned of (display dialog "{prompt}" default answer ""'
f'{hidden_clause} buttons {{"Отмена", "Продолжить"}} '
'default button "Продолжить" cancel button "Отмена")'
)
try:
result = subprocess.run(
[osascript, "-e", script],
check=False,
capture_output=True,
text=True,
timeout=300,
)
except (OSError, subprocess.SubprocessError) as exc:
raise CredentialDialogError("macOS credential dialog failed") from exc
if result.returncode != 0:
raise CredentialDialogError("Credential entry was cancelled")
value = result.stdout.rstrip("\r\n")
if not value:
raise CredentialDialogError("Credential value must not be empty")
return value
def prompt_wifi_credentials() -> tuple[str, str]:
"""Collect Wi-Fi credentials locally without placing them in command arguments."""
ssid = _dialog_text("Имя Wi-Fi сети, к которой подключён Mac", hidden=False)
password = _dialog_text("Пароль этой Wi-Fi сети", hidden=True)
return ssid, password