Files
wehub-resource-sync 0418dc5cf9
CI / Python tests (3.10) (push) Has been cancelled
CI / Python tests (3.11) (push) Has been cancelled
CI / Python quality (push) Has been cancelled
CI / Frontend typecheck (push) Has been cancelled
Autopilot Pages / deploy (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:45:00 +08:00

125 lines
4.1 KiB
Python

"""Tests for ``openharness.auth.flows`` browser-launching behavior.
These cover the platform dispatch in ``DeviceCodeFlow._try_open_browser``,
particularly the Windows path: it must use ``os.startfile`` (ShellExecuteW)
rather than ``subprocess.Popen([...], shell=True)``, otherwise URLs containing
``&`` / ``|`` / ``^`` returned by a hostile or compromised device-flow
endpoint are interpreted as ``cmd.exe`` command separators.
"""
from __future__ import annotations
from typing import Any
import pytest
from openharness.auth.flows import DeviceCodeFlow
class _FakeProc:
returncode = 0
def wait(self, timeout: float | None = None) -> int:
return 0
@pytest.fixture
def popen_calls(monkeypatch: pytest.MonkeyPatch) -> list[tuple[tuple[Any, ...], dict[str, Any]]]:
"""Record every ``subprocess.Popen`` call without spawning real processes."""
calls: list[tuple[tuple[Any, ...], dict[str, Any]]] = []
def _capture(*args: Any, **kwargs: Any) -> _FakeProc:
calls.append((args, kwargs))
return _FakeProc()
monkeypatch.setattr("openharness.auth.flows.subprocess.Popen", _capture)
return calls
@pytest.fixture
def startfile_calls(monkeypatch: pytest.MonkeyPatch) -> list[str]:
"""Record every ``os.startfile`` call.
``os.startfile`` only exists on Windows, so ``raising=False`` is required
so the fixture also works on the Linux/macOS test runners in CI.
"""
calls: list[str] = []
monkeypatch.setattr(
"openharness.auth.flows.os.startfile",
lambda url: calls.append(url),
raising=False,
)
return calls
def test_open_browser_windows_uses_startfile_not_shell(
monkeypatch: pytest.MonkeyPatch,
popen_calls: list[tuple[tuple[Any, ...], dict[str, Any]]],
startfile_calls: list[str],
) -> None:
"""Regression: Windows path must not pass ``shell=True`` to subprocess.
A device-flow endpoint that returned ``https://x.com&calc.exe`` would
have its trailing token executed by ``cmd.exe`` under the previous
implementation. ``os.startfile`` calls ShellExecute directly, so the
full URL is handed to the registered URL handler verbatim.
"""
monkeypatch.setattr("openharness.auth.flows.platform.system", lambda: "Windows")
url = "https://github.com/login/device&calc.exe"
opened = DeviceCodeFlow._try_open_browser(url)
assert opened is True
assert startfile_calls == [url]
assert all(not kwargs.get("shell") for _, kwargs in popen_calls)
@pytest.mark.parametrize(
"url",
[
"javascript:alert(1)",
"file:///etc/passwd",
"ftp://example.com/payload",
"",
"calc.exe",
],
)
def test_open_browser_rejects_non_http_scheme(
monkeypatch: pytest.MonkeyPatch,
popen_calls: list[tuple[tuple[Any, ...], dict[str, Any]]],
startfile_calls: list[str],
url: str,
) -> None:
"""Non-http(s) URLs must not reach any platform browser-launcher."""
monkeypatch.setattr("openharness.auth.flows.platform.system", lambda: "Windows")
assert DeviceCodeFlow._try_open_browser(url) is False
assert startfile_calls == []
assert popen_calls == []
def test_open_browser_macos_uses_open_argv(
monkeypatch: pytest.MonkeyPatch,
popen_calls: list[tuple[tuple[Any, ...], dict[str, Any]]],
) -> None:
monkeypatch.setattr("openharness.auth.flows.platform.system", lambda: "Darwin")
assert DeviceCodeFlow._try_open_browser("https://example.com/login") is True
assert len(popen_calls) == 1
args, kwargs = popen_calls[0]
assert args[0] == ["open", "https://example.com/login"]
assert kwargs.get("shell") is not True
def test_open_browser_linux_uses_xdg_open_argv(
monkeypatch: pytest.MonkeyPatch,
popen_calls: list[tuple[tuple[Any, ...], dict[str, Any]]],
) -> None:
monkeypatch.setattr("openharness.auth.flows.platform.system", lambda: "Linux")
assert DeviceCodeFlow._try_open_browser("https://example.com/login") is True
assert len(popen_calls) == 1
args, kwargs = popen_calls[0]
assert args[0] == ["xdg-open", "https://example.com/login"]
assert kwargs.get("shell") is not True