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


The following commit(s) were added to refs/heads/atlas-2.6 by this push:
     new 205b53fca ATLAS-5326: Enforce Atlas authorization on AdminResource 
REST endpoints (#675)
205b53fca is described below

commit 205b53fcae3d8a39583756e66976c74da0823a3b
Author: Radhika Kundam <[email protected]>
AuthorDate: Tue Jul 28 09:59:09 2026 -0700

    ATLAS-5326: Enforce Atlas authorization on AdminResource REST endpoints 
(#675)
    
    * ATLAS-5326: Enforce Atlas authorization on AdminResource REST endpoints
    
    (cherry picked from commit 53af3d8d7667ab17636aab8ecfd39f829724f2a9)
---
 .../apache/atlas/web/resources/AdminResource.java  |  30 ++-
 .../atlas/web/resources/AdminResourceTest.java     | 272 +++++++++++++++------
 2 files changed, 231 insertions(+), 71 deletions(-)

diff --git 
a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java 
b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
index da9967a1c..b0e3b04b8 100755
--- a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
@@ -268,9 +268,11 @@ public class AdminResource {
     @GET
     @Path("stack")
     @Produces(MediaType.TEXT_PLAIN)
-    public String getThreadDump() {
+    public String getThreadDump() throws AtlasBaseException {
         LOG.debug("==> AdminResource.getThreadDump()");
 
+        AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_EXPORT), "thread dump");
+
         ThreadGroup topThreadGroup = Thread.currentThread().getThreadGroup();
 
         while (topThreadGroup.getParent() != null) {
@@ -735,6 +737,8 @@ public class AdminResource {
     @Produces(Servlets.JSON_MEDIA_TYPE)
     @Consumes(MediaType.APPLICATION_JSON)
     public void abortAsyncImport(@PathParam("importId") String importId) 
throws AtlasBaseException {
+        AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_IMPORT), "abort async import");
+
         importService.abortAsyncImport(importId);
     }
 
@@ -749,6 +753,8 @@ public class AdminResource {
                 perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"AdminResource.getAsyncImportStatus()");
             }
 
+            AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_IMPORT), "async import status");
+
             return importService.getAsyncImportsStatus(offset, limit);
         } finally {
             AtlasPerfTracer.log(perf);
@@ -766,6 +772,8 @@ public class AdminResource {
                 perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"AdminResource.getAsyncImportStatusById(importId=" + importId + ")");
             }
 
+            AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_IMPORT), "async import status by 
id");
+
             return importService.getAsyncImportRequest(importId);
         } finally {
             AtlasPerfTracer.log(perf);
@@ -923,6 +931,8 @@ public class AdminResource {
                 perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"cluster.getServer(" + serverName + ")");
             }
 
+            AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_EXPORT), "get server");
+
             AtlasServer cluster = new AtlasServer(serverName, serverName);
 
             return atlasServerService.get(cluster);
@@ -946,6 +956,8 @@ public class AdminResource {
                 perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"getExportImportAudit(" + serverName + ")");
             }
 
+            AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_EXPORT), "export import audit");
+
             return exportImportAuditService.get(userName, operation, 
serverName, startTime, endTime, limit, offset);
         } finally {
             AtlasPerfTracer.log(perf);
@@ -1018,6 +1030,8 @@ public class AdminResource {
                 perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"AdminResource.getAuditDetails(" + auditGuid + ", " + limit + ", " + offset + 
")");
             }
 
+            AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_AUDITS), "audit details");
+
             List<AtlasEntityHeader> ret = new ArrayList<>();
 
             AtlasAuditEntry auditEntry = 
auditService.toAtlasAuditEntry(entityStore.getById(auditGuid, false, true));
@@ -1075,6 +1089,8 @@ public class AdminResource {
                 perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "checkState(" + 
request + ")");
             }
 
+            AtlasAuthorizationUtils.verifyAccess(new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_READ), "check 
state");
+
             return entityStore.checkState(request);
         } finally {
             AtlasPerfTracer.log(perf);
@@ -1084,9 +1100,11 @@ public class AdminResource {
     @GET
     @Path("patches")
     @Produces(Servlets.JSON_MEDIA_TYPE)
-    public AtlasPatches getAtlasPatches() {
+    public AtlasPatches getAtlasPatches() throws AtlasBaseException {
         LOG.debug("==> AdminResource.getAtlasPatches()");
 
+        AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_IMPORT), "patches");
+
         AtlasPatches ret = patchManager.getAllPatches();
 
         LOG.debug("<== AdminResource.getAtlasPatches()");
@@ -1098,6 +1116,8 @@ public class AdminResource {
     @Path("/tasks")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public List<AtlasTask> getTaskStatus(@QueryParam("guids") List<String> 
guids) throws AtlasBaseException {
+        AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_PURGE), "tasks");
+
         return CollectionUtils.isNotEmpty(guids) ? 
taskManagement.getByGuids(guids) : taskManagement.getAll();
     }
 
@@ -1105,6 +1125,8 @@ public class AdminResource {
     @Path("/tasks")
     @Produces(Servlets.JSON_MEDIA_TYPE)
     public void deleteTask(@QueryParam("guids") List<String> guids) throws 
AtlasBaseException {
+        AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_PURGE), "delete tasks");
+
         if (CollectionUtils.isNotEmpty(guids)) {
             taskManagement.deleteByGuids(guids);
         }
@@ -1113,7 +1135,9 @@ public class AdminResource {
     @GET
     @Path("/debug/metrics")
     @Produces(MediaType.APPLICATION_JSON)
-    public Map<String, DebugMetrics> getDebugMetrics() {
+    public Map<String, DebugMetrics> getDebugMetrics() throws 
AtlasBaseException {
+        AtlasAuthorizationUtils.verifyAccess(new 
AtlasAdminAccessRequest(AtlasPrivilege.ADMIN_EXPORT), "debug metrics");
+
         return debugMetricsRESTSink.getMetrics();
     }
 
diff --git 
a/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java 
b/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
index 7723ee75a..0402c333f 100644
--- a/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
+++ b/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
@@ -21,6 +21,7 @@ package org.apache.atlas.web.resources;
 import com.fasterxml.jackson.databind.JsonNode;
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.authorize.AtlasAuthorizationUtils;
+import org.apache.atlas.authorize.AtlasEntityAccessRequest;
 import org.apache.atlas.discovery.SearchContext;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.PList;
@@ -96,6 +97,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.Callable;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyBoolean;
@@ -232,6 +234,22 @@ public class AdminResourceTest {
                 debugMetricsRESTSink, auditReductionService, atlasMetricsUtil, 
purgeService);
     }
 
+    private void withAuthorizationBypass(Runnable runnable) {
+        try (MockedStatic<AtlasAuthorizationUtils> mockedUtils = 
mockStatic(AtlasAuthorizationUtils.class)) {
+            mockedUtils.when(() -> 
AtlasAuthorizationUtils.verifyAccess(any(org.apache.atlas.authorize.AtlasAdminAccessRequest.class),
 any())).then(invocation -> null);
+            mockedUtils.when(() -> 
AtlasAuthorizationUtils.verifyAccess(any(AtlasEntityAccessRequest.class), 
any())).then(invocation -> null);
+            runnable.run();
+        }
+    }
+
+    private <T> T withAuthorizationBypassCallable(Callable<T> callable) throws 
Exception {
+        try (MockedStatic<AtlasAuthorizationUtils> mockedUtils = 
mockStatic(AtlasAuthorizationUtils.class)) {
+            mockedUtils.when(() -> 
AtlasAuthorizationUtils.verifyAccess(any(org.apache.atlas.authorize.AtlasAdminAccessRequest.class),
 any())).then(invocation -> null);
+            mockedUtils.when(() -> 
AtlasAuthorizationUtils.verifyAccess(any(AtlasEntityAccessRequest.class), 
any())).then(invocation -> null);
+            return callable.call();
+        }
+    }
+
     // Helper method to inject HttpServletRequest via reflection
     private void injectHttpServletRequest(AdminResource adminResource) throws 
Exception {
         Field requestField = 
AdminResource.class.getDeclaredField("httpServletRequest");
@@ -249,11 +267,18 @@ public class AdminResourceTest {
     @Test
     public void testGetThreadDump() {
         AdminResource adminResource = createAdminResource();
-        String threadDump = adminResource.getThreadDump();
+        withAuthorizationBypass(() -> {
+            String threadDump = null;
+            try {
+                threadDump = adminResource.getThreadDump();
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
 
-        assertNotNull(threadDump);
-        assertTrue(threadDump.length() > 0);
-        assertTrue(threadDump.contains("State:"));
+            assertNotNull(threadDump);
+            assertTrue(threadDump.length() > 0);
+            assertTrue(threadDump.contains("State:"));
+        });
     }
 
     @Test
@@ -436,10 +461,16 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        AtlasCheckStateResult result = adminResource.checkState(request);
+        withAuthorizationBypass(() -> {
+            try {
+                AtlasCheckStateResult result = 
adminResource.checkState(request);
 
-        assertNotNull(result);
-        verify(entityStore).checkState(request);
+                assertNotNull(result);
+                verify(entityStore).checkState(request);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -450,10 +481,16 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        AtlasPatches result = adminResource.getAtlasPatches();
+        withAuthorizationBypass(() -> {
+            try {
+                AtlasPatches result = adminResource.getAtlasPatches();
 
-        assertNotNull(result);
-        verify(patchManager).getAllPatches();
+                assertNotNull(result);
+                verify(patchManager).getAllPatches();
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -470,11 +507,17 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasTask> result = adminResource.getTaskStatus(guids);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasTask> result = adminResource.getTaskStatus(guids);
 
-        assertNotNull(result);
-        assertFalse(result.isEmpty());
-        verify(taskManagement).getByGuids(guids);
+                assertNotNull(result);
+                assertFalse(result.isEmpty());
+                verify(taskManagement).getByGuids(guids);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -487,10 +530,16 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasTask> result = adminResource.getTaskStatus(null);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasTask> result = adminResource.getTaskStatus(null);
 
-        assertNotNull(result);
-        verify(taskManagement).getAll();
+                assertNotNull(result);
+                verify(taskManagement).getAll();
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -501,19 +550,31 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        adminResource.deleteTask(guids);
+        withAuthorizationBypass(() -> {
+            try {
+                adminResource.deleteTask(guids);
 
-        verify(taskManagement).deleteByGuids(guids);
+                verify(taskManagement).deleteByGuids(guids);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
     public void testDeleteTaskWithEmptyGuids() throws Exception {
         AdminResource adminResource = createAdminResource();
 
-        adminResource.deleteTask(null);
+        withAuthorizationBypass(() -> {
+            try {
+                adminResource.deleteTask(null);
 
-        // Should not call deleteByGuids when guids is null or empty
-        verify(taskManagement, never()).deleteByGuids(any());
+                // Should not call deleteByGuids when guids is null or empty
+                verify(taskManagement, never()).deleteByGuids(any());
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -526,11 +587,17 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        Map<String, DebugMetrics> result = adminResource.getDebugMetrics();
+        withAuthorizationBypass(() -> {
+            try {
+                Map<String, DebugMetrics> result = 
adminResource.getDebugMetrics();
 
-        assertNotNull(result);
-        assertFalse(result.isEmpty());
-        verify(debugMetricsRESTSink).getMetrics();
+                assertNotNull(result);
+                assertFalse(result.isEmpty());
+                verify(debugMetricsRESTSink).getMetrics();
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -661,7 +728,10 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        adminResource.checkState(request);
+        withAuthorizationBypassCallable(() -> {
+            adminResource.checkState(request);
+            return null;
+        });
     }
 
     @Test
@@ -812,9 +882,15 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        adminResource.abortAsyncImport(importId);
+        withAuthorizationBypass(() -> {
+            try {
+                adminResource.abortAsyncImport(importId);
 
-        verify(importService).abortAsyncImport(importId);
+                verify(importService).abortAsyncImport(importId);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -828,10 +904,16 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        PList<AsyncImportStatus> result = 
adminResource.getAsyncImportStatus(offset, limit);
+        withAuthorizationBypass(() -> {
+            try {
+                PList<AsyncImportStatus> result = 
adminResource.getAsyncImportStatus(offset, limit);
 
-        assertNotNull(result);
-        verify(importService).getAsyncImportsStatus(offset, limit);
+                assertNotNull(result);
+                verify(importService).getAsyncImportsStatus(offset, limit);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -844,10 +926,16 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        AtlasAsyncImportRequest result = 
adminResource.getAsyncImportStatusById(importId);
+        withAuthorizationBypass(() -> {
+            try {
+                AtlasAsyncImportRequest result = 
adminResource.getAsyncImportStatusById(importId);
 
-        assertNotNull(result);
-        verify(importService).getAsyncImportRequest(importId);
+                assertNotNull(result);
+                verify(importService).getAsyncImportRequest(importId);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -860,10 +948,16 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        AtlasServer result = adminResource.getCluster(serverName);
+        withAuthorizationBypass(() -> {
+            try {
+                AtlasServer result = adminResource.getCluster(serverName);
 
-        assertNotNull(result);
-        verify(atlasServerService).get(any(AtlasServer.class));
+                assertNotNull(result);
+                verify(atlasServerService).get(any(AtlasServer.class));
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -885,12 +979,18 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<ExportImportAuditEntry> result = 
adminResource.getExportImportAudit(serverName, userName, operation,
-                startTime, endTime, limit, offset);
+        withAuthorizationBypass(() -> {
+            try {
+                List<ExportImportAuditEntry> result = 
adminResource.getExportImportAudit(serverName, userName, operation,
+                        startTime, endTime, limit, offset);
 
-        assertNotNull(result);
-        assertFalse(result.isEmpty());
-        verify(exportImportAuditService).get(userName, operation, serverName, 
startTime, endTime, limit, offset);
+                assertNotNull(result);
+                assertFalse(result.isEmpty());
+                verify(exportImportAuditService).get(userName, operation, 
serverName, startTime, endTime, limit, offset);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -904,11 +1004,17 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasTask> result = adminResource.ageoutAuditData(criteria, true);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasTask> result = 
adminResource.ageoutAuditData(criteria, true);
 
-        assertNotNull(result);
-        assertFalse(result.isEmpty());
-        verify(auditReductionService).startAuditAgingByConfig();
+                assertNotNull(result);
+                assertFalse(result.isEmpty());
+                verify(auditReductionService).startAuditAgingByConfig();
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -931,12 +1037,18 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasTask> result = adminResource.ageoutAuditData(criteria, 
false);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasTask> result = 
adminResource.ageoutAuditData(criteria, false);
 
-        assertNotNull(result);
-        assertFalse(result.isEmpty());
-        
verify(auditReductionService).buildAgeoutCriteriaForAllAgingTypes(criteria);
-        
verify(auditReductionService).startAuditAgingByCriteria(mockCriteriaMap);
+                assertNotNull(result);
+                assertFalse(result.isEmpty());
+                
verify(auditReductionService).buildAgeoutCriteriaForAllAgingTypes(criteria);
+                
verify(auditReductionService).startAuditAgingByCriteria(mockCriteriaMap);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -946,10 +1058,16 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasTask> result = adminResource.ageoutAuditData(criteria, 
false);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasTask> result = 
adminResource.ageoutAuditData(criteria, false);
 
-        assertNull(result);
-        verify(auditReductionService, 
never()).startAuditAgingByCriteria(any());
+                assertNull(result);
+                verify(auditReductionService, 
never()).startAuditAgingByCriteria(any());
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -963,11 +1081,17 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasAuditEntry> result = 
adminResource.getAtlasAudits(searchParameters);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasAuditEntry> result = 
adminResource.getAtlasAudits(searchParameters);
 
-        assertNotNull(result);
-        assertFalse(result.isEmpty());
-        verify(auditService).get(searchParameters);
+                assertNotNull(result);
+                assertFalse(result.isEmpty());
+                verify(auditService).get(searchParameters);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -992,12 +1116,18 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasEntityHeader> result = 
adminResource.getAuditDetails(auditGuid, limit, offset);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasEntityHeader> result = 
adminResource.getAuditDetails(auditGuid, limit, offset);
 
-        assertNotNull(result);
-        assertFalse(result.isEmpty());
-        verify(entityStore).getById(auditGuid, false, true);
-        verify(auditService).toAtlasAuditEntry(any());
+                assertNotNull(result);
+                assertFalse(result.isEmpty());
+                verify(entityStore).getById(auditGuid, false, true);
+                verify(auditService).toAtlasAuditEntry(any());
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test
@@ -1012,11 +1142,17 @@ public class AdminResourceTest {
 
         AdminResource adminResource = createAdminResource();
 
-        List<AtlasEntityHeader> result = 
adminResource.getAuditDetails(auditGuid, 10, 0);
+        withAuthorizationBypass(() -> {
+            try {
+                List<AtlasEntityHeader> result = 
adminResource.getAuditDetails(auditGuid, 10, 0);
 
-        assertNotNull(result);
-        assertTrue(result.isEmpty());
-        verify(entityStore).getById(auditGuid, false, true);
+                assertNotNull(result);
+                assertTrue(result.isEmpty());
+                verify(entityStore).getById(auditGuid, false, true);
+            } catch (AtlasBaseException e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
     @Test

Reply via email to