feat: dev NewSystemInitializer

This commit is contained in:
tjq 2023-09-05 22:48:02 +08:00
parent 0da830a6bc
commit 93ea59a54b
5 changed files with 162 additions and 2 deletions

View File

@ -13,6 +13,10 @@ import lombok.Getter;
@AllArgsConstructor
public enum Permission {
/**
* 不需要权限
*/
NONE(1),
/**
* 读权限查看控制台数据
*/

View File

@ -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: 动态权限判断新建不需要权限
try {
//获取请求body
byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream());
String body = new String(bodyBytes, request.getCharacterEncoding());
Map<String, Object> 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;
}
}

View File

@ -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<Role> appRoles = appId2Role.get(appId);
for (Role role : appRoles) {

View File

@ -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<NamespaceDO, Long> {
Optional<NamespaceDO> findByCode(String code);
}

View File

@ -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<UserInfoDO> 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<NamespaceDO> 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<Boolean> initialized, Consumer<Void> 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);
}
}
}
}