Skip to content

Commit 04a951a

Browse files
GOV-667: Allow updates to proceed
1 parent ed258d4 commit 04a951a

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

pyatlan/client/common/transport.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,10 @@ def create_mock_response(
6363
def parse_auth_policy_entity(request: httpx.Request) -> Optional[tuple[str, str, str]]:
6464
"""
6565
Parse the request body and return (policy_name, persona_guid, temp_guid)
66-
if the request is a bulk POST containing an AuthPolicy, else None.
66+
if the request is a bulk POST containing a NEW AuthPolicy creation, else None.
67+
68+
Only matches policy CREATES (temp GUIDs starting with "-"), not UPDATES
69+
(real GUIDs), to prevent suppressing legitimate policy modifications.
6770
"""
6871
if request.method != "POST" or BULK_UPDATE.path not in str(request.url):
6972
return None
@@ -81,13 +84,24 @@ def parse_auth_policy_entity(request: httpx.Request) -> Optional[tuple[str, str,
8184
for entity in body.get("entities", []):
8285
if entity.get("typeName") != "AuthPolicy":
8386
continue
87+
88+
entity_guid = entity.get("guid", "-1")
89+
# Only match policy CREATES (temp GUIDs like "-1", "-2", etc.)
90+
# Skip policy UPDATES (real GUIDs) to avoid suppressing modifications
91+
if not isinstance(entity_guid, str) or not entity_guid.startswith("-"):
92+
logger.debug(
93+
"parse_auth_policy_entity: skipping duplicate check for policy with GUID %s (likely an update or invalid type)",
94+
entity_guid,
95+
)
96+
continue
97+
8498
policy_name = entity.get("attributes", {}).get("name")
8599
access_control = entity.get("attributes", {}).get("accessControl")
86100
persona_guid = (
87101
access_control.get("guid") if isinstance(access_control, dict) else None
88102
)
89103
if policy_name and persona_guid:
90-
return policy_name, persona_guid, entity.get("guid", "-1")
104+
return policy_name, persona_guid, entity_guid
91105
return None
92106

93107

tests/unit/test_transport.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,49 @@ def test_returns_none_for_invalid_utf8(self):
118118
req = httpx.Request("POST", BULK_URL, content=b"\xff\xfe")
119119
assert parse_auth_policy_entity(req) is None
120120

121+
def test_returns_none_for_policy_update_with_real_guid(self):
122+
"""Policy updates (real GUIDs) should not be matched to prevent suppressing updates."""
123+
req = _make_bulk_request(temp_guid=EXISTING_GUID)
124+
assert parse_auth_policy_entity(req) is None
125+
126+
def test_returns_none_for_none_guid(self):
127+
"""None GUID should not crash and should be skipped."""
128+
import json
129+
130+
body = {
131+
"entities": [
132+
{
133+
"typeName": "AuthPolicy",
134+
"guid": None,
135+
"attributes": {
136+
"name": POLICY_NAME,
137+
"accessControl": {"guid": PERSONA_GUID},
138+
},
139+
}
140+
]
141+
}
142+
req = httpx.Request("POST", BULK_URL, content=json.dumps(body).encode())
143+
assert parse_auth_policy_entity(req) is None
144+
145+
def test_returns_none_for_integer_guid(self):
146+
"""Integer GUID should not crash and should be skipped."""
147+
import json
148+
149+
body = {
150+
"entities": [
151+
{
152+
"typeName": "AuthPolicy",
153+
"guid": -1,
154+
"attributes": {
155+
"name": POLICY_NAME,
156+
"accessControl": {"guid": PERSONA_GUID},
157+
},
158+
}
159+
]
160+
}
161+
req = httpx.Request("POST", BULK_URL, content=json.dumps(body).encode())
162+
assert parse_auth_policy_entity(req) is None
163+
121164

122165
# ---------------------------------------------------------------------------
123166
# create_mock_response

0 commit comments

Comments
 (0)