From 93ea59a54b05460e591238905c654f1c06c78516 Mon Sep 17 00:00:00 2001 From: tjq Date: Tue, 5 Sep 2023 22:48:02 +0800 Subject: [PATCH] feat: dev NewSystemInitializer --- .../tech/powerjob/server/auth/Permission.java | 4 + .../dp/ModifyOrCreateDynamicPermission.java | 30 ++++- .../auth/service/PowerJobAuthServiceImpl.java | 3 + .../repository/NamespaceRepository.java | 4 + .../initializer/NewSystemInitializer.java | 123 ++++++++++++++++++ 5 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/initializer/NewSystemInitializer.java diff --git a/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/Permission.java b/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/Permission.java index b59c8e69..2098e2db 100644 --- a/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/Permission.java +++ b/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/Permission.java @@ -13,6 +13,10 @@ import lombok.Getter; @AllArgsConstructor public enum Permission { + /** + * 不需要权限 + */ + NONE(1), /** * 读权限,查看控制台数据 */ diff --git a/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/interceptor/dp/ModifyOrCreateDynamicPermission.java b/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/interceptor/dp/ModifyOrCreateDynamicPermission.java index 93da4daf..99afd84d 100644 --- a/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/interceptor/dp/ModifyOrCreateDynamicPermission.java +++ b/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/interceptor/dp/ModifyOrCreateDynamicPermission.java @@ -1,19 +1,45 @@ package tech.powerjob.server.auth.interceptor.dp; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.StreamUtils; +import tech.powerjob.common.serialize.JsonUtils; import tech.powerjob.server.auth.Permission; import javax.servlet.http.HttpServletRequest; +import java.util.Map; /** + * 针对 namespace 和 app 两大鉴权纬度,创建不需要任何权限,但任何修改操作都需要 WRITE 权限 * 创建不需要权限,修改需要校验权限 * * @author tjq * @since 2023/9/3 */ +@Slf4j public class ModifyOrCreateDynamicPermission implements DynamicPermission { @Override public Permission calculate(HttpServletRequest request, Object handler) { - // TODO: 动态权限判断,新建不需要权限 - return Permission.WRITE; + + try { + //获取请求body + byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream()); + String body = new String(bodyBytes, request.getCharacterEncoding()); + + Map inputParams = JsonUtils.parseMap(body); + + Object id = inputParams.get("id"); + + // 创建,不需要权限 + if (id == null) { + return Permission.NONE; + } + + return Permission.WRITE; + } catch (Exception e) { + log.error("[ModifyOrCreateDynamicPermission] check permission failed, please fix the bug!!!"); + } + + // 异常情况先放行,不影响功能使用,后续修复 BUG + return Permission.NONE; } } diff --git a/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/service/PowerJobAuthServiceImpl.java b/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/service/PowerJobAuthServiceImpl.java index ed28829c..f1b0dbe1 100644 --- a/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/service/PowerJobAuthServiceImpl.java +++ b/powerjob-server/powerjob-server-auth/src/main/java/tech/powerjob/server/auth/service/PowerJobAuthServiceImpl.java @@ -146,6 +146,9 @@ public class PowerJobAuthServiceImpl implements PowerJobAuthService { Long appId = Long.valueOf(appIdStr); final Permission requiredPermission = parsePermission(request, handler, apiPermission); + if (requiredPermission == Permission.NONE) { + return true; + } final Collection appRoles = appId2Role.get(appId); for (Role role : appRoles) { diff --git a/powerjob-server/powerjob-server-persistence/src/main/java/tech/powerjob/server/persistence/remote/repository/NamespaceRepository.java b/powerjob-server/powerjob-server-persistence/src/main/java/tech/powerjob/server/persistence/remote/repository/NamespaceRepository.java index bf4956fd..845f8fca 100644 --- a/powerjob-server/powerjob-server-persistence/src/main/java/tech/powerjob/server/persistence/remote/repository/NamespaceRepository.java +++ b/powerjob-server/powerjob-server-persistence/src/main/java/tech/powerjob/server/persistence/remote/repository/NamespaceRepository.java @@ -3,6 +3,8 @@ package tech.powerjob.server.persistence.remote.repository; import org.springframework.data.jpa.repository.JpaRepository; import tech.powerjob.server.persistence.remote.model.NamespaceDO; +import java.util.Optional; + /** * 命名空间 * @@ -10,4 +12,6 @@ import tech.powerjob.server.persistence.remote.model.NamespaceDO; * @since 2023/9/3 */ public interface NamespaceRepository extends JpaRepository { + + Optional findByCode(String code); } diff --git a/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/initializer/NewSystemInitializer.java b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/initializer/NewSystemInitializer.java new file mode 100644 index 00000000..797e9a77 --- /dev/null +++ b/powerjob-server/powerjob-server-starter/src/main/java/tech/powerjob/server/initializer/NewSystemInitializer.java @@ -0,0 +1,123 @@ +package tech.powerjob.server.initializer; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; +import tech.powerjob.common.utils.CommonUtils; +import tech.powerjob.server.common.constants.SwitchableStatus; +import tech.powerjob.server.extension.LockService; +import tech.powerjob.server.persistence.remote.model.NamespaceDO; +import tech.powerjob.server.persistence.remote.model.UserInfoDO; +import tech.powerjob.server.persistence.remote.repository.NamespaceRepository; +import tech.powerjob.server.persistence.remote.repository.UserInfoRepository; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * 新系统初始化器 + * + * @author tjq + * @since 2023/9/5 + */ +@Slf4j +@Component +public class NewSystemInitializer implements CommandLineRunner { + + private static final String SYSTEM_ADMIN_NAME = "ADMIN"; + private static final String SYSTEM_ADMIN_PASSWORD = "POWERJOB123456789"; + + private static final String SYSTEM_DEFAULT_NAMESPACE = "default_namespace"; + + private static final String LOCK_PREFIX = "sys_init_lock_"; + + private static final int MAX_LOCK_TIME = 5000; + + @Resource + private LockService lockService; + @Resource + private UserInfoRepository userInfoRepository; + @Resource + private NamespaceRepository namespaceRepository; + + @Override + public void run(String... args) throws Exception { + initSystemAdmin(); + initDefaultNamespace(); + } + + private void initSystemAdmin() { + clusterInit("admin", () -> { + Optional systemAdminUserOpt = userInfoRepository.findByUsername(SYSTEM_ADMIN_NAME); + return systemAdminUserOpt.isPresent(); + }, Void -> { + + UserInfoDO userInfoDO = new UserInfoDO(); + userInfoDO.setUsername(SYSTEM_ADMIN_NAME); + userInfoDO.setNick(SYSTEM_ADMIN_NAME); + userInfoDO.setPassword(SYSTEM_ADMIN_PASSWORD); + userInfoDO.setGmtCreate(new Date()); + userInfoDO.setGmtModified(new Date()); + + userInfoRepository.saveAndFlush(userInfoDO); + + log.info("[NewSystemInitializer] initSystemAdmin successfully!"); + + // 循环10遍,强提醒用户,第一次使用必须更改 admin 密码 + for (int i = 0; i < 10; i++) { + log.warn("The system has automatically created a super administrator account[username={},password={}], please log in and change the password immediately!", SYSTEM_ADMIN_NAME, SYSTEM_ADMIN_PASSWORD); + } + }); + } + + private void initDefaultNamespace() { + clusterInit("namespace", () -> { + Optional namespaceOpt = namespaceRepository.findByCode(SYSTEM_DEFAULT_NAMESPACE); + return namespaceOpt.isPresent(); + }, Void -> { + NamespaceDO namespaceDO = new NamespaceDO(); + namespaceDO.setCode(SYSTEM_DEFAULT_NAMESPACE); + namespaceDO.setName(SYSTEM_DEFAULT_NAMESPACE); + namespaceDO.setStatus(SwitchableStatus.ENABLE.getV()); + + namespaceRepository.saveAndFlush(namespaceDO); + + log.info("[NewSystemInitializer] initDefaultNamespace successfully!"); + }); + } + + private void clusterInit(String name, Supplier initialized, Consumer initFunc) { + + if (initialized.get()) { + return; + } + + String lockName = LOCK_PREFIX.concat(name); + lockService.tryLock(lockName, MAX_LOCK_TIME); + + while (true) { + boolean lockStatus = lockService.tryLock(lockName, MAX_LOCK_TIME); + if (!lockStatus) { + CommonUtils.easySleep(277); + continue; + } + + try { + if (initialized.get()) { + return; + } + + log.info("[NewSystemInitializer] try to initialize: {}", name); + initFunc.accept(null); + log.info("[NewSystemInitializer] initialize [{}] successfully!", name); + return; + } finally { + lockService.unlock(lockName); + } + } + + } +}