Publish curated Unraid-AppOps-Gateway source from ad0a390e431166c3198a2ac3bec010c2b44f2dea
This commit is contained in:
1 parent
29c1e3d5a1
commit
98d31477f9
35 files changed
+7264
-185
No files matched your search
@@ -2226,6 +2226,96 @@ def test_managed_repopulse_render_accepts_only_its_read_only_source_mount(
|
||||
deploy_module.validate_managed_v1_runtime(project, "a" * 40, "jens/repopulse")
|
||||
|
||||
|
||||
def test_managed_appdata_roots_are_fixed_and_bound_to_each_registration(
|
||||
deploy_module, monkeypatch, tmp_path
|
||||
):
|
||||
legacy_root = tmp_path / "legacy-appdata"
|
||||
managed_root = tmp_path / "managed-volume" / "_data"
|
||||
monkeypatch.setattr(deploy_module, "LEGACY_MANAGED_APPCONFIG_ROOT", legacy_root)
|
||||
monkeypatch.setattr(deploy_module, "MANAGED_APPCONFIG_ROOT", legacy_root)
|
||||
monkeypatch.setattr(deploy_module, "MANAGED_APPCONFIG_VOLUME_ROOT", managed_root)
|
||||
monkeypatch.setattr(deploy_module, "managed_appdata_volume_initialized", lambda: False)
|
||||
|
||||
assert deploy_module._registered_managed_appdata_root({}) == legacy_root
|
||||
assert deploy_module._registered_managed_appdata_root(
|
||||
{"managed_appdata_root": legacy_root.as_posix()}
|
||||
) == legacy_root
|
||||
with pytest.raises(deploy_module.DeployError, match="not initialized and available"):
|
||||
deploy_module._registered_managed_appdata_root(
|
||||
{"managed_appdata_root": managed_root.as_posix()}
|
||||
)
|
||||
with pytest.raises(deploy_module.DeployError, match="fixed registered roots"):
|
||||
deploy_module._registered_managed_appdata_root(
|
||||
{"managed_appdata_root": (tmp_path / "arbitrary").as_posix()}
|
||||
)
|
||||
|
||||
monkeypatch.setattr(deploy_module, "managed_appdata_volume_initialized", lambda: True)
|
||||
assert deploy_module._registered_managed_appdata_root(
|
||||
{"managed_appdata_root": managed_root.as_posix()}
|
||||
) == managed_root
|
||||
|
||||
for root, host in ((legacy_root, "legacy.example"), (managed_root, "managed.example")):
|
||||
env_path = root / "demo" / "deploy.env"
|
||||
env_path.parent.mkdir(parents=True)
|
||||
env_path.write_text(f"APPOPS_PUBLIC_URL=https://{host}\n", encoding="utf-8")
|
||||
if os.name != "nt":
|
||||
env_path.chmod(0o600)
|
||||
|
||||
project = {
|
||||
"appops_managed_target": True,
|
||||
"managed_plan_version": "itworx.deployment/v1",
|
||||
"managed_profile": "internal-webapp",
|
||||
"managed_application_id": "demo",
|
||||
"managed_runtime_environment_keys": ["APPOPS_PUBLIC_URL"],
|
||||
"env_source": (legacy_root / "demo" / "deploy.env").as_posix(),
|
||||
}
|
||||
assert deploy_module.managed_runtime_environment(project) == {
|
||||
"APPOPS_PUBLIC_URL": "https://legacy.example"
|
||||
}
|
||||
project["managed_appdata_root"] = managed_root.as_posix()
|
||||
project["env_source"] = (managed_root / "demo" / "deploy.env").as_posix()
|
||||
assert deploy_module.managed_runtime_environment(project) == {
|
||||
"APPOPS_PUBLIC_URL": "https://managed.example"
|
||||
}
|
||||
|
||||
|
||||
def test_managed_project_path_is_derived_from_its_stored_appdata_root(
|
||||
deploy_module, monkeypatch
|
||||
):
|
||||
monkeypatch.setattr(deploy_module, "managed_appdata_volume_initialized", lambda: True)
|
||||
monkeypatch.setattr(deploy_module, "git_path_exists", lambda *_args: True)
|
||||
project = {
|
||||
"containers": ["demo"],
|
||||
"source_dir": (deploy_module.EXACT_SOURCE_ROOT / "demo").as_posix(),
|
||||
"exact_source": True,
|
||||
"compose_dir": ".",
|
||||
"compose_files": ["compose.yml"],
|
||||
"compose_project": "demo",
|
||||
"managed_plan_version": "itworx.deployment/v1",
|
||||
"managed_application_id": "demo",
|
||||
"managed_appdata_path": "/srv/example/appdata/demo",
|
||||
"managed_image_repository": "demo",
|
||||
"managed_image_tag": "production",
|
||||
"managed_proxy_network": "itworx-proxy",
|
||||
"managed_internal_port": 8000,
|
||||
"appops_deployment_secret_file": "jens__demo",
|
||||
}
|
||||
|
||||
deploy_module.validate_project_config(Path("repo.git"), project, "a" * 40)
|
||||
managed = {
|
||||
**project,
|
||||
"managed_appdata_root": deploy_module.MANAGED_APPCONFIG_VOLUME_ROOT.as_posix(),
|
||||
"managed_appdata_path": (
|
||||
deploy_module.MANAGED_APPCONFIG_VOLUME_ROOT / "demo"
|
||||
).as_posix(),
|
||||
}
|
||||
deploy_module.validate_project_config(Path("repo.git"), managed, "a" * 40)
|
||||
|
||||
remapped = {**managed, "managed_appdata_path": "/srv/example/appdata/demo"}
|
||||
with pytest.raises(deploy_module.DeployError, match="not derived"):
|
||||
deploy_module.validate_project_config(Path("repo.git"), remapped, "a" * 40)
|
||||
|
||||
|
||||
def test_repopulse_project_registry_requires_its_fixed_build_identity(
|
||||
deploy_module, monkeypatch
|
||||
):
|
||||
@@ -4582,6 +4672,25 @@ def _appops_plan(revision: str) -> dict[str, object]:
|
||||
}
|
||||
|
||||
|
||||
def test_appops_plan_root_must_match_the_registered_target_root(status_module):
|
||||
project = _appops_project()
|
||||
plan = _appops_plan("a" * 40)
|
||||
assert status_module._appops_plan({"jens/repo-a": project}, plan) == (
|
||||
"jens/repo-a", "a" * 40, project,
|
||||
)
|
||||
|
||||
project["managed_appdata_root"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
|
||||
project["managed_appdata_path"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data/repo-a"
|
||||
alternate_plan = {**plan, "trusted_appdata_root": "/var/lib/docker/volumes/itworx-managed-appdata/_data"}
|
||||
assert status_module._appops_plan({"jens/repo-a": project}, alternate_plan) == (
|
||||
"jens/repo-a", "a" * 40, project,
|
||||
)
|
||||
assert status_module._appops_plan({"jens/repo-a": project}, plan) is None
|
||||
|
||||
drifted = {**project, "managed_appdata_path": "/srv/example/appdata/repo-a"}
|
||||
assert status_module._appops_plan({"jens/repo-a": drifted}, alternate_plan) is None
|
||||
|
||||
|
||||
def _write_appops_secret(root: Path, name: str, value: bytes) -> None:
|
||||
root.mkdir(mode=0o700)
|
||||
root.chmod(0o700)
|
||||
@@ -5838,6 +5947,7 @@ def _controller_enrollment_payload(*, credential: bool = False) -> dict[str, obj
|
||||
"profile": "internal-webapp-oidc",
|
||||
"container_name": "wsbc-portal",
|
||||
"compose_file": ".itworx/deployment.yml",
|
||||
"trusted_appdata_root": "/srv/example/appdata",
|
||||
"appdata_path": "/srv/example/appdata/wsbc-portal",
|
||||
"data_path": "/srv/example/appdata/wsbc-portal/data",
|
||||
"runtime_uid": 1654,
|
||||
@@ -5871,6 +5981,7 @@ def _repopulse_controller_enrollment_payload(*, credential: bool = False) -> dic
|
||||
"profile": "repopulse-authenticated",
|
||||
"container_name": "repopulse",
|
||||
"compose_file": ".itworx/deployment.yml",
|
||||
"trusted_appdata_root": "/srv/example/appdata",
|
||||
"appdata_path": "/srv/example/appdata/repopulse",
|
||||
"data_path": "/srv/example/appdata/repopulse/data",
|
||||
"runtime_uid": 10001,
|
||||
@@ -5929,8 +6040,10 @@ def test_controller_repopulse_runtime_seal_fixes_gitea_url_and_hides_values(stat
|
||||
env_path = app_root / "deploy.managed.env"
|
||||
env_path.write_text("", encoding="utf-8")
|
||||
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", appdata_root)
|
||||
monkeypatch.setattr(status_module, "LEGACY_APPDATA_ROOT", appdata_root)
|
||||
monkeypatch.setattr(status_module, "EXACT_SOURCE_ROOT", tmp_path / "sources")
|
||||
payload = _repopulse_controller_enrollment_payload(credential=True)
|
||||
payload["trusted_appdata_root"] = appdata_root.as_posix()
|
||||
payload["appdata_path"] = app_root.as_posix()
|
||||
payload["data_path"] = (app_root / "data").as_posix()
|
||||
enrollment = status_module._controller_enrollment(payload, require_credential=True)
|
||||
@@ -6106,6 +6219,76 @@ def test_controller_enrollment_contract_rejects_arbitrary_compose_and_paths(stat
|
||||
assert status_module._controller_enrollment(unsafe, require_credential=True) is None
|
||||
|
||||
|
||||
def test_controller_enrollment_derives_paths_from_the_selected_fixed_root(status_module, monkeypatch):
|
||||
managed_root = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
|
||||
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", Path(managed_root))
|
||||
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda root: root.as_posix() == managed_root)
|
||||
alternate = _controller_enrollment_payload()
|
||||
alternate["trusted_appdata_root"] = managed_root
|
||||
alternate["appdata_path"] = managed_root + "/wsbc-portal"
|
||||
alternate["data_path"] = managed_root + "/wsbc-portal/data"
|
||||
|
||||
enrollment = status_module._controller_enrollment(alternate, require_credential=False)
|
||||
assert enrollment is not None
|
||||
project = status_module._enrollment_project(enrollment)
|
||||
assert project["managed_appdata_root"] == managed_root
|
||||
assert project["managed_appdata_path"] == managed_root + "/wsbc-portal"
|
||||
|
||||
unsafe_path = {**alternate, "data_path": "/srv/example/appdata/wsbc-portal/data"}
|
||||
assert status_module._controller_enrollment(unsafe_path, require_credential=False) is None
|
||||
|
||||
unsupported_root = {**alternate, "trusted_appdata_root": "/srv/example/other"}
|
||||
assert status_module._controller_enrollment(unsupported_root, require_credential=False) is None
|
||||
|
||||
|
||||
def test_controller_accepts_legacy_requests_after_managed_marker_is_initialized(status_module, monkeypatch):
|
||||
managed_root = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
|
||||
monkeypatch.setattr(status_module, "_refresh_appdata_root_selection", lambda: Path(managed_root))
|
||||
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda root: root.as_posix() == managed_root)
|
||||
legacy = _controller_enrollment_payload()
|
||||
assert legacy["trusted_appdata_root"] == "/srv/example/appdata"
|
||||
|
||||
enrollment = status_module._controller_enrollment(legacy, require_credential=False)
|
||||
assert enrollment is not None
|
||||
assert enrollment["trusted_appdata_root"] == "/srv/example/appdata"
|
||||
assert "managed_appdata_root" not in status_module._enrollment_project(enrollment)
|
||||
|
||||
|
||||
def test_controller_accepts_legacy_v1_payload_without_root_field(status_module):
|
||||
legacy = _controller_enrollment_payload()
|
||||
legacy.pop("trusted_appdata_root")
|
||||
|
||||
enrollment = status_module._controller_enrollment(legacy, require_credential=False)
|
||||
|
||||
assert enrollment is not None
|
||||
assert enrollment["trusted_appdata_root"] == "/srv/example/appdata"
|
||||
assert "managed_appdata_root" not in status_module._enrollment_project(enrollment)
|
||||
|
||||
|
||||
def test_repopulse_enrollment_remains_bound_to_legacy_appdata_root(status_module, monkeypatch):
|
||||
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", Path("/var/lib/docker/volumes/itworx-managed-appdata/_data"))
|
||||
payload = _repopulse_controller_enrollment_payload()
|
||||
payload["trusted_appdata_root"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
|
||||
payload["appdata_path"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data/repopulse"
|
||||
payload["data_path"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data/repopulse/data"
|
||||
|
||||
assert status_module._controller_enrollment(payload, require_credential=False) is None
|
||||
|
||||
|
||||
def test_fixed_repopulse_profile_stays_legacy_with_managed_marker(status_module, monkeypatch):
|
||||
managed_root = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
|
||||
monkeypatch.setattr(status_module, "_refresh_appdata_root_selection", lambda: Path(managed_root))
|
||||
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda root: root.as_posix() == managed_root)
|
||||
|
||||
enrollment = status_module._controller_enrollment(
|
||||
_repopulse_controller_enrollment_payload(),
|
||||
require_credential=False,
|
||||
)
|
||||
|
||||
assert enrollment is not None
|
||||
assert enrollment["trusted_appdata_root"] == "/srv/example/appdata"
|
||||
|
||||
|
||||
def test_controller_runtime_seal_accepts_only_profile_owned_keys(status_module, tmp_path, monkeypatch):
|
||||
appdata_root = tmp_path / "appdata"
|
||||
app_root = appdata_root / "wsbc-portal"
|
||||
@@ -6113,8 +6296,10 @@ def test_controller_runtime_seal_accepts_only_profile_owned_keys(status_module,
|
||||
env_path = app_root / "deploy.env"
|
||||
env_path.write_text("", encoding="utf-8")
|
||||
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", appdata_root)
|
||||
monkeypatch.setattr(status_module, "LEGACY_APPDATA_ROOT", appdata_root)
|
||||
monkeypatch.setattr(status_module, "EXACT_SOURCE_ROOT", tmp_path / "sources")
|
||||
payload = _controller_enrollment_payload(credential=True)
|
||||
payload["trusted_appdata_root"] = appdata_root.as_posix()
|
||||
payload["appdata_path"] = app_root.as_posix()
|
||||
payload["data_path"] = (app_root / "data").as_posix()
|
||||
enrollment = status_module._controller_enrollment(payload, require_credential=True)
|
||||
@@ -6154,6 +6339,7 @@ def test_controller_enrollment_replay_requires_the_existing_target_credential(st
|
||||
projects_path.write_text(json.dumps({"jens/windows-support-bundle-collector": project}), encoding="utf-8")
|
||||
monkeypatch.setattr(status_module, "PROJECTS_PATH", projects_path)
|
||||
monkeypatch.setattr(status_module, "APPOPS_DEPLOYMENT_SECRET_ROOT", secrets_root)
|
||||
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda _root: True)
|
||||
enrollment["target_credential"] = "y" * 64
|
||||
|
||||
status, _evidence = status_module._enroll_controller_target(enrollment)
|
||||
@@ -7316,3 +7502,249 @@ def test_workmesh_backup_receipt_requires_bound_manifest_and_verified_restore_by
|
||||
assert status_module._verified_workmesh_backup_receipt(
|
||||
request_id, candidate, preflight, inputs
|
||||
) is None
|
||||
|
||||
|
||||
def _managed_storage_http_request(
|
||||
status_module,
|
||||
server,
|
||||
*,
|
||||
body: bytes,
|
||||
nonce: str,
|
||||
secret: bytes | None,
|
||||
signature: str | None = None,
|
||||
signed_path: str | None = None,
|
||||
):
|
||||
path = status_module.MANAGED_APPDATA_INITIALIZE_PATH
|
||||
timestamp = str(int(status_module.time.time()))
|
||||
headers = {"Content-Type": "application/json", "Content-Length": str(len(body))}
|
||||
if nonce:
|
||||
headers["X-ITWorx-Deployment-Nonce"] = nonce
|
||||
if timestamp:
|
||||
headers["X-ITWorx-Deployment-Timestamp"] = timestamp
|
||||
if signature is None and secret is not None:
|
||||
signature = status_module._request_signature(
|
||||
secret,
|
||||
method="POST",
|
||||
path=signed_path or path,
|
||||
timestamp=timestamp,
|
||||
nonce=nonce,
|
||||
raw_body=body,
|
||||
)
|
||||
if signature is not None:
|
||||
headers["X-ITWorx-Deployment-Signature"] = signature
|
||||
|
||||
connection = http.client.HTTPConnection(*server.server_address, timeout=2)
|
||||
connection.request("POST", path, body=body, headers=headers)
|
||||
response = connection.getresponse()
|
||||
status = response.status
|
||||
payload = json.loads(response.read())
|
||||
connection.close()
|
||||
return status, payload, headers
|
||||
|
||||
|
||||
def test_managed_appdata_initializer_http_requires_exact_signed_one_time_request(
|
||||
status_module, tmp_path, monkeypatch
|
||||
):
|
||||
secret = b"managed-storage-bootstrap-" + b"x" * 48
|
||||
secret_path = tmp_path / "bootstrap"
|
||||
secret_path.write_bytes(secret)
|
||||
secret_path.chmod(0o600)
|
||||
nonce_root = tmp_path / "nonces"
|
||||
monkeypatch.setattr(status_module, "APPOPS_ENROLLMENT_BOOTSTRAP_SECRET_FILE", secret_path)
|
||||
monkeypatch.setattr(status_module, "APPOPS_NONCE_ROOT", nonce_root)
|
||||
monkeypatch.setattr(
|
||||
status_module.Handler,
|
||||
"_managed_storage_initialization_prerequisites",
|
||||
lambda _handler: True,
|
||||
)
|
||||
initialized = []
|
||||
monkeypatch.setattr(
|
||||
status_module,
|
||||
"ensure_managed_appdata_root",
|
||||
lambda: initialized.append(True) or "initialized",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
status_module,
|
||||
"_refresh_appdata_root_selection",
|
||||
lambda: status_module.MANAGED_APPDATA_ROOT,
|
||||
)
|
||||
server = status_module.BoundedThreadingHTTPServer(
|
||||
("127.0.0.1", 0), status_module.Handler
|
||||
)
|
||||
serving = threading.Thread(target=server.serve_forever, daemon=True)
|
||||
serving.start()
|
||||
body = json.dumps(
|
||||
{
|
||||
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
|
||||
"target": status_module.MANAGED_APPDATA_INITIALIZE_TARGET,
|
||||
},
|
||||
separators=(",", ":"),
|
||||
).encode("utf-8")
|
||||
try:
|
||||
success_status, success_payload, success_headers = _managed_storage_http_request(
|
||||
status_module,
|
||||
server,
|
||||
body=body,
|
||||
nonce="a" * 32,
|
||||
secret=secret,
|
||||
)
|
||||
assert success_status == 200
|
||||
assert success_payload == {
|
||||
"status": "initialized",
|
||||
"trustedAppdataRoot": status_module.MANAGED_APPDATA_ROOT.as_posix(),
|
||||
"backupLocation": "dockerRootDir",
|
||||
}
|
||||
assert initialized == [True]
|
||||
assert secret.decode("ascii") not in json.dumps(success_payload)
|
||||
|
||||
replay = http.client.HTTPConnection(*server.server_address, timeout=2)
|
||||
replay.request(
|
||||
"POST",
|
||||
status_module.MANAGED_APPDATA_INITIALIZE_PATH,
|
||||
body=body,
|
||||
headers=success_headers,
|
||||
)
|
||||
replay_response = replay.getresponse()
|
||||
replay_payload = json.loads(replay_response.read())
|
||||
replay.close()
|
||||
assert replay_response.status == 403
|
||||
assert replay_payload == {"status": "authentication_rejected"}
|
||||
assert initialized == [True]
|
||||
|
||||
invalid_requests = [
|
||||
_managed_storage_http_request(
|
||||
status_module,
|
||||
server,
|
||||
body=body,
|
||||
nonce="b" * 32,
|
||||
secret=secret,
|
||||
signature="0" * 64,
|
||||
),
|
||||
_managed_storage_http_request(
|
||||
status_module,
|
||||
server,
|
||||
body=body,
|
||||
nonce="c" * 32,
|
||||
secret=secret,
|
||||
signed_path="/v1/appops/enrollments/capabilities",
|
||||
),
|
||||
_managed_storage_http_request(
|
||||
status_module,
|
||||
server,
|
||||
body=body,
|
||||
nonce="d" * 32,
|
||||
secret=None,
|
||||
),
|
||||
]
|
||||
assert [status for status, _payload, _headers in invalid_requests] == [403, 403, 403]
|
||||
assert initialized == [True]
|
||||
|
||||
for index, payload in enumerate(
|
||||
[
|
||||
{
|
||||
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
|
||||
"target": "tower/other-controller",
|
||||
},
|
||||
{
|
||||
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
|
||||
"target": status_module.MANAGED_APPDATA_INITIALIZE_TARGET,
|
||||
"path": "C:/private/sentinel",
|
||||
},
|
||||
],
|
||||
start=1,
|
||||
):
|
||||
raw_body = json.dumps(payload, separators=(",", ":")).encode("utf-8")
|
||||
rejected_status, rejected_payload, _headers = _managed_storage_http_request(
|
||||
status_module,
|
||||
server,
|
||||
body=raw_body,
|
||||
nonce=f"{index:032x}",
|
||||
secret=secret,
|
||||
)
|
||||
assert rejected_status == 400
|
||||
assert rejected_payload == {"status": "invalid_managed_storage_request"}
|
||||
assert "C:/private/sentinel" not in json.dumps(rejected_payload)
|
||||
oversized_status, oversized_payload, _headers = _managed_storage_http_request(
|
||||
status_module,
|
||||
server,
|
||||
body=b"x" * 1025,
|
||||
nonce="e" * 32,
|
||||
secret=None,
|
||||
)
|
||||
assert oversized_status == 413
|
||||
assert oversized_payload == {"status": "invalid_body_size"}
|
||||
assert initialized == [True]
|
||||
finally:
|
||||
server.shutdown()
|
||||
server.server_close()
|
||||
serving.join(timeout=2)
|
||||
|
||||
|
||||
def test_managed_appdata_initializer_http_prerequisite_and_refusal_are_sanitized(
|
||||
status_module, tmp_path, monkeypatch
|
||||
):
|
||||
secret = b"managed-storage-bootstrap-" + b"y" * 48
|
||||
secret_path = tmp_path / "bootstrap"
|
||||
secret_path.write_bytes(secret)
|
||||
secret_path.chmod(0o600)
|
||||
monkeypatch.setattr(status_module, "APPOPS_ENROLLMENT_BOOTSTRAP_SECRET_FILE", secret_path)
|
||||
monkeypatch.setattr(status_module, "APPOPS_NONCE_ROOT", tmp_path / "nonces")
|
||||
prerequisites = {"ready": False}
|
||||
monkeypatch.setattr(
|
||||
status_module.Handler,
|
||||
"_managed_storage_initialization_prerequisites",
|
||||
lambda _handler: prerequisites["ready"],
|
||||
)
|
||||
calls = []
|
||||
monkeypatch.setattr(
|
||||
status_module,
|
||||
"ensure_managed_appdata_root",
|
||||
lambda: calls.append(True) or "initialized",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
status_module,
|
||||
"_refresh_appdata_root_selection",
|
||||
lambda: status_module.MANAGED_APPDATA_ROOT,
|
||||
)
|
||||
server = status_module.BoundedThreadingHTTPServer(
|
||||
("127.0.0.1", 0), status_module.Handler
|
||||
)
|
||||
serving = threading.Thread(target=server.serve_forever, daemon=True)
|
||||
serving.start()
|
||||
body = json.dumps(
|
||||
{
|
||||
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
|
||||
"target": status_module.MANAGED_APPDATA_INITIALIZE_TARGET,
|
||||
},
|
||||
separators=(",", ":"),
|
||||
).encode("utf-8")
|
||||
try:
|
||||
status, payload, _headers = _managed_storage_http_request(
|
||||
status_module, server, body=body, nonce="f" * 32, secret=secret
|
||||
)
|
||||
assert status == 503
|
||||
assert payload == {"status": "managed_storage_prerequisite_unavailable"}
|
||||
assert calls == []
|
||||
|
||||
prerequisites["ready"] = True
|
||||
|
||||
def refuse_with_sensitive_diagnostic():
|
||||
raise status_module.UnsafeManagedAppdataRoot(
|
||||
"secret/path sentinel C:/private/appdata"
|
||||
)
|
||||
|
||||
monkeypatch.setattr(
|
||||
status_module, "ensure_managed_appdata_root", refuse_with_sensitive_diagnostic
|
||||
)
|
||||
status, payload, _headers = _managed_storage_http_request(
|
||||
status_module, server, body=body, nonce="1" * 32, secret=secret
|
||||
)
|
||||
assert status == 409
|
||||
assert payload == {"status": "managed_storage_initialization_refused"}
|
||||
assert "secret/path sentinel" not in json.dumps(payload)
|
||||
assert "C:/private/appdata" not in json.dumps(payload)
|
||||
assert secret.decode("ascii") not in json.dumps(payload)
|
||||
finally:
|
||||
server.shutdown()
|
||||
server.server_close()
|
||||
serving.join(timeout=2)
|
||||
Reference in new issue
Block a user