Files
security-alert-center/backend/tests/test_winrm_connect.py
T

112 lines
3.9 KiB
Python

"""WinRM bundle delivery and CLIXML error parsing tests."""
from pathlib import Path
from unittest.mock import patch
from app.services.rdp_bundle_delivery import build_rdp_bundle_zip, get_rdp_bundle_zip, register_rdp_bundle_zip
from app.services.winrm_connect import (
RDP_BUNDLE_REQUIRED,
RDP_REMOTE_STAGING,
WinRmCmdResult,
_clixml_to_plain,
_custom_deploy_body,
_deploy_from_staging_body,
_download_bundle_body,
_prepare_staging_body,
_winrm_failure_detail,
run_winrm_rdp_monitor_update,
)
def test_prepare_staging_recreates_remote_dir():
script = _prepare_staging_body(RDP_REMOTE_STAGING)
assert "Remove-Item" in script
assert "_sac_staging" in script
def test_download_bundle_uses_invoke_webrequest():
script = _download_bundle_body(
RDP_REMOTE_STAGING,
"https://sac.example/api/v1/agent/rdp-bundle/token",
)
assert "Invoke-WebRequest" in script
assert "Expand-Archive" in script
assert "WriteAllBytes" not in script
def test_deploy_from_staging_runs_local_bundle():
script = _deploy_from_staging_body(RDP_REMOTE_STAGING)
assert "-SourceShareRoot" in script
assert "Deploy-LoginMonitor.ps1" in script
def test_custom_deploy_script_escapes_single_quotes():
script = _custom_deploy_body(r"C:\Users\O'Brien\Deploy-LoginMonitor.ps1")
assert "O''Brien" in script
def test_rdp_bundle_zip_roundtrip(tmp_path: Path):
repo = tmp_path / "repo"
repo.mkdir()
for name in RDP_BUNDLE_REQUIRED:
(repo / name).write_text(name, encoding="utf-8")
zip_bytes = build_rdp_bundle_zip(repo, tuple(RDP_BUNDLE_REQUIRED))
token = register_rdp_bundle_zip(zip_bytes)
assert get_rdp_bundle_zip(token) == zip_bytes
def test_run_winrm_rdp_monitor_update_downloads_bundle_from_sac(tmp_path: Path):
repo = tmp_path / "repo"
repo.mkdir()
for name in RDP_BUNDLE_REQUIRED:
(repo / name).write_text(f"content-{name}", encoding="utf-8")
calls: list[str] = []
def fake_run_ps(*, script: str, **kwargs) -> WinRmCmdResult:
calls.append(script)
if "Remove-Item" in script:
return WinRmCmdResult(ok=True, message="staging ok", target="pc", stdout="Staging ready")
if "Invoke-WebRequest" in script:
return WinRmCmdResult(ok=True, message="download ok", target="pc", stdout="Bundle extracted")
if "& $deploy" in script:
return WinRmCmdResult(
ok=True,
message="WinRM OK (pc), exit 0",
target="pc",
stdout="deployed 1.2.3",
exit_code=0,
)
return WinRmCmdResult(ok=True, message="ok", target="pc", exit_code=0)
with (
patch("app.services.winrm_connect._fetch_rdp_bundle_dir", return_value=repo),
patch("app.services.winrm_connect._bundle_download_url", return_value="https://sac.test/bundle.zip"),
patch("app.services.winrm_connect.run_winrm_ps", side_effect=fake_run_ps),
):
result = run_winrm_rdp_monitor_update(
target="pc",
user="B26\\admin",
password="pw",
repo_url="https://git.example.com/RDP-login-monitor.git",
)
assert result.ok is True
assert "SAC served bundle" in result.stdout
assert any("Invoke-WebRequest" in call for call in calls)
assert not any("FromBase64String" in call for call in calls)
def test_winrm_failure_detail_never_returns_raw_clixml_progress():
clixml = (
"#< CLIXML <Objs Version=\"1.1.0.1\">"
'<Obj S="progress"><MS><PR N="Record"><AV>Preparing modules for first use.</AV></PR></MS></Obj>'
)
detail = _winrm_failure_detail("", clixml, 1)
assert "#< CLIXML" not in detail
def test_clixml_to_plain_strips_progress_only_blob():
clixml = "#< CLIXML <Objs><Obj S=\"progress\"><AV>Preparing modules for first use.</AV></Obj></Objs>"
assert _clixml_to_plain(clixml) == ""