Repository: kylin
Updated Branches:
  refs/heads/master 2d11fbcea -> 85b4b2c7c


KYLIN-2563 Fix bug in query authorization


Project: http://git-wip-us.apache.org/repos/asf/kylin/repo
Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/85b4b2c7
Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/85b4b2c7
Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/85b4b2c7

Branch: refs/heads/master
Commit: 85b4b2c7c0dc7d2052cd92cc50ac3b6b94f88668
Parents: 2d11fbc
Author: kangkaisen <[email protected]>
Authored: Fri Apr 21 17:10:19 2017 +0800
Committer: kangkaisen <[email protected]>
Committed: Wed Apr 26 18:35:17 2017 +0800

----------------------------------------------------------------------
 .../rest/controller/ProjectController.java      |  59 ++--------
 .../apache/kylin/rest/service/QueryService.java |   9 +-
 .../org/apache/kylin/rest/util/AclUtil.java     | 116 +++++++++++++++++++
 3 files changed, 134 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kylin/blob/85b4b2c7/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
----------------------------------------------------------------------
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
 
b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
index a6edece..40e798a 100644
--- 
a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
+++ 
b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
@@ -34,6 +34,7 @@ import org.apache.kylin.rest.request.ProjectRequest;
 import org.apache.kylin.rest.service.AccessService;
 import org.apache.kylin.rest.service.CubeService;
 import org.apache.kylin.rest.service.ProjectService;
+import org.apache.kylin.rest.util.AclUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,9 +42,6 @@ import 
org.springframework.security.acls.domain.GrantedAuthoritySid;
 import org.springframework.security.acls.domain.PrincipalSid;
 import org.springframework.security.acls.model.AccessControlEntry;
 import org.springframework.security.acls.model.Acl;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -69,6 +67,8 @@ public class ProjectController extends BasicController {
     private AccessService accessService;
     @Autowired
     private CubeService cubeService;
+    @Autowired
+    private AclUtil aclUtil;
 
     /**
      * Get available project list
@@ -90,29 +90,16 @@ public class ProjectController extends BasicController {
         List<ProjectInstance> projectInstances = 
projectService.listAllProjects(limit, offset);
 
         //get user infomation
-        Authentication authentication = 
SecurityContextHolder.getContext().getAuthentication();
-        UserDetails userDetails = null;
-        if (authentication == null) {
-            logger.debug("authentication is null.");
-            throw new InternalErrorException("Can not find authentication 
infomation.");
-        }
-        if (authentication.getPrincipal() instanceof UserDetails) {
-            logger.debug("authentication.getPrincipal() is " + 
authentication.getPrincipal());
-            userDetails = (UserDetails) authentication.getPrincipal();
-        }
-        if (authentication.getDetails() instanceof UserDetails) {
-            logger.debug("authentication.getDetails() is " + 
authentication.getDetails());
-            userDetails = (UserDetails) authentication.getDetails();
-        }
+        UserDetails userDetails = aclUtil.getCurrentUser();
+        String userName = userDetails.getUsername();
 
         //check if ROLE_ADMIN return all,also get user role list
-        List<String> userAuthority = new ArrayList<>();
-        for (GrantedAuthority auth : authentication.getAuthorities()) {
-            userAuthority.add(auth.getAuthority());
-            if (auth.getAuthority().equals(Constant.ROLE_ADMIN))
+        List<String> userAuthority = aclUtil.getAuthorityList();
+        for (String auth : userAuthority) {
+            if (auth.equals(Constant.ROLE_ADMIN))
                 return projectInstances;
         }
-        String userName = userDetails.getUsername();
+
         for (ProjectInstance projectInstance : projectInstances) {
             if (projectInstance == null) {
                 continue;
@@ -157,32 +144,8 @@ public class ProjectController extends BasicController {
                     if (cubeInstance == null) {
                         continue;
                     }
-                    boolean hasCubePermission = false;
-                    AclEntity cubeAe = 
accessService.getAclEntity("CubeInstance", cubeInstance.getId());
-                    Acl cubeAcl = accessService.getAcl(cubeAe);
-                    //cube no Acl info will not be used to filter project
-                    if (cubeAcl != null) {
-                        //cube owner will have permission to read project
-                        if (((PrincipalSid) 
cubeAcl.getOwner()).getPrincipal().equals(userName)) {
-                            hasProjectPermission = true;
-                            break;
-                        }
-                        for (AccessControlEntry cubeAce : 
cubeAcl.getEntries()) {
-
-                            if (cubeAce.getSid() instanceof PrincipalSid && 
((PrincipalSid) cubeAce.getSid()).getPrincipal().equals(userName)) {
-                                hasCubePermission = true;
-                                break;
-                            } else if (cubeAce.getSid() instanceof 
GrantedAuthoritySid) {
-                                String cubeAuthority = ((GrantedAuthoritySid) 
cubeAce.getSid()).getGrantedAuthority();
-                                if (userAuthority.contains(cubeAuthority)) {
-                                    hasCubePermission = true;
-                                    break;
-                                }
-
-                            }
-                        }
-                    }
-                    if (hasCubePermission) {
+
+                    if (aclUtil.isHasCubePermission(cubeInstance)) {
                         hasProjectPermission = true;
                         break;
                     }

http://git-wip-us.apache.org/repos/asf/kylin/blob/85b4b2c7/server-base/src/main/java/org/apache/kylin/rest/service/QueryService.java
----------------------------------------------------------------------
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 6a38638..b526f96 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
@@ -76,6 +76,7 @@ import org.apache.kylin.rest.model.TableMeta;
 import org.apache.kylin.rest.request.PrepareSqlRequest;
 import org.apache.kylin.rest.request.SQLRequest;
 import org.apache.kylin.rest.response.SQLResponse;
+import org.apache.kylin.rest.util.AclUtil;
 import org.apache.kylin.rest.util.QueryUtil;
 import org.apache.kylin.rest.util.Serializer;
 import org.apache.kylin.rest.util.TableauInterceptor;
@@ -85,7 +86,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
@@ -124,6 +124,9 @@ public class QueryService extends BasicService {
     @Autowired
     private CacheService cacheService;
 
+    @Autowired
+    private AclUtil aclUtil;
+
     @PostConstruct
     public void init() throws IOException {
         Preconditions.checkNotNull(cacheManager, "cacheManager is not injected 
yet");
@@ -298,8 +301,10 @@ public class QueryService extends BasicService {
         checkCubeAuthorization(cubeInstance);
     }
 
-    @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#cube, 
'ADMINISTRATION') or hasPermission(#cube, 'MANAGEMENT')" + " or 
hasPermission(#cube, 'OPERATION') or hasPermission(#cube, 'READ')")
     private void checkCubeAuthorization(CubeInstance cube) throws 
AccessDeniedException {
+        if (!aclUtil.isHasCubePermission(cube)) {
+            throw new AccessDeniedException("Access denied");
+        }
     }
 
     private void checkHybridAuthorization(HybridInstance hybridInstance) 
throws AccessDeniedException {

http://git-wip-us.apache.org/repos/asf/kylin/blob/85b4b2c7/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
new file mode 100644
index 0000000..440b2f9
--- /dev/null
+++ b/server-base/src/main/java/org/apache/kylin/rest/util/AclUtil.java
@@ -0,0 +1,116 @@
+/*
+ * 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.persistence.AclEntity;
+import org.apache.kylin.cube.CubeInstance;
+import org.apache.kylin.rest.constant.Constant;
+import org.apache.kylin.rest.exception.InternalErrorException;
+import org.apache.kylin.rest.service.AccessService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.acls.domain.GrantedAuthoritySid;
+import org.springframework.security.acls.domain.PrincipalSid;
+import org.springframework.security.acls.model.AccessControlEntry;
+import org.springframework.security.acls.model.Acl;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component("aclUtil")
+public class AclUtil {
+    private static final Logger logger = 
LoggerFactory.getLogger(AclUtil.class);
+
+    @Autowired
+    private AccessService accessService;
+
+    /**
+     * @return <tt>true</tt> the current user has permission to query the 
cube, otherwise
+     * <tt>false</tt>
+     */
+    public boolean isHasCubePermission(CubeInstance cube) {
+        boolean hasCubePermission = false;
+        String userName = getCurrentUser().getUsername();
+        List<String> userAuthority = getAuthorityList();
+
+        //check if ROLE_ADMIN
+        for (String auth : userAuthority) {
+            if (auth.equals(Constant.ROLE_ADMIN)) {
+                return true;
+            }
+        }
+
+        AclEntity cubeAe = accessService.getAclEntity("CubeInstance", 
cube.getId());
+        Acl cubeAcl = accessService.getAcl(cubeAe);
+        //cube Acl info
+        if (cubeAcl != null) {
+            if (((PrincipalSid) 
cubeAcl.getOwner()).getPrincipal().equals(userName)) {
+                hasCubePermission = true;
+            }
+
+            for (AccessControlEntry cubeAce : cubeAcl.getEntries()) {
+                if (cubeAce.getSid() instanceof PrincipalSid && 
((PrincipalSid) cubeAce.getSid()).getPrincipal().equals(userName)) {
+                    hasCubePermission = true;
+                    break;
+                } else if (cubeAce.getSid() instanceof GrantedAuthoritySid) {
+                    String cubeAuthority = ((GrantedAuthoritySid) 
cubeAce.getSid()).getGrantedAuthority();
+                    if (userAuthority.contains(cubeAuthority)) {
+                        hasCubePermission = true;
+                        break;
+                    }
+
+                }
+            }
+        }
+        return hasCubePermission;
+    }
+
+    public UserDetails getCurrentUser() {
+        Authentication authentication = 
SecurityContextHolder.getContext().getAuthentication();
+        UserDetails userDetails = null;
+        if (authentication == null) {
+            logger.debug("authentication is null.");
+            throw new InternalErrorException("Can not find authentication 
infomation.");
+        }
+        if (authentication.getPrincipal() instanceof UserDetails) {
+            logger.debug("authentication.getPrincipal() is " + 
authentication.getPrincipal());
+            userDetails = (UserDetails) authentication.getPrincipal();
+        }
+        if (authentication.getDetails() instanceof UserDetails) {
+            logger.debug("authentication.getDetails() is " + 
authentication.getDetails());
+            userDetails = (UserDetails) authentication.getDetails();
+        }
+        return userDetails;
+    }
+
+    public List<String> getAuthorityList() {
+        Authentication authentication = 
SecurityContextHolder.getContext().getAuthentication();
+        List<String> userAuthority = new ArrayList<>();
+        for (GrantedAuthority auth : authentication.getAuthorities()) {
+            userAuthority.add(auth.getAuthority());
+        }
+        return userAuthority;
+    }
+}

Reply via email to