mirror of https://gitee.com/topiam/eiam
🏗️ 初始化逻辑调整
parent
f044f4e2ad
commit
2c4a946cda
|
@ -22,31 +22,24 @@ import java.io.File;
|
|||
import java.io.FileWriter;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import cn.topiam.employee.common.entity.account.OrganizationMemberEntity;
|
||||
import cn.topiam.employee.common.entity.setting.AdministratorEntity;
|
||||
import cn.topiam.employee.common.enums.UserStatus;
|
||||
import cn.topiam.employee.common.repository.account.OrganizationMemberRepository;
|
||||
import cn.topiam.employee.common.repository.setting.AdministratorRepository;
|
||||
import cn.topiam.employee.support.init.Initializer;
|
||||
import cn.topiam.employee.support.trace.TraceUtils;
|
||||
import cn.topiam.employee.support.config.AbstractSystemInitializer;
|
||||
import cn.topiam.employee.support.config.InitializationException;
|
||||
import static cn.topiam.employee.support.constant.EiamConstants.DEFAULT_ADMIN_USERNAME;
|
||||
import static cn.topiam.employee.support.constant.EiamConstants.TOPIAM_INIT_AUTHENTICATION;
|
||||
import static cn.topiam.employee.support.lock.LockAspect.getTopiamLockKeyPrefix;
|
||||
import static cn.topiam.employee.support.util.CreateFileUtil.createFile;
|
||||
import static cn.topiam.employee.support.constant.EiamConstants.ROOT_NODE;
|
||||
|
||||
/**
|
||||
* DefaultAdministratorInitialize
|
||||
|
@ -54,9 +47,8 @@ import static cn.topiam.employee.support.util.CreateFileUtil.createFile;
|
|||
* @author TopIAM
|
||||
* Created by support@topiam.cn on 2022/11/26 21:44
|
||||
*/
|
||||
@Order(2)
|
||||
@Component
|
||||
public class DefaultAdministratorInitializer implements Initializer {
|
||||
public class DefaultAdministratorInitializer extends AbstractSystemInitializer {
|
||||
|
||||
private final Logger logger = LoggerFactory
|
||||
.getLogger(DefaultAdministratorInitializer.class);
|
||||
|
@ -68,48 +60,43 @@ public class DefaultAdministratorInitializer implements Initializer {
|
|||
private static final String INITIAL_PASSWORD_DEFAULT = "topiam.cn";
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void execute(ApplicationContext applicationContext) {
|
||||
//@formatter:off
|
||||
String traceId = idGenerator.generateId().toString();
|
||||
TraceUtils.put(traceId);
|
||||
RLock lock = redissonClient.getLock(getTopiamLockKeyPrefix());
|
||||
boolean tryLock = false;
|
||||
public void init() throws InitializationException {
|
||||
try {
|
||||
SecurityContextHolder.getContext().setAuthentication(TOPIAM_INIT_AUTHENTICATION);
|
||||
tryLock = lock.tryLock(1, TimeUnit.SECONDS);
|
||||
if (tryLock){
|
||||
Optional<AdministratorEntity> optional = administratorRepository.findByUsername(DEFAULT_ADMIN_USERNAME);
|
||||
Optional<AdministratorEntity> optional = administratorRepository
|
||||
.findByUsername(DEFAULT_ADMIN_USERNAME);
|
||||
if (optional.isEmpty()) {
|
||||
String initPassword;
|
||||
String initPasswordFileTips;
|
||||
String passwordType = System.getProperty(INITIAL_PASSWORD_TYPE_NAME);
|
||||
if (StringUtils.hasText(passwordType) && "generate".equals(passwordType)) {
|
||||
initPassword = idGenerator.generateId().toString().replace("-", "").toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
else {
|
||||
initPassword = idGenerator.generateId().toString().replace("-", "")
|
||||
.toLowerCase(Locale.ENGLISH);
|
||||
} else {
|
||||
String passwordInitial = System.getProperty(INITIAL_PASSWORD_VALUE_NAME);
|
||||
if (StringUtils.hasText(passwordInitial)) {
|
||||
initPassword = passwordInitial;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
initPassword = INITIAL_PASSWORD_DEFAULT;
|
||||
}
|
||||
}
|
||||
String initialAdminPasswordFilePath = getInitialAdminPasswordFilePath();createFile(initialAdminPasswordFilePath);
|
||||
BufferedWriter stream = new BufferedWriter(new FileWriter(initialAdminPasswordFilePath));
|
||||
String initialAdminPasswordFilePath = getInitialAdminPasswordFilePath();
|
||||
FileUtils.writeStringToFile(new File(initialAdminPasswordFilePath), initPassword,
|
||||
"UTF-8");
|
||||
BufferedWriter stream = new BufferedWriter(
|
||||
new FileWriter(initialAdminPasswordFilePath));
|
||||
initPasswordFileTips = "This may also be found at: " + initialAdminPasswordFilePath;
|
||||
//清空
|
||||
stream.write(initPassword);
|
||||
stream.flush();
|
||||
stream.close();
|
||||
logger.info("""
|
||||
logger.info(
|
||||
"""
|
||||
|
||||
*************************************************************
|
||||
*************************************************************
|
||||
*************************************************************
|
||||
|
||||
TOPIAM console initial setup is required. An admin user has been created and a initialize password.
|
||||
TOPIAM console initial setup is required. An admin administrator has been created and a initialize password.
|
||||
Please use the following password to proceed to installation:
|
||||
|
||||
%s
|
||||
|
@ -119,42 +106,26 @@ public class DefaultAdministratorInitializer implements Initializer {
|
|||
*************************************************************
|
||||
*************************************************************
|
||||
|
||||
""".formatted(initPassword, initPasswordFileTips));
|
||||
"""
|
||||
.formatted(initPassword, initPasswordFileTips));
|
||||
//保存管理员
|
||||
saveInitAdministrator(DEFAULT_ADMIN_USERNAME, initPassword);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception exception) {
|
||||
int exitCode = SpringApplication.exit(applicationContext,
|
||||
() -> 0);
|
||||
System.exit(exitCode);
|
||||
} finally {
|
||||
if (tryLock && lock.isLocked()) {
|
||||
lock.unlock();
|
||||
}
|
||||
TraceUtils.remove();
|
||||
SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());
|
||||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存管理员
|
||||
*
|
||||
* @param username {@link String}
|
||||
* @param password {@link String}
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveInitAdministrator(String username, String password) {
|
||||
AdministratorEntity administrator = new AdministratorEntity();
|
||||
administrator.setUsername(username);
|
||||
administrator.setPassword(passwordEncoder.encode(password));
|
||||
administrator.setUsername(DEFAULT_ADMIN_USERNAME);
|
||||
administrator.setFullName("管理员");
|
||||
administrator.setPassword(passwordEncoder.encode(initPassword));
|
||||
administrator.setStatus(UserStatus.ENABLED);
|
||||
administrator.setNeedChangePassword(true);
|
||||
administrator.setRemark(
|
||||
"This administrator user is automatically created during system initialization.");
|
||||
"This administrator is automatically created during system initialization.");
|
||||
administratorRepository.save(administrator);
|
||||
OrganizationMemberEntity member = new OrganizationMemberEntity();
|
||||
member.setOrgId(ROOT_NODE);
|
||||
member.setUserId(administrator.getId());
|
||||
organizationMemberRepository.save(member);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new InitializationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String addSeparator(String dir) {
|
||||
|
@ -175,20 +146,24 @@ public class DefaultAdministratorInitializer implements Initializer {
|
|||
return path + "initialAdminPassword";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
private final AlternativeJdkIdGenerator idGenerator = new AlternativeJdkIdGenerator();
|
||||
|
||||
private final OrganizationMemberRepository organizationMemberRepository;
|
||||
|
||||
private final AdministratorRepository administratorRepository;
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
private final RedissonClient redissonClient;
|
||||
|
||||
public DefaultAdministratorInitializer(AdministratorRepository administratorRepository,
|
||||
PasswordEncoder passwordEncoder,
|
||||
RedissonClient redissonClient) {
|
||||
public DefaultAdministratorInitializer(OrganizationMemberRepository organizationMemberRepository,
|
||||
AdministratorRepository administratorRepository,
|
||||
PasswordEncoder passwordEncoder) {
|
||||
this.organizationMemberRepository = organizationMemberRepository;
|
||||
this.administratorRepository = administratorRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.redissonClient = redissonClient;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,26 +19,17 @@ package cn.topiam.employee.console.initializer;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
|
||||
import cn.topiam.employee.common.entity.app.AppGroupEntity;
|
||||
import cn.topiam.employee.common.enums.app.AppDefaultGroup;
|
||||
import cn.topiam.employee.common.enums.app.AppGroupType;
|
||||
import cn.topiam.employee.common.repository.app.AppGroupRepository;
|
||||
import cn.topiam.employee.support.init.Initializer;
|
||||
import cn.topiam.employee.support.trace.TraceUtils;
|
||||
import static cn.topiam.employee.support.constant.EiamConstants.TOPIAM_INIT_AUTHENTICATION;
|
||||
import static cn.topiam.employee.support.lock.LockAspect.getTopiamLockKeyPrefix;
|
||||
import cn.topiam.employee.support.config.AbstractSystemInitializer;
|
||||
import cn.topiam.employee.support.config.InitializationException;
|
||||
|
||||
/**
|
||||
* DefaultAppGroupInitialize
|
||||
|
@ -48,20 +39,12 @@ import static cn.topiam.employee.support.lock.LockAspect.getTopiamLockKeyPrefix;
|
|||
*/
|
||||
@Order(2)
|
||||
@Component
|
||||
public class DefaultAppGroupInitializer implements Initializer {
|
||||
public class DefaultAppGroupInitializer extends AbstractSystemInitializer {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void execute(ApplicationContext applicationContext) {
|
||||
public void init() throws InitializationException {
|
||||
//@formatter:off
|
||||
String traceId = idGenerator.generateId().toString();
|
||||
TraceUtils.put(traceId);
|
||||
RLock lock = redissonClient.getLock(getTopiamLockKeyPrefix());
|
||||
boolean tryLock = false;
|
||||
try {
|
||||
SecurityContextHolder.getContext().setAuthentication(TOPIAM_INIT_AUTHENTICATION);
|
||||
tryLock = lock.tryLock(1, TimeUnit.SECONDS);
|
||||
if (tryLock) {
|
||||
Arrays.stream(AppDefaultGroup.values()).toList().forEach(i -> {
|
||||
Optional<AppGroupEntity> optional = appGroupRepository.findByCode(i.getCode());
|
||||
if (optional.isEmpty()) {
|
||||
|
@ -74,33 +57,16 @@ public class DefaultAppGroupInitializer implements Initializer {
|
|||
appGroupRepository.save(appGroup);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception exception) {
|
||||
int exitCode = SpringApplication.exit(applicationContext,
|
||||
() -> 0);
|
||||
System.exit(exitCode);
|
||||
} finally {
|
||||
if (tryLock && lock.isLocked()) {
|
||||
lock.unlock();
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 4;
|
||||
}
|
||||
TraceUtils.remove();
|
||||
SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());
|
||||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
private final AlternativeJdkIdGenerator idGenerator = new AlternativeJdkIdGenerator();
|
||||
|
||||
private final AppGroupRepository appGroupRepository;
|
||||
|
||||
private final RedissonClient redissonClient;
|
||||
|
||||
public DefaultAppGroupInitializer(AppGroupRepository appGroupRepository,
|
||||
RedissonClient redissonClient) {
|
||||
public DefaultAppGroupInitializer(AppGroupRepository appGroupRepository) {
|
||||
this.appGroupRepository = appGroupRepository;
|
||||
this.redissonClient = redissonClient;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package cn.topiam.employee.console.initializer;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import cn.topiam.employee.common.entity.setting.SettingEntity;
|
||||
import cn.topiam.employee.common.repository.setting.SettingRepository;
|
||||
import cn.topiam.employee.support.config.AbstractSystemInitializer;
|
||||
import cn.topiam.employee.support.config.InitializationException;
|
||||
import cn.topiam.employee.support.util.AesUtils;
|
||||
import static cn.topiam.employee.common.constant.SettingConstants.AES_SECRET;
|
||||
|
||||
/**
|
||||
* EncryptSecretInitializer
|
||||
*
|
||||
* @author TopIAM
|
||||
* Created by support@topiam.cn on 2024/04/04 21:24
|
||||
*/
|
||||
@Component
|
||||
public class EncryptSecretInitializer extends AbstractSystemInitializer {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void init() throws InitializationException {
|
||||
SettingEntity optional = settingRepository.findByName(AES_SECRET);
|
||||
if (Objects.isNull(optional)) {
|
||||
SettingEntity setting = new SettingEntity();
|
||||
setting.setName(AES_SECRET);
|
||||
setting.setValue(AesUtils.generateKey());
|
||||
setting.setDesc("Project aes secret");
|
||||
setting.setRemark(
|
||||
"This aes secret is automatically created during system initialization.");
|
||||
settingRepository.save(setting);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* SettingRepository
|
||||
*/
|
||||
private final SettingRepository settingRepository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param settingRepository {@link SettingRepository}
|
||||
*/
|
||||
public EncryptSecretInitializer(SettingRepository settingRepository) {
|
||||
this.settingRepository = settingRepository;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package cn.topiam.employee.console.initializer;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import cn.topiam.employee.common.entity.setting.SettingEntity;
|
||||
import cn.topiam.employee.common.geo.GeoLocationProviderConfig;
|
||||
import cn.topiam.employee.common.jackjson.encrypt.EncryptionModule;
|
||||
import cn.topiam.employee.common.repository.setting.SettingRepository;
|
||||
import cn.topiam.employee.support.config.AbstractSystemInitializer;
|
||||
import cn.topiam.employee.support.config.InitializationException;
|
||||
import static cn.topiam.employee.common.geo.ip2region.Ip2regionGeoLocationParserImpl.IP2REGION;
|
||||
import static cn.topiam.employee.core.setting.GeoIpProviderConstants.IPADDRESS_SETTING_NAME;
|
||||
|
||||
/**
|
||||
* GeoIpProviderInitializer
|
||||
*
|
||||
* @author TOPIAM
|
||||
* Created by support@topiam.cn on 2024/11/3 18:11
|
||||
*/
|
||||
@Component
|
||||
public class GeoIpProviderInitializer extends AbstractSystemInitializer {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(GeoIpProviderInitializer.class);
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void init() throws InitializationException {
|
||||
//@formatter:off
|
||||
try {
|
||||
SettingEntity optional = settingRepository.findByName(IPADDRESS_SETTING_NAME);
|
||||
if (Objects.isNull(optional)) {
|
||||
logger.info("初始化系统默认IP地址提供商");
|
||||
SettingEntity setting = new SettingEntity();
|
||||
setting.setName(IPADDRESS_SETTING_NAME);
|
||||
ObjectMapper objectMapper = EncryptionModule.deserializerDecrypt();
|
||||
// 指定序列化输入的类型
|
||||
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
setting.setValue(objectMapper.writeValueAsString(new GeoLocationProviderConfig(IP2REGION, null)));
|
||||
setting.setDesc(IP2REGION.getName());
|
||||
setting.setRemark("The system initializes the default configuration.");
|
||||
settingRepository.save(setting);
|
||||
}
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new InitializationException(e);
|
||||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* SettingRepository
|
||||
*/
|
||||
private final SettingRepository settingRepository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param settingRepository {@link SettingRepository}
|
||||
*/
|
||||
public GeoIpProviderInitializer(SettingRepository settingRepository) {
|
||||
this.settingRepository = settingRepository;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* eiam-console - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package cn.topiam.employee.console.initializer;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cn.topiam.employee.common.entity.account.OrganizationEntity;
|
||||
import cn.topiam.employee.common.enums.account.OrganizationType;
|
||||
import cn.topiam.employee.common.repository.account.OrganizationRepository;
|
||||
import cn.topiam.employee.support.config.AbstractSystemInitializer;
|
||||
import cn.topiam.employee.support.config.InitializationException;
|
||||
import cn.topiam.employee.support.security.util.SecurityUtils;
|
||||
import static cn.topiam.employee.support.constant.EiamConstants.*;
|
||||
import static cn.topiam.employee.support.security.userdetails.DataOrigin.INPUT;
|
||||
|
||||
/**
|
||||
* SystemInitializer
|
||||
*
|
||||
* @author TopIAM
|
||||
* Created by support@topiam.cn on 2024/04/04 21:24
|
||||
*/
|
||||
@Component
|
||||
public class RootOrganizationInitializer extends AbstractSystemInitializer {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RootOrganizationInitializer.class);
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void init() throws InitializationException {
|
||||
//@formatter:off
|
||||
Optional<OrganizationEntity> optional = organizationRepository.findById(ROOT_NODE);
|
||||
if (optional.isEmpty()) {
|
||||
logger.info("初始化父级组织");
|
||||
OrganizationEntity organization = new OrganizationEntity();
|
||||
organization.setId(ROOT_NODE);
|
||||
organization.setName(ROOT_DEPT_NAME);
|
||||
organization.setCode(ROOT_NODE);
|
||||
organization.setPath(PATH_SEPARATOR+ROOT_NODE);
|
||||
organization.setDisplayPath(PATH_SEPARATOR+ROOT_DEPT_NAME);
|
||||
organization.setDataOrigin(INPUT.getType());
|
||||
organization.setType(OrganizationType.GROUP);
|
||||
organization.setLeaf(false);
|
||||
organization.setEnabled(true);
|
||||
organization.setOrder(0L);
|
||||
organization.setCreateBy(SecurityUtils.getCurrentUserName());
|
||||
organization.setCreateTime(LocalDateTime.now());
|
||||
organization.setUpdateBy(SecurityUtils.getCurrentUserName());
|
||||
organization.setUpdateTime(LocalDateTime.now());
|
||||
organization.setRemark("Root organization");
|
||||
organizationRepository.batchSave(Lists.newArrayList(organization));
|
||||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* OrganizationRepository
|
||||
*/
|
||||
private final OrganizationRepository organizationRepository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param organizationRepository {@link OrganizationRepository}
|
||||
*/
|
||||
public RootOrganizationInitializer(OrganizationRepository organizationRepository) {
|
||||
this.organizationRepository = organizationRepository;
|
||||
}
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* eiam-core - Employee Identity and Access Management
|
||||
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package cn.topiam.employee.core.initializer;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import cn.topiam.employee.common.entity.account.OrganizationEntity;
|
||||
import cn.topiam.employee.common.entity.setting.SettingEntity;
|
||||
import cn.topiam.employee.common.geo.GeoLocationProviderConfig;
|
||||
import cn.topiam.employee.common.jackjson.encrypt.EncryptionModule;
|
||||
import cn.topiam.employee.common.repository.account.OrganizationRepository;
|
||||
import cn.topiam.employee.common.repository.setting.SettingRepository;
|
||||
import cn.topiam.employee.support.init.Initializer;
|
||||
import cn.topiam.employee.support.security.util.SecurityUtils;
|
||||
import cn.topiam.employee.support.trace.TraceUtils;
|
||||
import cn.topiam.employee.support.util.AesUtils;
|
||||
import static cn.topiam.employee.common.constant.SettingConstants.AES_SECRET;
|
||||
import static cn.topiam.employee.common.enums.account.OrganizationType.DEPARTMENT;
|
||||
import static cn.topiam.employee.common.geo.ip2region.Ip2regionGeoLocationServiceImpl.IP2REGION;
|
||||
import static cn.topiam.employee.core.setting.GeoIpProviderConstants.IPADDRESS_SETTING_NAME;
|
||||
import static cn.topiam.employee.support.constant.EiamConstants.*;
|
||||
import static cn.topiam.employee.support.lock.LockAspect.getTopiamLockKeyPrefix;
|
||||
import static cn.topiam.employee.support.security.userdetails.DataOrigin.INPUT;
|
||||
|
||||
/**
|
||||
* SystemInitializer
|
||||
*
|
||||
* @author TopIAM
|
||||
* Created by support@topiam.cn on 2024/04/04 21:24
|
||||
*/
|
||||
@Component
|
||||
public class SystemInitializer implements Initializer {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SystemInitializer.class);
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void execute(ApplicationContext applicationContext) {
|
||||
String traceId = idGenerator.generateId().toString();
|
||||
TraceUtils.put(traceId);
|
||||
RLock lock = redissonClient.getLock(getTopiamLockKeyPrefix() + COLON + "system_init");
|
||||
boolean tryLock = false;
|
||||
try {
|
||||
SecurityContextHolder.getContext().setAuthentication(TOPIAM_INIT_AUTHENTICATION);
|
||||
tryLock = lock.tryLock(1, TimeUnit.SECONDS);
|
||||
if (tryLock) {
|
||||
//init 加密秘钥
|
||||
initEncryptSecret();
|
||||
//init IP 提供商
|
||||
initIpProvider();
|
||||
//初始化组织机构
|
||||
initRootOrganization();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
int exitCode = SpringApplication.exit(applicationContext, () -> 0);
|
||||
System.exit(exitCode);
|
||||
} finally {
|
||||
if (tryLock && lock.isLocked()) {
|
||||
lock.unlock();
|
||||
}
|
||||
TraceUtils.remove();
|
||||
SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化加密秘钥
|
||||
*/
|
||||
private void initEncryptSecret() {
|
||||
SettingEntity optional = settingRepository.findByName(AES_SECRET);
|
||||
if (Objects.isNull(optional)) {
|
||||
SettingEntity setting = new SettingEntity();
|
||||
setting.setName(AES_SECRET);
|
||||
setting.setValue(AesUtils.generateKey());
|
||||
setting.setDesc("Project aes secret");
|
||||
setting.setRemark(
|
||||
"This aes secret is automatically created during system initialization.");
|
||||
settingRepository.save(setting);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化IP地址提供商
|
||||
*
|
||||
* @throws JsonProcessingException JsonProcessingException
|
||||
*/
|
||||
private void initIpProvider() throws JsonProcessingException {
|
||||
//@formatter:off
|
||||
SettingEntity optional = settingRepository.findByName(IPADDRESS_SETTING_NAME);
|
||||
if (Objects.isNull(optional)) {
|
||||
logger.info("初始化系统默认IP地址提供商");
|
||||
SettingEntity setting = new SettingEntity();
|
||||
setting.setName(IPADDRESS_SETTING_NAME);
|
||||
ObjectMapper objectMapper = EncryptionModule.deserializerDecrypt();
|
||||
// 指定序列化输入的类型
|
||||
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||
setting.setValue(objectMapper.writeValueAsString(new GeoLocationProviderConfig(IP2REGION, null)));
|
||||
setting.setDesc(IP2REGION.getName());
|
||||
setting.setRemark("The system initializes the default configuration.");
|
||||
settingRepository.save(setting);
|
||||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化组织机构
|
||||
*/
|
||||
private void initRootOrganization() {
|
||||
//@formatter:off
|
||||
Optional<OrganizationEntity> optional = organizationRepository.findById(ROOT_NODE);
|
||||
if (optional.isEmpty()) {
|
||||
logger.info("初始化父级组织");
|
||||
OrganizationEntity organization = new OrganizationEntity();
|
||||
organization.setId(ROOT_NODE);
|
||||
organization.setName(ROOT_DEPT_NAME);
|
||||
organization.setCode(ROOT_NODE);
|
||||
organization.setPath(PATH_SEPARATOR+ROOT_NODE);
|
||||
organization.setDisplayPath(PATH_SEPARATOR+ROOT_DEPT_NAME);
|
||||
organization.setType(DEPARTMENT);
|
||||
organization.setDataOrigin(INPUT.getType());
|
||||
organization.setLeaf(false);
|
||||
organization.setEnabled(true);
|
||||
organization.setOrder(0L);
|
||||
organization.setCreateBy(SecurityUtils.getCurrentUserName());
|
||||
organization.setCreateTime(LocalDateTime.now());
|
||||
organization.setUpdateBy(SecurityUtils.getCurrentUserName());
|
||||
organization.setUpdateTime(LocalDateTime.now());
|
||||
organization.setRemark("Root organization");
|
||||
organizationRepository.batchSave(Lists.newArrayList(organization));
|
||||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
private final AlternativeJdkIdGenerator idGenerator = new AlternativeJdkIdGenerator();
|
||||
|
||||
/**
|
||||
* RedissonClient
|
||||
*/
|
||||
private final RedissonClient redissonClient;
|
||||
|
||||
/**
|
||||
* SettingRepository
|
||||
*/
|
||||
private final SettingRepository settingRepository;
|
||||
|
||||
/**
|
||||
* OrganizationRepository
|
||||
*/
|
||||
private final OrganizationRepository organizationRepository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param redissonClient {@link RedissonClient}
|
||||
* @param settingRepository {@link SettingRepository}
|
||||
* @param organizationRepository {@link OrganizationRepository}
|
||||
*/
|
||||
public SystemInitializer(RedissonClient redissonClient, SettingRepository settingRepository,
|
||||
OrganizationRepository organizationRepository) {
|
||||
this.redissonClient = redissonClient;
|
||||
this.settingRepository = settingRepository;
|
||||
this.organizationRepository = organizationRepository;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue