This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch atlas-2.6 in repository https://gitbox.apache.org/repos/asf/atlas.git
commit a891f16617d85a8d3b808bc319bb481118bd7148 Author: sheetalshah1007 <[email protected]> AuthorDate: Fri Sep 25 17:56:12 2026 +0530 ATLAS-5418: Enforce entity read check on v1 entity audit API (#770) --- .../apache/atlas/web/resources/EntityResource.java | 6 +++ .../java/org/apache/atlas/web/rest/EntityREST.java | 27 ++++++----- .../atlas/web/resources/EntityResourceTest.java | 52 +++++++++++++++++++++- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java index 7d6e829a42..4959065c4f 100755 --- a/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java +++ b/webapp/src/main/java/org/apache/atlas/web/resources/EntityResource.java @@ -992,6 +992,8 @@ public class EntityResource { perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityResource.getAuditEvents(" + guid + ", " + startKey + ", " + count + ")"); } + entityREST.verifyEntityReadForAudit(guid); + List<Object> events = entityAuditRepository.listEvents(guid, startKey, count); List<EntityAuditEvent> v1Events = new ArrayList<>(); @@ -1011,6 +1013,10 @@ public class EntityResource { response.put(AtlasClient.EVENTS, v1Events); return Response.ok(AtlasJson.toV1Json(response)).build(); + } catch (AtlasBaseException e) { + LOG.error("Unable to get audit events for entity guid={} startKey={}", guid, startKey, e); + + throw toWebApplicationException(e); } catch (IllegalArgumentException e) { LOG.error("Unable to get audit events for entity guid={} startKey={}", guid, startKey, e); diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java index 07f142d82a..6e2310a6c7 100644 --- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java +++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java @@ -850,18 +850,7 @@ public class EntityREST { perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "EntityREST.getAuditEvents(" + guid + ", " + startKey + ", " + count + ")"); } - // Enforces authorization for entity-read - try { - entitiesStore.getHeaderById(guid); - } catch (AtlasBaseException e) { - if (e.getAtlasErrorCode() == AtlasErrorCode.INSTANCE_GUID_NOT_FOUND) { - AtlasEntityHeader entityHeader = getEntityHeaderFromPurgedAudit(guid); - - AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, entityHeader), "read entity audit: guid=", guid); - } else { - throw e; - } - } + verifyEntityReadForAudit(guid); List<EntityAuditEventV2> ret = new ArrayList<>(); @@ -1288,6 +1277,20 @@ public class EntityREST { } } + public void verifyEntityReadForAudit(String guid) throws AtlasBaseException { + try { + entitiesStore.getHeaderById(guid); + } catch (AtlasBaseException e) { + if (e.getAtlasErrorCode() == AtlasErrorCode.INSTANCE_GUID_NOT_FOUND) { + AtlasEntityHeader entityHeader = getEntityHeaderFromPurgedAudit(guid); + + AtlasAuthorizationUtils.verifyAccess(new AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ, entityHeader), "read entity audit: guid=", guid); + } else { + throw e; + } + } + } + private AtlasEntityHeader getEntityHeaderFromPurgedAudit(String guid) throws AtlasBaseException { List<EntityAuditEventV2> auditEvents = auditRepository.listEventsV2(guid, EntityAuditActionV2.ENTITY_PURGE, null, (short) 1); AtlasEntityHeader ret = CollectionUtils.isNotEmpty(auditEvents) ? auditEvents.get(0).getEntityHeader() : null; diff --git a/webapp/src/test/java/org/apache/atlas/web/resources/EntityResourceTest.java b/webapp/src/test/java/org/apache/atlas/web/resources/EntityResourceTest.java index 7a62a726ba..23e8bcb165 100644 --- a/webapp/src/test/java/org/apache/atlas/web/resources/EntityResourceTest.java +++ b/webapp/src/test/java/org/apache/atlas/web/resources/EntityResourceTest.java @@ -17,22 +17,37 @@ */ package org.apache.atlas.web.resources; +import org.apache.atlas.AtlasErrorCode; +import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.instance.AtlasEntityHeader; import org.apache.atlas.model.instance.EntityMutationResponse; import org.apache.atlas.model.instance.EntityMutations; +import org.apache.atlas.repository.audit.EntityAuditRepository; +import org.apache.atlas.repository.converters.AtlasInstanceConverter; import org.apache.atlas.repository.store.graph.AtlasEntityStore; +import org.apache.atlas.type.AtlasTypeRegistry; +import org.apache.atlas.web.rest.EntityREST; import org.apache.commons.collections.CollectionUtils; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.expectThrows; /** * Unit test of {@link EntityResource} @@ -41,11 +56,30 @@ public class EntityResourceTest { private static final String DELETED_GUID = "deleted_guid"; @Mock - AtlasEntityStore entitiesStore; + private AtlasInstanceConverter restAdapters; + + @Mock + private AtlasEntityStore entitiesStore; + + @Mock + private AtlasTypeRegistry typeRegistry; + + @Mock + private EntityREST entityREST; + + @Mock + private EntityAuditRepository entityAuditRepository; + + @Mock + private AtlasInstanceConverter instanceConverter; + + private EntityResource entityResource; @BeforeMethod public void setUp() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); + entityResource = new EntityResource(restAdapters, entitiesStore, typeRegistry, entityREST, entityAuditRepository, + instanceConverter); } @Test @@ -72,6 +106,20 @@ public class EntityResourceTest { assertEquals(responseDeletedEntities, deletedEntities); } + @Test + public void testGetAuditEvents_deniedWhenEntityReadNotAllowed() throws Exception { + String guid = "test-guid"; + + doThrow(new AtlasBaseException(AtlasErrorCode.UNAUTHORIZED_ACCESS, "bob", "entity-read")).when(entityREST) + .verifyEntityReadForAudit(guid); + + WebApplicationException exception = expectThrows(WebApplicationException.class, + () -> entityResource.getAuditEvents(guid, null, (short) 10)); + + assertEquals(exception.getResponse().getStatus(), Response.Status.FORBIDDEN.getStatusCode()); + verify(entityAuditRepository, never()).listEvents(anyString(), any(), any(Short.class)); + } + private List<AtlasEntityHeader> toAtlasEntityHeaders(List<String> guids) { List<AtlasEntityHeader> ret = null;
