You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by ni...@apache.org on 2019/08/27 10:24:01 UTC

[kylin] branch master updated: The table should not display in Insight page when the user has no access to the table

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

nic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kylin.git


The following commit(s) were added to refs/heads/master by this push:
     new 54c1acf  The table should not display in Insight page when the user has no access to the table
54c1acf is described below

commit 54c1acf8d9a0f5a47e16484a690516977f79073f
Author: yaqian.zhang <59...@qq.com>
AuthorDate: Tue Aug 6 20:22:53 2019 +0800

    The table should not display in Insight page when the user has no access to the table
---
 .../org/apache/kylin/metadata/acl/TableACL.java    |  6 +++
 .../kylin/rest/controller/QueryController.java     | 10 ++---
 .../apache/kylin/rest/service/QueryService.java    |  8 ++++
 .../apache/kylin/rest/service/TableACLService.java | 44 ++++++++++++++++++++++
 .../kylin/rest/controller/QueryControllerTest.java |  7 +++-
 5 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java b/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java
index 57ebb61..b110064 100644
--- a/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java
+++ b/core-metadata/src/main/java/org/apache/kylin/metadata/acl/TableACL.java
@@ -34,6 +34,7 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 @SuppressWarnings("serial")
 @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE,
@@ -86,6 +87,11 @@ public class TableACL extends RootPersistentEntity {
         return currentEntry(type).getCanAccessList(table, allIdentifiers);
     }
 
+    public Set<String> getBlockedTablesByUser(String username, String type) {
+        return currentEntry(type).get(username) == null ? Sets.<String>newHashSet()
+                : currentEntry(type).get(username).getTables();
+    }
+
     public TableACL add(String name, String table, String type) {
         currentEntry(type).add(name, table);
         return this;
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
index b89772b..0323881 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/QueryController.java
@@ -37,7 +37,7 @@ import org.apache.kylin.common.QueryContext;
 import org.apache.kylin.common.QueryContextFacade;
 import org.apache.kylin.common.debug.BackdoorToggles;
 import org.apache.kylin.metadata.querymeta.SelectedColumnMeta;
-import org.apache.kylin.metadata.querymeta.TableMeta;
+import org.apache.kylin.metadata.querymeta.TableMetaWithType;
 import org.apache.kylin.rest.exception.ForbiddenException;
 import org.apache.kylin.rest.exception.InternalErrorException;
 import org.apache.kylin.rest.model.Query;
@@ -186,12 +186,8 @@ public class QueryController extends BasicController {
 
     @RequestMapping(value = "/tables_and_columns", method = RequestMethod.GET, produces = { "application/json" })
     @ResponseBody
-    public List<TableMeta> getMetadata(MetaRequest metaRequest) {
-        try {
-            return queryService.getMetadata(metaRequest.getProject());
-        } catch (SQLException e) {
-            throw new InternalErrorException(e.getLocalizedMessage(), e);
-        }
+    public List<TableMetaWithType> getMetadataV2(MetaRequest metaRequest) throws IOException, SQLException {
+            return queryService.getMetadataV2FilterByUser(metaRequest.getProject());
     }
 
     /**
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
index 171bd07..59e569b 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
@@ -158,6 +158,10 @@ public class QueryService extends BasicService {
     private ModelService modelService;
 
     @Autowired
+    @Qualifier("TableAclService")
+    private TableACLService tableAclService;
+
+    @Autowired
     private AclEvaluate aclEvaluate;
 
     private GenericKeyedObjectPool<PreparedContextKey, PreparedContext> preparedContextPool;
@@ -777,6 +781,10 @@ public class QueryService extends BasicService {
         return tableMetas;
     }
 
+    public List<TableMetaWithType> getMetadataV2FilterByUser(String project) throws SQLException, IOException {
+        return tableAclService.filterTableMetasByAcl(getMetadataV2(project), project);
+    }
+
     public List<TableMetaWithType> getMetadataV2(String project) throws SQLException, IOException {
         return getMetadataV2(getCubeManager(), project);
     }
diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/TableACLService.java b/server-base/src/main/java/org/apache/kylin/rest/service/TableACLService.java
index c054ba0..ca4a6bf 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/TableACLService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/TableACLService.java
@@ -18,17 +18,25 @@
 
 package org.apache.kylin.rest.service;
 
+import static org.apache.kylin.metadata.MetadataConstants.TYPE_USER;
+
 import java.io.IOException;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.kylin.common.KylinConfig;
+import org.apache.kylin.metadata.project.ProjectManager;
+import org.apache.kylin.metadata.querymeta.TableMetaWithType;
 import org.apache.kylin.metadata.acl.TableACL;
 import org.apache.kylin.rest.util.AclEvaluate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 
+import com.google.common.collect.Lists;
+
 @Component("TableAclService")
 public class TableACLService extends BasicService {
     private static final Logger logger = LoggerFactory.getLogger(TableACLService.class);
@@ -74,4 +82,40 @@ public class TableACLService extends BasicService {
         aclEvaluate.checkProjectAdminPermission(project);
         getTableACLManager().deleteTableACLByTbl(project, table);
     }
+
+    public List<TableMetaWithType> filterTableMetasByAcl(List<TableMetaWithType> tableMetaWithTypes, String project) throws IOException {
+        return filterByAcl(tableMetaWithTypes, project, new AclFilter<TableMetaWithType>() {
+            @Override
+            public boolean filter(TableMetaWithType table, Set<String> blockedTables) {
+                String identity = table.getTABLE_SCHEM() + "." + table.getTABLE_NAME();
+                return !blockedTables.contains(identity);
+            }
+        });
+    }
+
+    private interface AclFilter<T> {
+        boolean filter(T table, Set<String> blockedTables);
+    }
+
+    private <T> List<T> filterByAcl(List<T> tables, String project, AclFilter filter) throws IOException {
+        ProjectManager projectManager = ProjectManager.getInstance(KylinConfig.getInstanceFromEnv());
+
+        if (aclEvaluate.hasProjectAdminPermission(projectManager.getProject(project))) {
+            return tables;
+        }
+
+        String username = SecurityContextHolder.getContext().getAuthentication().getName();
+        Set<String> blockedTables = getBlockedTablesByUser(project, username, TYPE_USER);
+        List<T> result = Lists.newArrayList();
+        for (T table : tables) {
+            if (filter.filter(table, blockedTables)) {
+                result.add(table);
+            }
+        }
+        return result;
+    }
+
+    private Set<String> getBlockedTablesByUser(String project, String username, String type) throws IOException {
+        return getTableACLByProject(project).getBlockedTablesByUser(username, type);
+    }
 }
diff --git a/server/src/test/java/org/apache/kylin/rest/controller/QueryControllerTest.java b/server/src/test/java/org/apache/kylin/rest/controller/QueryControllerTest.java
index 2225096..c90b5c7 100644
--- a/server/src/test/java/org/apache/kylin/rest/controller/QueryControllerTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/controller/QueryControllerTest.java
@@ -33,6 +33,9 @@ import org.springframework.beans.factory.annotation.Qualifier;
 
 import org.springframework.cache.CacheManager;
 
+import java.io.IOException;
+import java.sql.SQLException;
+
 /**
  * @author xduo
  */
@@ -77,8 +80,8 @@ public class QueryControllerTest extends ServiceTestBase {
     }
 
     @Test
-    public void testGetMetadata() {
-        queryController.getMetadata(new MetaRequest(ProjectInstance.DEFAULT_PROJECT_NAME));
+    public void testGetMetadata() throws IOException, SQLException {
+        queryController.getMetadataV2(new MetaRequest(ProjectInstance.DEFAULT_PROJECT_NAME));
     }
 
 }