kylin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From liy...@apache.org
Subject [06/50] [abbrv] kylin git commit: KYLIN-2760 Enhance ACL Logic
Date Fri, 01 Sep 2017 02:54:42 GMT
http://git-wip-us.apache.org/repos/asf/kylin/blob/7a9f74c8/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java b/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
index 751d014..30ee99c 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/TableService.java
@@ -43,11 +43,11 @@ import org.apache.kylin.metadata.model.ColumnDesc;
 import org.apache.kylin.metadata.model.TableDesc;
 import org.apache.kylin.metadata.model.TableExtDesc;
 import org.apache.kylin.metadata.streaming.StreamingConfig;
-import org.apache.kylin.rest.constant.Constant;
 import org.apache.kylin.rest.exception.BadRequestException;
 import org.apache.kylin.rest.msg.Message;
 import org.apache.kylin.rest.msg.MsgPicker;
 import org.apache.kylin.rest.response.TableDescResponse;
+import org.apache.kylin.rest.util.AclEvaluate;
 import org.apache.kylin.source.ISourceMetadataExplorer;
 import org.apache.kylin.source.SourceFactory;
 import org.apache.kylin.source.hive.cardinality.HiveColumnCardinalityJob;
@@ -57,7 +57,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 
@@ -88,27 +87,34 @@ public class TableService extends BasicService {
     @Qualifier("kafkaMgmtService")
     private KafkaConfigService kafkaConfigService;
 
+    @Autowired
+    private AclEvaluate aclEvaluate;
+
     public List<TableDesc> getTableDescByProject(String project, boolean withExt) throws
IOException {
+        aclEvaluate.checkProjectReadPermission(project);
         List<TableDesc> tables = getProjectManager().listDefinedTables(project);
         if (null == tables) {
             return Collections.emptyList();
         }
         if (withExt) {
+            aclEvaluate.checkProjectWritePermission(project);
             tables = cloneTableDesc(tables, project);
         }
         return tables;
     }
 
     public TableDesc getTableDescByName(String tableName, boolean withExt, String prj) {
+        aclEvaluate.checkProjectReadPermission(prj);
         TableDesc table = getMetadataManager().getTableDesc(tableName, prj);
         if (withExt) {
+            aclEvaluate.checkProjectWritePermission(prj);
             table = cloneTableDesc(table, prj);
         }
         return table;
     }
 
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
     public String[] loadHiveTablesToProject(String[] tables, String project) throws Exception
{
+        aclEvaluate.checkProjectWritePermission(project);
         // de-dup
         SetMultimap<String, String> db2tables = LinkedHashMultimap.create();
         for (String fullTableName : tables) {
@@ -176,6 +182,7 @@ public class TableService extends BasicService {
     }
     
     public Map<String, String[]> loadHiveTables(String[] tableNames, String project,
boolean isNeedProfile) throws Exception {
+        aclEvaluate.checkProjectWritePermission(project);
         String submitter = SecurityContextHolder.getContext().getAuthentication().getName();
         Map<String, String[]> result = new HashMap<String, String[]>();
 
@@ -198,6 +205,7 @@ public class TableService extends BasicService {
     }
 
     public Map<String, String[]> unloadHiveTables(String[] tableNames, String project)
throws IOException {
+        aclEvaluate.checkProjectWritePermission(project);
         Set<String> unLoadSuccess = Sets.newHashSet();
         Set<String> unLoadFail = Sets.newHashSet();
         Map<String, String[]> result = new HashMap<String, String[]>();
@@ -231,8 +239,8 @@ public class TableService extends BasicService {
      * @param project
      * @return
      */
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
     public boolean unLoadHiveTable(String tableName, String project) throws IOException {
+        aclEvaluate.checkProjectWritePermission(project);
         Message msg = MsgPicker.getMsg();
 
         boolean rtn = false;
@@ -266,9 +274,9 @@ public class TableService extends BasicService {
             KafkaConfig kafkaConfig = null;
             try {
                 config = streamingService.getStreamingManager().getStreamingConfig(tableName);
-                kafkaConfig = kafkaConfigService.getKafkaConfig(tableName);
-                streamingService.dropStreamingConfig(config);
-                kafkaConfigService.dropKafkaConfig(kafkaConfig);
+                kafkaConfig = kafkaConfigService.getKafkaConfig(tableName, project);
+                streamingService.dropStreamingConfig(config, project);
+                kafkaConfigService.dropKafkaConfig(kafkaConfig, project);
                 rtn = true;
             } catch (Exception e) {
                 rtn = false;
@@ -284,8 +292,8 @@ public class TableService extends BasicService {
      * @param project
      * @throws IOException
      */
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
     public void addStreamingTable(TableDesc desc, String project) throws IOException {
+        aclEvaluate.checkProjectWritePermission(project);
         desc.setUuid(UUID.randomUUID().toString());
         getMetadataManager().saveSourceTable(desc, project);
         syncTableToProject(new String[] { desc.getIdentity() }, project);
@@ -351,7 +359,6 @@ public class TableService extends BasicService {
         return descs;
     }
 
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
     public void calculateCardinalityIfNotPresent(String[] tables, String submitter, String
prj) throws Exception {
         MetadataManager metaMgr = getMetadataManager();
         ExecutableManager exeMgt = ExecutableManager.getInstance(getConfig());
@@ -370,8 +377,8 @@ public class TableService extends BasicService {
      *
      * @param tableName
      */
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN)
     public void calculateCardinality(String tableName, String submitter, String prj) throws
Exception {
+        aclEvaluate.checkProjectWritePermission(prj);
         Message msg = MsgPicker.getMsg();
 
         tableName = normalizeHiveTableName(tableName);

http://git-wip-us.apache.org/repos/asf/kylin/blob/7a9f74c8/server-base/src/main/java/org/apache/kylin/rest/util/AclEvaluate.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/util/AclEvaluate.java b/server-base/src/main/java/org/apache/kylin/rest/util/AclEvaluate.java
new file mode 100644
index 0000000..8ef7423
--- /dev/null
+++ b/server-base/src/main/java/org/apache/kylin/rest/util/AclEvaluate.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+package org.apache.kylin.rest.util;
+
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.cube.CubeManager;
+import org.apache.kylin.engine.mr.CubingJob;
+import org.apache.kylin.job.JobInstance;
+import org.apache.kylin.job.execution.AbstractExecutable;
+import org.apache.kylin.job.execution.ExecutableManager;
+import org.apache.kylin.metadata.project.ProjectInstance;
+import org.apache.kylin.metadata.project.ProjectManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component("aclEvaluate")
+public class AclEvaluate {
+    @Autowired
+    private AclUtil aclUtil;
+
+    private ProjectInstance getProjectInstance(String projectName) {
+        return ProjectManager.getInstance(KylinConfig.getInstanceFromEnv()).getProject(projectName);
+    }
+
+    private ProjectInstance getProjectInstanceByCubeName(String cube) {
+        CubeInstance cubeInstance = CubeManager.getInstance(KylinConfig.getInstanceFromEnv()).getCube(cube);
+        return cubeInstance.getProjectInstance();
+    }
+
+    private ProjectInstance getProjectByJob(JobInstance job) {
+        AbstractExecutable executable = ExecutableManager.getInstance(KylinConfig.getInstanceFromEnv())
+                .getJob(job.getUuid());
+        String projectName = ((CubingJob) executable).getProjectName();
+        return getProjectInstance(projectName);
+    }
+
+    public boolean checkProjectAdminPermission(String projectName) {
+        ProjectInstance projectInstance = getProjectInstance(projectName);
+        return aclUtil.hasProjectAdminPermission(projectInstance);
+    }
+
+    //for raw project
+    public boolean checkProjectReadPermission(String projectName) {
+        ProjectInstance projectInstance = getProjectInstance(projectName);
+        return aclUtil.hasProjectReadPermission(projectInstance);
+    }
+
+    public boolean checkProjectWritePermission(String projectName) {
+        ProjectInstance projectInstance = getProjectInstance(projectName);
+        return aclUtil.hasProjectWritePermission(projectInstance);
+    }
+
+    public boolean checkProjectOperationPermission(String projectName) {
+        ProjectInstance projectInstance = getProjectInstance(projectName);
+        return aclUtil.hasProjectOperationPermission(projectInstance);
+    }
+
+    //for cube acl entity
+    public boolean checkProjectReadPermission(CubeInstance cube) {
+        return aclUtil.hasProjectReadPermission(cube.getProjectInstance());
+    }
+
+
+    public boolean checkProjectWritePermission(CubeInstance cube) {
+        return aclUtil.hasProjectWritePermission(cube.getProjectInstance());
+    }
+
+    public boolean checkProjectOperationPermission(CubeInstance cube) {
+        return aclUtil.hasProjectOperationPermission(cube.getProjectInstance());
+    }
+
+    //for job acl entity
+    public boolean checkProjectReadPermission(JobInstance job) {
+        return aclUtil.hasProjectReadPermission(getProjectByJob(job));
+    }
+
+    public boolean checkProjectWritePermission(JobInstance job) {
+        return aclUtil.hasProjectWritePermission(getProjectByJob(job));
+    }
+
+    public boolean checkProjectOperationPermission(JobInstance job) {
+        return aclUtil.hasProjectOperationPermission(getProjectByJob(job));
+    }
+
+    // ACL util's method, so that you can use AclEvaluate
+    public String getCurrentUserName() {
+        return aclUtil.getCurrentUserName();
+    }
+
+    public boolean hasCubeReadPermission(CubeInstance cube) {
+        return hasProjectReadPermission(cube.getProjectInstance());
+    }
+
+    public boolean hasProjectReadPermission(ProjectInstance project) {
+        return aclUtil.hasProjectReadPermission(project);
+    }
+
+    public boolean hasProjectOperationPermission(ProjectInstance project) {
+        return aclUtil.hasProjectOperationPermission(project);
+    }
+
+    public boolean hasProjectWritePermission(ProjectInstance project) {
+        return aclUtil.hasProjectWritePermission(project);
+    }
+
+    public boolean hasProjectAdminPermission(ProjectInstance project) {
+        return aclUtil.hasProjectAdminPermission(project);
+    }
+
+    public boolean checkIsGlobalAdmin() {
+        return aclUtil.checkIsGlobalAdmin();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/kylin/blob/7a9f74c8/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java
----------------------------------------------------------------------
diff --git a/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java b/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java
index 3b47288..602079e 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java
@@ -18,7 +18,6 @@
 
 package org.apache.kylin.rest.util;
 
-import org.apache.kylin.cube.CubeInstance;
 import org.apache.kylin.metadata.project.ProjectInstance;
 import org.apache.kylin.rest.constant.Constant;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -27,20 +26,44 @@ import org.springframework.stereotype.Component;
 
 @Component("aclUtil")
 public class AclUtil {
+    String getCurrentUserName() {
+        return SecurityContextHolder.getContext().getAuthentication().getName();
+    }
 
     //such method MUST NOT be called from within same class
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#cube, 'ADMINISTRATION')
or hasPermission(#cube, 'MANAGEMENT')" + " or hasPermission(#cube, 'OPERATION') or hasPermission(#cube,
'READ')")
-    public boolean hasCubeReadPermission(CubeInstance cube) {
+    //do not change public to package private
+    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN +
+            " or hasPermission(#project, 'ADMINISTRATION')" +
+            " or hasPermission(#project, 'MANAGEMENT')" +
+            " or hasPermission(#project, 'OPERATION')" +
+            " or hasPermission(#project, 'READ')")
+    public boolean hasProjectReadPermission(ProjectInstance project) {
         return true;
     }
 
-    //such method MUST NOT be called from within same class
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#project, 'ADMINISTRATION')
or hasPermission(#project, 'MANAGEMENT')" + " or hasPermission(#project, 'OPERATION') or hasPermission(#project,
'READ')")
-    public boolean hasProjectReadPermission(ProjectInstance project) {
+    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN +
+            " or hasPermission(#project, 'ADMINISTRATION')" +
+            " or hasPermission(#project, 'MANAGEMENT')" +
+            " or hasPermission(#project, 'OPERATION')")
+    public boolean hasProjectOperationPermission(ProjectInstance project) {
         return true;
     }
 
-    public String getCurrentUserName() {
-        return SecurityContextHolder.getContext().getAuthentication().getName();
+    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN +
+            " or hasPermission(#project, 'ADMINISTRATION')" +
+            " or hasPermission(#project, 'MANAGEMENT')")
+    public boolean hasProjectWritePermission(ProjectInstance project) {
+        return true;
+    }
+
+    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN +
+            " or hasPermission(#project, 'ADMINISTRATION')")
+    public boolean hasProjectAdminPermission(ProjectInstance project) {
+        return true;
+    }
+
+    @PreAuthorize("hasRole('ROLE_ADMIN')")
+    public boolean checkIsGlobalAdmin() {
+        return true;
     }
 }

http://git-wip-us.apache.org/repos/asf/kylin/blob/7a9f74c8/server-base/src/test/java/org/apache/kylin/rest/bean/BeanTest.java
----------------------------------------------------------------------
diff --git a/server-base/src/test/java/org/apache/kylin/rest/bean/BeanTest.java b/server-base/src/test/java/org/apache/kylin/rest/bean/BeanTest.java
index 27c77c3..da41952 100644
--- a/server-base/src/test/java/org/apache/kylin/rest/bean/BeanTest.java
+++ b/server-base/src/test/java/org/apache/kylin/rest/bean/BeanTest.java
@@ -65,7 +65,12 @@ public class BeanTest {
         Assert.assertTrue(!coulmnMeta.isSigned());
 
         Assert.assertEquals(Constant.ACCESS_HAS_ROLE_ADMIN, "hasRole('ROLE_ADMIN')");
-        Assert.assertEquals(Constant.ACCESS_POST_FILTER_READ, "hasRole('ROLE_ADMIN') or hasPermission(filterObject,
'READ') or hasPermission(filterObject, 'MANAGEMENT') " + "or hasPermission(filterObject, 'OPERATION')
or hasPermission(filterObject, 'ADMINISTRATION')");
+        Assert.assertEquals(Constant.ACCESS_POST_FILTER_READ,
+                "hasRole('ROLE_ADMIN') " +
+                        " or hasPermission(filterObject, 'ADMINISTRATION')"+
+                        " or hasPermission(filterObject, 'MANAGEMENT')" +
+                        " or hasPermission(filterObject, 'OPERATION')" +
+                        " or hasPermission(filterObject, 'READ')");
         Assert.assertEquals(Constant.FakeCatalogName, "defaultCatalog");
         Assert.assertEquals(Constant.FakeSchemaName, "defaultSchema");
         Assert.assertEquals(Constant.IDENTITY_ROLE, "role");

http://git-wip-us.apache.org/repos/asf/kylin/blob/7a9f74c8/server/src/test/java/org/apache/kylin/rest/controller/AccessControllerTest.java
----------------------------------------------------------------------
diff --git a/server/src/test/java/org/apache/kylin/rest/controller/AccessControllerTest.java
b/server/src/test/java/org/apache/kylin/rest/controller/AccessControllerTest.java
index 18fbd06..059dfdb 100644
--- a/server/src/test/java/org/apache/kylin/rest/controller/AccessControllerTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/controller/AccessControllerTest.java
@@ -154,7 +154,12 @@ public class AccessControllerTest extends ServiceTestBase implements
AclEntityTy
         assertTrue(cubes.size() > 0);
         CubeInstance cube = cubes.get(0);
         swichToAnalyst();
-        cubes = cubeController.getCubes(null, null, null, 100000, 0);
+        cubes.clear();
+        try {
+            cubes = cubeController.getCubes(null, null, null, 100000, 0);
+        } catch (AccessDeniedException e) {
+            //correct
+        }
         assertTrue(cubes.size() == 0);
 
         //grant auth
@@ -166,24 +171,30 @@ public class AccessControllerTest extends ServiceTestBase implements
AclEntityTy
             //correct
         }
         swichToAdmin();
-        List<AccessEntryResponse> aes = accessController.grant(CUBE_INSTANCE, cube.getUuid(),
accessRequest);
+        List<ProjectInstance> projects = projectController.getProjects(10000, 0);
+        List<AccessEntryResponse> aes = accessController.grant(PROJECT_INSTANCE, projects.get(0).getUuid(),
accessRequest);
         Assert.assertTrue(aes.size() == 1);
         swichToAnalyst();
-        cubes = cubeController.getCubes(null, null, null, 100000, 0);
-        assertEquals(1, cubes.size());
+        cubes = cubeController.getCubes(null, null, "default", 100000, 0);
+        assertTrue(cubes.size() > 0);
+        cubes.clear();
 
         //revoke auth
         try {
-            accessController.revoke(CUBE_INSTANCE, cube.getUuid(), accessRequest);
+            accessController.revoke(PROJECT_INSTANCE, projects.get(0).getUuid(), accessRequest);
             fail("ANALYST should not have auth to revoke");
         } catch (AccessDeniedException e) {
             //correct
         }
         swichToAdmin();
         accessRequest.setAccessEntryId((Long) aes.get(0).getId());
-        accessController.revoke(CUBE_INSTANCE, cube.getUuid(), accessRequest);
+        accessController.revoke(PROJECT_INSTANCE, projects.get(0).getUuid(), accessRequest);
         swichToAnalyst();
-        cubes = cubeController.getCubes(null, null, null, 10000, 0);
+        try {
+            cubes = cubeController.getCubes(null, null, null, 10000, 0);
+        } catch (AccessDeniedException e) {
+            //correct
+        }
         assertEquals(0, cubes.size());
     }
 


Mime
View raw message