From a750d0c55c38c051b535a3d79e68451ff00f70c9 Mon Sep 17 00:00:00 2001 From: tjq Date: Sun, 18 Feb 2024 19:56:51 +0800 Subject: [PATCH] feat: support user become app admin by username and passwor --- .../server/auth/service/WebAuthService.java | 9 ++++++ .../auth/service/impl/WebAuthServiceImpl.java | 9 ++++++ .../web/controller/AppInfoController.java | 28 ++++++++++++++++++- .../server/web/controller/AuthController.java | 4 +-- .../web/service/impl/UserWebServiceImpl.java | 27 ++++++++++++++++-- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/WebAuthService.java b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/WebAuthService.java index a2b8d7a8..f579ea19 100644 --- a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/WebAuthService.java +++ b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/WebAuthService.java @@ -18,6 +18,15 @@ import java.util.Map; */ public interface WebAuthService { + /** + * 对当前登录用户授予角色 + * @param roleScope 角色范围 + * @param target 目标 + * @param role 角色 + * @param extra 其他信息 + */ + void grantRole2LoginUser(RoleScope roleScope, Long target, Role role, String extra); + /** * 处理授权 * @param roleScope 权限范围 diff --git a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/impl/WebAuthServiceImpl.java b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/impl/WebAuthServiceImpl.java index e70aa043..9804f4f3 100644 --- a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/impl/WebAuthServiceImpl.java +++ b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/auth/service/impl/WebAuthServiceImpl.java @@ -29,6 +29,15 @@ public class WebAuthServiceImpl implements WebAuthService { private PowerJobPermissionService powerJobPermissionService; + @Override + public void grantRole2LoginUser(RoleScope roleScope, Long target, Role role, String extra) { + Long userId = LoginUserHolder.getUserId(); + if (userId == null) { + throw new PowerJobAuthException(AuthErrorCode.USER_NOT_LOGIN); + } + powerJobPermissionService.grantRole(roleScope, target, userId, role, extra); + } + @Override public void processPermissionOnSave(RoleScope roleScope, Long target, ComponentUserRoleInfo o) { ComponentUserRoleInfo componentUserRoleInfo = Optional.ofNullable(o).orElse(new ComponentUserRoleInfo()); diff --git a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AppInfoController.java b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AppInfoController.java index 435eed93..7d2c8ecc 100644 --- a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AppInfoController.java +++ b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AppInfoController.java @@ -1,6 +1,7 @@ package tech.powerjob.server.web.controller; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.BooleanUtils; @@ -13,11 +14,15 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import tech.powerjob.common.response.ResultDTO; +import tech.powerjob.common.serialize.JsonUtils; import tech.powerjob.common.utils.CommonUtils; import tech.powerjob.server.auth.LoginUserHolder; import tech.powerjob.server.auth.Permission; +import tech.powerjob.server.auth.Role; import tech.powerjob.server.auth.RoleScope; import tech.powerjob.server.auth.common.AuthConstants; +import tech.powerjob.server.auth.common.AuthErrorCode; +import tech.powerjob.server.auth.common.PowerJobAuthException; import tech.powerjob.server.auth.interceptor.ApiPermission; import tech.powerjob.server.auth.plugin.ModifyOrCreateDynamicPermission; import tech.powerjob.server.auth.plugin.SaveAppGrantPermissionPlugin; @@ -28,6 +33,7 @@ import tech.powerjob.server.persistence.remote.model.AppInfoDO; import tech.powerjob.server.persistence.remote.model.NamespaceDO; import tech.powerjob.server.persistence.remote.repository.AppInfoRepository; import tech.powerjob.server.web.converter.NamespaceConverter; +import tech.powerjob.server.web.request.AppAssertRequest; import tech.powerjob.server.web.request.ComponentUserRoleInfo; import tech.powerjob.server.web.request.ModifyAppInfoRequest; import tech.powerjob.server.web.request.QueryAppInfoRequest; @@ -108,7 +114,7 @@ public class AppInfoController { } @PostMapping("/list") - @ApiPermission(name = "Namespace-List", roleScope = RoleScope.APP, requiredPermission = Permission.NONE) + @ApiPermission(name = "App-List", roleScope = RoleScope.APP, requiredPermission = Permission.NONE) public ResultDTO> listAppInfoByQuery(@RequestBody QueryAppInfoRequest queryAppInfoRequest) { Pageable pageable = PageRequest.of(queryAppInfoRequest.getIndex(), queryAppInfoRequest.getPageSize()); @@ -163,6 +169,26 @@ public class AppInfoController { return ResultDTO.success(pageRet); } + @PostMapping("/becomeAdmin") + @ApiPermission(name = "App-BecomeAdmin", roleScope = RoleScope.GLOBAL, requiredPermission = Permission.NONE) + public ResultDTO becomeAdminByAppNameAndPassword(@RequestBody AppAssertRequest appAssertRequest) { + String appName = appAssertRequest.getAppName(); + Optional appInfoOpt = appInfoRepository.findByAppName(appName); + if (!appInfoOpt.isPresent()) { + throw new IllegalArgumentException("can't find app by appName: " + appName); + } + if (!StringUtils.equals(appInfoOpt.get().getPassword(), appAssertRequest.getPassword())) { + throw new PowerJobAuthException(AuthErrorCode.INCORRECT_PASSWORD); + } + + Map extra = Maps.newHashMap(); + extra.put("source", "becomeAdminByAppNameAndPassword"); + + webAuthService.grantRole2LoginUser(RoleScope.APP, appInfoOpt.get().getId(), Role.ADMIN, JsonUtils.toJSONString(extra)); + + return ResultDTO.success(null); + } + private List convert(List data, boolean fillDetail) { if (CollectionUtils.isEmpty(data)) { return Lists.newLinkedList(); diff --git a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AuthController.java b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AuthController.java index dc7e0d6f..b9198764 100644 --- a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AuthController.java +++ b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/controller/AuthController.java @@ -105,8 +105,8 @@ public class AuthController { } @PostMapping("/saveGlobalAdmin") - @ApiPermission(name = "Auth-GrantAdmin", roleScope = RoleScope.GLOBAL, requiredPermission = Permission.SU) - public ResultDTO grantAppPermission(@RequestBody ComponentUserRoleInfo componentUserRoleInfo) { + @ApiPermission(name = "Auth-SaveGlobalAdmin", roleScope = RoleScope.GLOBAL, requiredPermission = Permission.SU) + public ResultDTO saveGlobalAdmin(@RequestBody ComponentUserRoleInfo componentUserRoleInfo) { if (CollectionUtils.isEmpty(componentUserRoleInfo.getAdmin())) { throw new IllegalArgumentException("At least one super administrator is required!"); diff --git a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/service/impl/UserWebServiceImpl.java b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/service/impl/UserWebServiceImpl.java index 2806ecd2..fd44bce3 100644 --- a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/service/impl/UserWebServiceImpl.java +++ b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/web/service/impl/UserWebServiceImpl.java @@ -1,5 +1,7 @@ package tech.powerjob.server.web.service.impl; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import org.springframework.stereotype.Service; import tech.powerjob.server.persistence.remote.model.UserInfoDO; import tech.powerjob.server.persistence.remote.repository.UserInfoRepository; @@ -9,6 +11,7 @@ import tech.powerjob.server.web.service.UserWebService; import javax.annotation.Resource; import java.util.Optional; +import java.util.concurrent.TimeUnit; /** * UserWebService @@ -19,6 +22,15 @@ import java.util.Optional; @Service public class UserWebServiceImpl implements UserWebService { + /** + * 展示用的 user 查询缓存,对延迟不敏感 + */ + private final Cache userCache4Show = CacheBuilder.newBuilder() + .softValues() + .maximumSize(256) + .expireAfterWrite(3, TimeUnit.MINUTES) + .build(); + @Resource private UserInfoRepository userInfoRepository; @@ -29,7 +41,18 @@ public class UserWebServiceImpl implements UserWebService { return Optional.empty(); } - Optional userInfoOpt = userInfoRepository.findById(userId); - return userInfoOpt.map(UserConverter::do2BaseVo); + try { + UserInfoDO userInfoDO = userCache4Show.get(userId, () -> { + Optional userInfoOpt = userInfoRepository.findById(userId); + if (userInfoOpt.isPresent()) { + return userInfoOpt.get(); + } + throw new IllegalArgumentException("can't find user by userId: " + userId); + }); + + return Optional.of(UserConverter.do2BaseVo(userInfoDO)); + } catch (Exception e) { + return Optional.empty(); + } } }