fix: confirm exact canonical consumed act binding
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
This commit is contained in:
parent
8624fa20bb
commit
eece796b8b
3 changed files with 98 additions and 3 deletions
|
|
@ -127,3 +127,50 @@ def test_denied_read_never_represents_confirmation(engine, app, tmp_path):
|
|||
raise HTTPError(req.full_url, status, "refused", {}, None)
|
||||
with pytest.raises(ApprovalProtocolError, match="unauthorized"):
|
||||
confirmer(client(tmp_path, opener), obj)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("original,substitute", [(True, 1), (False, 0), (1, 1.0), (1, True)])
|
||||
@pytest.mark.parametrize("recompute_served_digest", [False, True])
|
||||
def test_confirmation_refuses_python_equal_json_distinct_target(
|
||||
engine, tmp_path, original, substitute, recompute_served_digest
|
||||
):
|
||||
expected = binding(target={"nested": [{"value": original}]})
|
||||
obj = engine.create(expected, validity(), pdp_digest=FREE, pdp_path=True,
|
||||
human_control=True)
|
||||
engine.add_entry(obj.id, "human:founder", principal_type="human")
|
||||
engine.consume(obj.id, FULL, decision_id="decision:original")
|
||||
result = engine.get(obj.id).as_dict()
|
||||
result["binding"]["target"] = {"nested": [{"value": substitute}]}
|
||||
if recompute_served_digest:
|
||||
from approval_engine.binding import binding_digest
|
||||
result["binding"]["digest"] = binding_digest(result["binding"])
|
||||
assert result["binding"]["target"] == expected["target"]
|
||||
with pytest.raises(ApprovalProtocolError, match="binding does not match"):
|
||||
client(tmp_path, lambda *_a, **_k: Response(result)).confirm_consumption(
|
||||
obj.id, FULL, "decision:original", expected_binding=expected,
|
||||
expected_pdp_digest=FREE)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("digest", [None, "sha256:" + "00" * 32, True])
|
||||
def test_confirmation_requires_served_native_digest_correspondence(engine, tmp_path, digest):
|
||||
obj = consumed(engine)
|
||||
result = engine.get(obj.id).as_dict()
|
||||
if digest is None:
|
||||
result["binding"].pop("digest")
|
||||
else:
|
||||
result["binding"]["digest"] = digest
|
||||
with pytest.raises(ApprovalProtocolError, match="binding does not match"):
|
||||
confirmer(client(tmp_path, lambda *_a, **_k: Response(result)), obj)
|
||||
|
||||
|
||||
def test_confirmation_accepts_nested_json_types_and_key_order(engine, tmp_path):
|
||||
expected = binding(target={"b": [True, False, 1, 1.0], "a": {"unicode": "ä"}})
|
||||
obj = engine.create(expected, validity(), pdp_digest=FREE, pdp_path=True,
|
||||
human_control=True)
|
||||
engine.add_entry(obj.id, "human:founder", principal_type="human")
|
||||
engine.consume(obj.id, FULL, decision_id="decision:original")
|
||||
result = engine.get(obj.id).as_dict()
|
||||
result["binding"]["target"] = dict(reversed(list(expected["target"].items())))
|
||||
assert client(tmp_path, lambda *_a, **_k: Response(result)).confirm_consumption(
|
||||
obj.id, FULL, "decision:original", expected_binding=expected,
|
||||
expected_pdp_digest=FREE)["approval_id"] == obj.id
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue