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

nju_yaho pushed a commit to tag ebay-3.1.0-release-20200701
in repository https://gitbox.apache.org/repos/asf/kylin.git

commit 2a7cb7b1024452b87a2d9b000e3a93c711c2949d
Author: Zhong, Yanghong <nju_y...@apache.org>
AuthorDate: Fri Jun 19 17:47:50 2020 +0800

    KYLIN-4588 Add a rest API to get project list for a user able to access
---
 .../kylin/rest/controller/ProjectController.java   | 30 ++++++++++++++++++++++
 .../apache/kylin/rest/service/AccessService.java   | 12 +++++++++
 2 files changed, 42 insertions(+)

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 410ff11..7edca34 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
@@ -36,10 +36,14 @@ import org.apache.kylin.rest.service.CubeService;
 import org.apache.kylin.rest.service.ProjectService;
 import org.apache.kylin.rest.util.AclEvaluate;
 import org.apache.kylin.rest.util.ValidateUtil;
+import org.apache.kylin.shaded.com.google.common.collect.Lists;
 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.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -118,6 +122,32 @@ public class ProjectController extends BasicController {
         return readableProjects.subList(projectOffset, projectOffset + 
projectLimit);
     }
 
+    @RequestMapping(value = "/readable/user/{userName}", method = { 
RequestMethod.GET }, produces = {
+            "application/json" })
+    @ResponseBody
+    public List<ProjectInstance> getReadableProjects(@PathVariable String 
userName,
+            @RequestParam(value = "limit", required = false) Integer limit,
+            @RequestParam(value = "offset", required = false) Integer offset) {
+        Authentication origAuth = 
SecurityContextHolder.getContext().getAuthentication();
+
+        logger.info("Going to impersonate to user {} from {}", userName, 
origAuth.getName());
+
+        try {
+            accessService.switchToUser(userName);
+            return getReadableProjects(limit, offset);
+        } catch (UsernameNotFoundException e) {
+            logger.warn("User {} does not exist in system", userName);
+            return Lists.newArrayList();
+        } catch (InternalErrorException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new InternalErrorException(e);
+        } finally {
+            SecurityContextHolder.getContext().setAuthentication(origAuth);
+            logger.info("Recover to the origin user {} from impersonated one 
{}", origAuth.getName(), userName);
+        }
+    }
+
     @RequestMapping(value = "", method = { RequestMethod.POST }, produces = { 
"application/json" })
     @ResponseBody
     public ProjectInstance saveProject(@RequestBody ProjectRequest 
projectRequest) {
diff --git 
a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java 
b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
index 5b7d562..62c7b71 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/service/AccessService.java
@@ -58,9 +58,11 @@ import 
org.springframework.security.acls.model.NotFoundException;
 import org.springframework.security.acls.model.ObjectIdentity;
 import org.springframework.security.acls.model.Permission;
 import org.springframework.security.acls.model.Sid;
+import 
org.springframework.security.authentication.AnonymousAuthenticationToken;
 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 org.springframework.transaction.annotation.Transactional;
 
@@ -75,6 +77,10 @@ public class AccessService {
     @Qualifier("aclService")
     private AclService aclService;
 
+    @Autowired
+    @Qualifier("userService")
+    UserService userService;
+    
     // ~ Methods to manage acl life circle of domain objects ~
 
     @Transactional
@@ -481,4 +487,10 @@ public class AccessService {
         }
         return null;
     }
+
+    public void switchToUser(String user) {
+        UserDetails userDetails = userService.loadUserByUsername(user);
+        Authentication userAuth = new AnonymousAuthenticationToken(user, 
userDetails, userDetails.getAuthorities());
+        SecurityContextHolder.getContext().setAuthentication(userAuth);
+    }
 }

Reply via email to