"""Real Access Engine oracle, source-only; no synthetic reimplementation.""" import copy import json import os from pathlib import Path import subprocess import pytest from secrets_engine.authorization import request_digest, approval_binding_digest from secrets_engine.errors import DecisionError from secrets_engine.execution_contract import catalog_target_digest from tests.test_action_authorization import _request @pytest.fixture(scope="session") def go_oracle(tmp_path_factory): access = Path(os.environ.get("ACCESS_ENGINE_SOURCE", "/home/worsch/access-engine")) directory = tmp_path_factory.mktemp("go-canonical") source = directory / "main.go" source.write_text('''package main import ("encoding/json"; "os"; "github.com/netkingdom/access-engine/pkg/api") func main() { var request api.CheckRequest if err := json.NewDecoder(os.Stdin).Decode(&request); err != nil { panic(err) } json.NewEncoder(os.Stdout).Encode([]string{api.RequestDigest(request), api.ApprovalBindingDigest(request)}) } ''') binary = directory / "oracle" subprocess.run(["go", "build", "-o", str(binary), str(source)], cwd=access, check=True, timeout=120) return binary def _oracle(binary, request): result = subprocess.run([str(binary)], input=json.dumps(request, ensure_ascii=False, allow_nan=False), text=True, capture_output=True, check=True, timeout=5) return json.loads(result.stdout) @pytest.mark.parametrize("purpose", ["café<&>", "漢字😀", "separator\u2028paragraph\u2029", 'quoted"\\\n\t', "\\u003c", "ascii"]) def test_real_go_unicode_and_approval_join(go_oracle, purpose): request = _request() request["context"]["purpose"] = purpose request["context"]["nested"] = {"ключ<&>": [purpose, None, True, False]} expected = _oracle(go_oracle, request) assert [request_digest(request), approval_binding_digest(request)] == expected before = request_digest(request) request["context"]["approval"] = {"id": "approval:é<&>", "binding": {"pdp_digest": before}} expected = _oracle(go_oracle, request) assert [request_digest(request), approval_binding_digest(request)] == expected assert expected[1] == before and expected[0] != before @pytest.mark.parametrize("number", [0, 1, -1, 1.0, 0.0, -0.0, 1.5, 1e-7, 1e-6, 1.2e-6, 1e20, 1e21, 1e23, 5e-324, 1.7976931348623157e308, 1000000000000000, 2**53-1, -(2**53-1)]) def test_numeric_admitted_profile(go_oracle, number): request = _request() request["context"]["number"] = {"nested": [number]} assert request_digest(request) == _oracle(go_oracle, request)[0] @pytest.mark.parametrize("number", [float("nan"), float("inf"), -float("inf"), 2**53, 2**53+1, 10**100]) def test_numeric_outside_profile_fails_closed(number): request = _request() request["context"]["number"] = number with pytest.raises(DecisionError): request_digest(request) with pytest.raises(DecisionError): approval_binding_digest(request) def test_empty_optional_maps_and_approval_only(go_oracle): request = _request() request["subject"]["attributes"] = {} request["resource"]["attributes"] = {} request["context"] = {"approval": {"id": "test"}} assert [request_digest(request), approval_binding_digest(request)] == _oracle(go_oracle, request) request["purpose"] = "readback" assert [request_digest(request), approval_binding_digest(request)] == _oracle(go_oracle, request) def test_unicode_fingerprint_is_distinct_and_unchanged(go_oracle): request = _request() target = request["context"]["catalog_target"] target["org"] = "café<&>" import hashlib expected = "sha256:" + hashlib.sha256(json.dumps(target, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode()).hexdigest() assert catalog_target_digest(target) == expected assert request_digest(request) == _oracle(go_oracle, request)[0] def test_invalid_unicode_fails_closed(): request = _request() request["context"]["purpose"] = "bad\ud800" with pytest.raises(DecisionError): request_digest(request) def test_binary64_samples_against_real_go(go_oracle): import random import struct import math randomizer = random.Random(20261011) for _ in range(256): number = struct.unpack(">d", randomizer.getrandbits(64).to_bytes(8, "big"))[0] if not math.isfinite(number): continue request = _request() request["context"]["number"] = number assert request_digest(request) == _oracle(go_oracle, request)[0], repr(number)