This is an automated email from the ASF dual-hosted git repository.

liyang-kylin pushed a commit to branch kylin5
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit 28c8d98e79cd772d800fdecb39dbbdf780a74312
Author: Li Yang <[email protected]>
AuthorDate: Sat Nov 7 14:31:39 2026 +0800

    KYLIN-6123 enforce profiling project authorization
---
 .../org/apache/kylin/rest/service/JobService.java  |  4 ++++
 .../apache/kylin/rest/service/JobServiceTest.java  | 28 ++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git 
a/src/data-loading-service/src/main/java/org/apache/kylin/rest/service/JobService.java
 
b/src/data-loading-service/src/main/java/org/apache/kylin/rest/service/JobService.java
index 294dc10b23..f5ec5f8e6c 100644
--- 
a/src/data-loading-service/src/main/java/org/apache/kylin/rest/service/JobService.java
+++ 
b/src/data-loading-service/src/main/java/org/apache/kylin/rest/service/JobService.java
@@ -175,6 +175,7 @@ public class JobService extends BasicService {
     }
 
     public void startProfileByProject(String project, String jobStepId, String 
params) {
+        aclEvaluate.checkProjectOperationPermission(project);
         if (!KylinConfig.getInstanceFromEnv().buildJobProfilingEnabled()) {
             throw new KylinException(JobErrorCode.PROFILING_NOT_ENABLED, 
String.format(Locale.ROOT,
                     MsgPicker.getMsg().getProfilingNotEnabled(), 
BUILD_JOB_PROFILING_PARAMETER));
@@ -184,6 +185,7 @@ public class JobService extends BasicService {
 
     public void dumpProfileByProject(String project, String jobStepId, String 
params,
             Pair<InputStream, String> jobOutputAndDownloadFile) {
+        aclEvaluate.checkProjectOperationPermission(project);
         if (!KylinConfig.getInstanceFromEnv().buildJobProfilingEnabled()) {
             throw new KylinException(JobErrorCode.PROFILING_NOT_ENABLED, 
String.format(Locale.ROOT,
                     MsgPicker.getMsg().getProfilingNotEnabled(), 
BUILD_JOB_PROFILING_PARAMETER));
@@ -200,6 +202,7 @@ public class JobService extends BasicService {
                     MsgPicker.getMsg().getProfilingNotEnabled(), 
BUILD_JOB_PROFILING_PARAMETER));
         }
         Pair<String, String> projectNameAndJobStepId = 
getProjectNameAndJobStepId(yarnAppId);
+        
aclEvaluate.checkProjectOperationPermission(projectNameAndJobStepId.getFirst());
         
BuildAsyncProfileHelper.startProfile(projectNameAndJobStepId.getFirst(), 
projectNameAndJobStepId.getSecond(),
                 params);
     }
@@ -211,6 +214,7 @@ public class JobService extends BasicService {
                     MsgPicker.getMsg().getProfilingNotEnabled(), 
BUILD_JOB_PROFILING_PARAMETER));
         }
         Pair<String, String> projectNameAndJobStepId = 
getProjectNameAndJobStepId(yarnAppId);
+        
aclEvaluate.checkProjectOperationPermission(projectNameAndJobStepId.getFirst());
         InputStream jobOutput = 
BuildAsyncProfileHelper.dump(projectNameAndJobStepId.getFirst(),
                 projectNameAndJobStepId.getSecond(), params);
         jobOutputAndDownloadFile.setFirst(jobOutput);
diff --git 
a/src/data-loading-service/src/test/java/org/apache/kylin/rest/service/JobServiceTest.java
 
b/src/data-loading-service/src/test/java/org/apache/kylin/rest/service/JobServiceTest.java
index b3c83987e7..618021b2c3 100644
--- 
a/src/data-loading-service/src/test/java/org/apache/kylin/rest/service/JobServiceTest.java
+++ 
b/src/data-loading-service/src/test/java/org/apache/kylin/rest/service/JobServiceTest.java
@@ -800,6 +800,7 @@ public class JobServiceTest extends 
NLocalFileMetadataTestCase {
             errorMsg = e.getMessage();
         }
         Assert.assertEquals(0, errorMsg.length());
+        Mockito.verify(aclEvaluate).checkProjectOperationPermission(project);
         HadoopUtil.deletePath(HadoopUtil.getCurrentConfiguration(), 
actionPath);
     }
 
@@ -837,6 +838,7 @@ public class JobServiceTest extends 
NLocalFileMetadataTestCase {
             errorMsg = e.getMessage();
         }
         Assert.assertEquals(0, errorMsg.length());
+        Mockito.verify(aclEvaluate).checkProjectOperationPermission(project);
         HadoopUtil.deletePath(HadoopUtil.getCurrentConfiguration(), 
actionPath);
         HadoopUtil.deletePath(HadoopUtil.getCurrentConfiguration(), 
dumpFilePath);
         t1.interrupt();
@@ -873,6 +875,7 @@ public class JobServiceTest extends 
NLocalFileMetadataTestCase {
                 
KylinConfig.getInstanceFromEnv().getJobTmpProfilerFlagsDir(project, jobStepId) 
+ "/status");
         HadoopUtil.writeStringToHdfs(ProfilerStatus.IDLE(), actionPath);
         jobService.startProfileByYarnAppId(yarnAppId, startParams);
+        Mockito.verify(aclEvaluate).checkProjectOperationPermission(project);
         HadoopUtil.deletePath(HadoopUtil.getCurrentConfiguration(), 
actionPath);
     }
 
@@ -914,11 +917,36 @@ public class JobServiceTest extends 
NLocalFileMetadataTestCase {
             errorMsg = e.getMessage();
         }
         Assert.assertEquals(0, errorMsg.length());
+        Mockito.verify(aclEvaluate).checkProjectOperationPermission(project);
         HadoopUtil.deletePath(HadoopUtil.getCurrentConfiguration(), 
actionPath);
         HadoopUtil.deletePath(HadoopUtil.getCurrentConfiguration(), 
dumpFilePath);
         t1.interrupt();
     }
 
+    @Test
+    public void testProfileOperationsByProjectCheckAcl() {
+        Mockito.doThrow(new AccessDeniedException("Access is 
denied")).when(aclEvaluate)
+                .checkProjectOperationPermission(project);
+
+        Assert.assertThrows(AccessDeniedException.class,
+                () -> jobService.startProfileByProject(project, jobStepId, 
startParams));
+        Assert.assertThrows(AccessDeniedException.class,
+                () -> jobService.dumpProfileByProject(project, jobStepId, 
dumpParams, new Pair<>()));
+    }
+
+    @Test
+    public void testProfileOperationsByYarnAppIdCheckResolvedProjectAcl() {
+        overwriteSystemProp("kylin.engine.spark.cluster-manager-class-name", 
sparkClusterManagerName);
+        Mockito.doReturn(project).when(jobService).getProjectByJobId(jobId);
+        Mockito.doThrow(new AccessDeniedException("Access is 
denied")).when(aclEvaluate)
+                .checkProjectOperationPermission(project);
+
+        Assert.assertThrows(AccessDeniedException.class,
+                () -> jobService.startProfileByYarnAppId(yarnAppId, 
startParams));
+        Assert.assertThrows(AccessDeniedException.class,
+                () -> jobService.dumpProfileByYarnAppId(yarnAppId, dumpParams, 
new Pair<>()));
+    }
+
     @Test
     public void testSetResponseLanguageNull() {
         HttpServletRequest mockRequest = mock(HttpServletRequest.class);

Reply via email to