"""脱敏守卫:Secret、认证头、连接串、AccessKey 后四位(任务书 P1-B 安全 / P1-H)。""" from __future__ import annotations import json from clients.redaction import mask_access_key, redact_headers, redact_obj, redact_text SECRET = "S3CRET-VALUE-DO-NOT-LEAK" PASSWORD = "pw-123456" def test_mask_access_key_keeps_last_four(): assert mask_access_key("TESTKPARTNER") == "****TNER" assert mask_access_key("ab") == "****" assert mask_access_key("") == "" def test_redact_text_removes_known_secret(): text = f"signature computed with {SECRET} for tenant" out = redact_text(text, [SECRET]) assert SECRET not in out assert "***REDACTED***" in out def test_redact_text_masks_connection_string_password(): text = f"server=127.0.0.1;uid=root;password={PASSWORD};database=aidop_integration_sim" out = redact_text(text) assert PASSWORD not in out assert "aidop_integration_sim" in out def test_redact_text_masks_bearer_and_basic(): assert "abc.def.ghi" not in redact_text("Authorization: Bearer abc.def.ghi") assert "dXNlcjpwdw==" not in redact_text("Authorization: Basic dXNlcjpwdw==") def test_redact_headers_masks_sensitive_headers(): headers = { "X-Access-Key": "TESTKPARTNER", "X-Signature": "BASE64SIG==", "Authorization": f"Bearer {SECRET}", "X-Nonce": "n-1", } out = redact_headers(headers, [SECRET]) assert out["X-Access-Key"] == "****TNER" assert out["X-Signature"] == "***REDACTED***" assert out["Authorization"] == "***REDACTED***" assert out["X-Nonce"] == "n-1" def test_redact_obj_recurses_and_masks_by_key_name(): payload = { "request": {"headers": {"x-signature": "SIG", "x-access-key": "TESTKPARTNER"}}, "notes": [f"secret was {SECRET}", {"password": PASSWORD}], "httpStatus": 202, } out = redact_obj(payload, [SECRET]) dumped = json.dumps(out, ensure_ascii=False) assert SECRET not in dumped assert PASSWORD not in dumped assert out["request"]["headers"]["x-signature"] == "***REDACTED***" assert out["request"]["headers"]["x-access-key"] == "****TNER" assert out["httpStatus"] == 202