From 2c4a946cdaa22a1cc16efc714dc4a625aa103f5a Mon Sep 17 00:00:00 2001 From: smallbun <2689170096@qq.com> Date: Mon, 16 Dec 2024 01:03:56 +0800 Subject: [PATCH] =?UTF-8?q?:building=5Fconstruction:=20=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E9=80=BB=E8=BE=91=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultAdministratorInitializer.java | 191 ++++++++--------- .../DefaultAppGroupInitializer.java | 74 ++----- .../initializer/EncryptSecretInitializer.java | 73 +++++++ .../initializer/GeoIpProviderInitializer.java | 92 ++++++++ .../RootOrganizationInitializer.java | 95 +++++++++ .../core/initializer/SystemInitializer.java | 197 ------------------ 6 files changed, 363 insertions(+), 359 deletions(-) create mode 100644 eiam-console/src/main/java/cn/topiam/employee/console/initializer/EncryptSecretInitializer.java create mode 100644 eiam-console/src/main/java/cn/topiam/employee/console/initializer/GeoIpProviderInitializer.java create mode 100644 eiam-console/src/main/java/cn/topiam/employee/console/initializer/RootOrganizationInitializer.java delete mode 100644 eiam-core/src/main/java/cn/topiam/employee/core/initializer/SystemInitializer.java diff --git a/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAdministratorInitializer.java b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAdministratorInitializer.java index 8a1c49d8..352db7c5 100644 --- a/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAdministratorInitializer.java +++ b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAdministratorInitializer.java @@ -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,93 +60,72 @@ 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 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 { - String passwordInitial = System.getProperty(INITIAL_PASSWORD_VALUE_NAME); - if (StringUtils.hasText(passwordInitial)) { - initPassword = passwordInitial; - } - else { - initPassword = INITIAL_PASSWORD_DEFAULT; - } - } - String initialAdminPasswordFilePath = getInitialAdminPasswordFilePath();createFile(initialAdminPasswordFilePath); - BufferedWriter stream = new BufferedWriter(new FileWriter(initialAdminPasswordFilePath)); - initPasswordFileTips = "This may also be found at: " + initialAdminPasswordFilePath; - //清空 - stream.write(initPassword); - stream.flush(); - stream.close(); - logger.info(""" + Optional 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 { + String passwordInitial = System.getProperty(INITIAL_PASSWORD_VALUE_NAME); + if (StringUtils.hasText(passwordInitial)) { + initPassword = passwordInitial; + } else { + initPassword = INITIAL_PASSWORD_DEFAULT; + } + } + 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( + """ - ************************************************************* - ************************************************************* - ************************************************************* + ************************************************************* + ************************************************************* + ************************************************************* - TOPIAM console initial setup is required. An admin user has been created and a initialize password. - Please use the following password to proceed to installation: + 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 + %s - %s\s - ************************************************************* - ************************************************************* - ************************************************************* + %s\s + ************************************************************* + ************************************************************* + ************************************************************* - """.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(); + """ + .formatted(initPassword, initPasswordFileTips)); + //保存管理员 + AdministratorEntity administrator = new AdministratorEntity(); + administrator.setUsername(DEFAULT_ADMIN_USERNAME); + administrator.setFullName("管理员"); + administrator.setPassword(passwordEncoder.encode(initPassword)); + administrator.setStatus(UserStatus.ENABLED); + administrator.setNeedChangePassword(true); + administrator.setRemark( + "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); } - TraceUtils.remove(); - SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext()); + } catch (Exception e) { + throw new InitializationException(e); } - //@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.setStatus(UserStatus.ENABLED); - administrator.setNeedChangePassword(true); - administrator.setRemark( - "This administrator user is automatically created during system initialization."); - administratorRepository.save(administrator); } public static String addSeparator(String dir) { @@ -175,20 +146,24 @@ public class DefaultAdministratorInitializer implements Initializer { return path + "initialAdminPassword"; } - private final AlternativeJdkIdGenerator idGenerator = new AlternativeJdkIdGenerator(); - - private final AdministratorRepository administratorRepository; - - private final PasswordEncoder passwordEncoder; - - private final RedissonClient redissonClient; - - public DefaultAdministratorInitializer(AdministratorRepository administratorRepository, - PasswordEncoder passwordEncoder, - RedissonClient redissonClient) { - this.administratorRepository = administratorRepository; - this.passwordEncoder = passwordEncoder; - this.redissonClient = redissonClient; + @Override + public int getOrder() { + return 3; } + private final AlternativeJdkIdGenerator idGenerator = new AlternativeJdkIdGenerator(); + + private final OrganizationMemberRepository organizationMemberRepository; + + private final AdministratorRepository administratorRepository; + + private final PasswordEncoder passwordEncoder; + + public DefaultAdministratorInitializer(OrganizationMemberRepository organizationMemberRepository, + AdministratorRepository administratorRepository, + PasswordEncoder passwordEncoder) { + this.organizationMemberRepository = organizationMemberRepository; + this.administratorRepository = administratorRepository; + this.passwordEncoder = passwordEncoder; + } } diff --git a/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAppGroupInitializer.java b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAppGroupInitializer.java index 99816b16..4818604d 100644 --- a/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAppGroupInitializer.java +++ b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/DefaultAppGroupInitializer.java @@ -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,59 +39,34 @@ 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 optional = appGroupRepository.findByCode(i.getCode()); - if (optional.isEmpty()) { - AppGroupEntity appGroup = new AppGroupEntity(); - appGroup.setCode(i.getCode()); - appGroup.setName(i.getDesc()); - appGroup.setType(AppGroupType.DEFAULT); - appGroup.setRemark( - "This app group is automatically created during system initialization."); - appGroupRepository.save(appGroup); - } - }); - + Arrays.stream(AppDefaultGroup.values()).toList().forEach(i -> { + Optional optional = appGroupRepository.findByCode(i.getCode()); + if (optional.isEmpty()) { + AppGroupEntity appGroup = new AppGroupEntity(); + appGroup.setCode(i.getCode()); + appGroup.setName(i.getDesc()); + appGroup.setType(AppGroupType.DEFAULT); + appGroup.setRemark( + "This app group is automatically created during system initialization."); + appGroupRepository.save(appGroup); } - - } 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 + }); + } + @Override + public int getOrder() { + return 4; } - - 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; } - } diff --git a/eiam-console/src/main/java/cn/topiam/employee/console/initializer/EncryptSecretInitializer.java b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/EncryptSecretInitializer.java new file mode 100644 index 00000000..606fa770 --- /dev/null +++ b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/EncryptSecretInitializer.java @@ -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 . + */ +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; + } +} diff --git a/eiam-console/src/main/java/cn/topiam/employee/console/initializer/GeoIpProviderInitializer.java b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/GeoIpProviderInitializer.java new file mode 100644 index 00000000..7d1d592d --- /dev/null +++ b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/GeoIpProviderInitializer.java @@ -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 . + */ +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; + } +} diff --git a/eiam-console/src/main/java/cn/topiam/employee/console/initializer/RootOrganizationInitializer.java b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/RootOrganizationInitializer.java new file mode 100644 index 00000000..0fa39167 --- /dev/null +++ b/eiam-console/src/main/java/cn/topiam/employee/console/initializer/RootOrganizationInitializer.java @@ -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 . + */ +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 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; + } +} diff --git a/eiam-core/src/main/java/cn/topiam/employee/core/initializer/SystemInitializer.java b/eiam-core/src/main/java/cn/topiam/employee/core/initializer/SystemInitializer.java deleted file mode 100644 index a25f1be4..00000000 --- a/eiam-core/src/main/java/cn/topiam/employee/core/initializer/SystemInitializer.java +++ /dev/null @@ -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 . - */ -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 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; - } -}