This is an automated email from the ASF dual-hosted git repository.
mandarambawane pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new 134148188 ATLAS-5418: Enforce entity read check on v1 entity audit API
(#770)
134148188 is described below
commit 13414818896c2efb902b1c14ddb23bfe69f97b9d
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 ccf66c595..a011902a2 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 1f0e380cd..9f5f7b01c 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 7a62a726b..23e8bcb16 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;