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); + } }