优化代码

pull/63/MERGE
awenes 2023-10-02 09:26:16 +08:00
parent d19448d113
commit de70c194f5
11 changed files with 64 additions and 340 deletions

View File

@ -21,7 +21,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -34,18 +33,14 @@ import cn.topiam.employee.audit.context.AuditContext;
import cn.topiam.employee.audit.entity.Target;
import cn.topiam.employee.audit.enums.TargetType;
import cn.topiam.employee.common.entity.account.OrganizationEntity;
import cn.topiam.employee.common.entity.account.OrganizationMemberEntity;
import cn.topiam.employee.common.entity.account.QUserEntity;
import cn.topiam.employee.common.enums.DataOrigin;
import cn.topiam.employee.common.repository.account.OrganizationMemberRepository;
import cn.topiam.employee.common.repository.account.OrganizationRepository;
import cn.topiam.employee.console.converter.account.OrganizationConverter;
import cn.topiam.employee.console.pojo.result.account.*;
import cn.topiam.employee.console.pojo.save.account.OrganizationCreateParam;
import cn.topiam.employee.console.pojo.update.account.OrganizationUpdateParam;
import cn.topiam.employee.console.service.account.OrganizationService;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.support.repository.id.SnowflakeIdGenerator;
import cn.topiam.employee.support.util.BeanUtils;
@ -116,7 +111,6 @@ public class OrganizationServiceImpl implements OrganizationService {
Optional<OrganizationEntity> optional = this.organizationRepository.findById(param.getId());
if (optional.isPresent()) {
OrganizationEntity entity = optional.get();
String userIds;
//如果修改了名字,递归修改和该组织有关所有节点信息的展示路径
if (!optional.get().getName().equals(param.getName())) {
//修改名称
@ -126,22 +120,10 @@ public class OrganizationServiceImpl implements OrganizationService {
if (!entity.getLeaf()) {
recursiveUpdateDisplayPath(entity.getId(), entity.getId(), param.getName());
}
userIds = organizationRepository
.getOrgMemberList(organization.getId(), QUserEntity.userEntity.id).stream()
.map(String::valueOf).collect(Collectors.joining(","));
} else {
List<OrganizationMemberEntity> orgMemberList = organizationMemberRepository
.findAllByOrgId(entity.getId());
userIds = orgMemberList.stream().map(item -> String.valueOf(item.getUserId()))
.collect(Collectors.joining(","));
}
//修改
BeanUtils.merge(organization, entity, LAST_MODIFIED_BY, LAST_MODIFIED_TIME);
organizationRepository.save(entity);
// 更新用户es信息
if (StringUtils.isNotBlank(userIds)) {
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, userIds);
}
AuditContext.setTarget(
Target.builder().id(entity.getId()).type(TargetType.ORGANIZATION).build());
return true;
@ -259,9 +241,7 @@ public class OrganizationServiceImpl implements OrganizationService {
@Override
public OrganizationResult getOrganization(String id) {
Optional<OrganizationEntity> entity = organizationRepository.findById(id);
OrganizationResult organizationResult = entity
.map(organizationConverter::entityConvertToGetOrganizationResult).orElse(null);
return organizationResult;
return entity.map(organizationConverter::entityConvertToGetOrganizationResult).orElse(null);
}
/**
@ -315,13 +295,6 @@ public class OrganizationServiceImpl implements OrganizationService {
.name(organization.get().getName()).build());
//存在子组织,递归更改子组织 path 和 displayPath
recursiveUpdateChildNodePathAndDisplayPath(entity.getId());
// 更新用户es信息
String userIds = organizationRepository
.getOrgMemberList(entity.getId(), QUserEntity.userEntity.id).stream()
.map(String::valueOf).collect(Collectors.joining(","));
if (StringUtils.isNotBlank(userIds)) {
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, userIds);
}
return true;
}
return false;
@ -458,20 +431,11 @@ public class OrganizationServiceImpl implements OrganizationService {
/**
*
*/
private final OrganizationConverter organizationConverter;
private final OrganizationConverter organizationConverter;
/**
* OrganizationRepository
*/
private final OrganizationRepository organizationRepository;
private final OrganizationRepository organizationRepository;
/**
* MessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
/**
* OrganizationMemberRepository
*/
private final OrganizationMemberRepository organizationMemberRepository;
}

View File

@ -21,12 +21,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.google.common.collect.Lists;
import com.querydsl.core.types.ExpressionUtils;
@ -49,8 +47,6 @@ import cn.topiam.employee.console.pojo.result.account.UserGroupMemberListResult;
import cn.topiam.employee.console.pojo.save.account.UserGroupCreateParam;
import cn.topiam.employee.console.pojo.update.account.UserGroupUpdateParam;
import cn.topiam.employee.console.service.account.UserGroupService;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.support.exception.TopIamException;
import cn.topiam.employee.support.repository.page.domain.Page;
import cn.topiam.employee.support.repository.page.domain.PageModel;
@ -118,14 +114,6 @@ public class UserGroupServiceImpl implements UserGroupService {
UserGroupEntity details = getUserGroup(Long.valueOf(param.getId()));
BeanUtils.merge(entity, details, LAST_MODIFIED_TIME, LAST_MODIFIED_BY);
userGroupRepository.save(details);
// 更新用户es信息
List<UserGroupMemberEntity> userGroupMemberList = userGroupMemberRepository
.findByGroupId(details.getId());
if (!CollectionUtils.isEmpty(userGroupMemberList)) {
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
userGroupMemberList.stream().map(item -> String.valueOf(item.getUserId()))
.collect(Collectors.joining(",")));
}
AuditContext.setTarget(
Target.builder().id(details.getId().toString()).type(TargetType.USER_GROUP).build());
return true;
@ -183,8 +171,6 @@ public class UserGroupServiceImpl implements UserGroupService {
public Boolean removeMember(String id, String userId) {
//查询关联关系
userGroupMemberRepository.deleteByGroupIdAndUserId(Long.valueOf(id), Long.valueOf(userId));
// 更新用户es用户组信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, userId);
AuditContext.setTarget(Target.builder().id(userId).type(TargetType.USER).build(),
Target.builder().id(id).type(TargetType.USER_GROUP).build());
return true;
@ -215,8 +201,6 @@ public class UserGroupServiceImpl implements UserGroupService {
});
//添加
userGroupMemberRepository.saveAll(list);
// 更新用户es用户组信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, String.join(",", userIds));
List<Target> targets = new ArrayList<>(Arrays.stream(userIds)
.map(i -> Target.builder().id(i).type(TargetType.USER).build()).toList());
@ -254,8 +238,6 @@ public class UserGroupServiceImpl implements UserGroupService {
}
userIds.forEach(userId -> userGroupMemberRepository
.deleteByGroupIdAndUserId(Long.valueOf(id), Long.valueOf(userId)));
// 更新用户es用户组信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, String.join(",", userIds));
List<Target> targets = new ArrayList<>(userIds.stream()
.map(i -> Target.builder().id(i).type(TargetType.USER).build()).toList());
@ -301,9 +283,4 @@ public class UserGroupServiceImpl implements UserGroupService {
* UserGroupMemberRepository
*/
private final UserGroupMemberRepository userGroupMemberRepository;
/**
* MessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
}

View File

@ -61,8 +61,6 @@ import cn.topiam.employee.console.service.account.UserService;
import cn.topiam.employee.core.message.MsgVariable;
import cn.topiam.employee.core.message.mail.MailMsgEventPublish;
import cn.topiam.employee.core.message.sms.SmsMsgEventPublish;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.support.autoconfiguration.SupportProperties;
import cn.topiam.employee.support.exception.BadParamsException;
import cn.topiam.employee.support.exception.InfoValidityFailException;
@ -200,12 +198,7 @@ public class UserServiceImpl implements UserService {
throw new TopIamException(AuditContext.getContent());
}
AuditContext.setTarget(Target.builder().id(id.toString()).type(TargetType.USER).build());
boolean update = userRepository.updateUserStatus(id, status) > 0;
if (update) {
// 更新索引数据
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, String.valueOf(id));
}
return update;
return userRepository.updateUserStatus(id, status) > 0;
}
/**
@ -258,9 +251,6 @@ public class UserServiceImpl implements UserService {
organizationMemberRepository.save(member);
AuditContext.setTarget(Target.builder().type(USER).id(user.getId().toString()).build(),
Target.builder().type(USER_DETAIL).id(detail.getId().toString()).build());
// 保存ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.valueOf(user.getId()));
// 发送短信和邮件的欢迎信息(密码通知)
UserCreateParam.PasswordInitializeConfig passwordInitializeConfig = param
.getPasswordInitializeConfig();
@ -369,9 +359,6 @@ public class UserServiceImpl implements UserService {
userDetailsRepository.save(detail);
AuditContext.setTarget(Target.builder().type(USER).id(user.getId().toString()).build(),
Target.builder().type(USER_DETAIL).id(detail.getId().toString()).build());
// 更新ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.valueOf(user.getId()));
return true;
}
@ -400,8 +387,6 @@ public class UserServiceImpl implements UserService {
//删除用户组用户详情
userGroupMemberRepository.deleteByUserId(Long.valueOf(id));
AuditContext.setTarget(Target.builder().id(id).type(TargetType.USER).build());
// 删除ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.DELETE, id);
return true;
}
@ -445,8 +430,6 @@ public class UserServiceImpl implements UserService {
organizationMemberRepository.deleteAllByUserId(idList);
//删除用户组关系
userGroupMemberRepository.deleteAllByUserId(idList);
// 批量删除ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.DELETE, String.join(",", ids));
return true;
}
@ -614,8 +597,4 @@ public class UserServiceImpl implements UserService {
*/
private final PasswordPolicyManager<UserEntity> passwordPolicyManager;
/**
* MessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
}

View File

@ -55,8 +55,6 @@ import cn.topiam.employee.common.repository.identitysource.IdentitySourceSyncRec
import cn.topiam.employee.common.storage.Storage;
import cn.topiam.employee.core.message.mail.MailMsgEventPublish;
import cn.topiam.employee.core.message.sms.SmsMsgEventPublish;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.identitysource.core.domain.Dept;
import cn.topiam.employee.identitysource.core.domain.User;
import cn.topiam.employee.identitysource.core.enums.IdentitySourceEventReceiveType;
@ -133,7 +131,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
List<IdentitySourceEventRecordEntity> records = new ArrayList<>();
List<UserEntity> createUsers = new ArrayList<>();
Set<OrganizationMemberEntity> createOrganizationMembers = Sets.newHashSet();
List<String> batchEsUserIdList = new ArrayList<>();
users.forEach(thirdPartyUser -> {
log.info("处理上游用户新增事件:[{}]开始", thirdPartyUser.getUserId());
UserEntity userEntity = thirdPartyUserToUserEntity(thirdPartyUser, identitySource);
@ -149,7 +146,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
userEntity.getId());
createOrganizationMember(createOrganizationMembers, userEntity, organization);
});
batchEsUserIdList.add(String.valueOf(userEntity.getId()));
//记录日志
IdentitySourceEventRecordEntity record = new IdentitySourceEventRecordEntity();
record.setObjectId(userEntity.getId().toString());
@ -174,9 +170,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
organizationMemberRepository.batchSave(Lists.newArrayList(createOrganizationMembers));
//保存事件记录
identitySourceEventRecordRepository.batchSave(records);
// 异步创建ES用户数据
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.join(",", batchEsUserIdList));
// 批量发送短信邮件欢迎信息(密码通知)
publishMessage(createUsers);
}
@ -192,7 +185,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
List<IdentitySourceEventRecordEntity> records = new ArrayList<>();
List<UserEntity> updateUsers = new ArrayList<>();
List<OrganizationMemberEntity> createOrganizationMembers = new ArrayList<>();
List<String> batchEsUserIdList = new ArrayList<>();
//需要删除组织成员关系集合 KEY用户IDvalue组织ID
Map<Long, Set<String>> deleteOrganizationMembers = Maps.newHashMap();
Map<UserEntity, Set<OrganizationEntity>> currentUsers = Maps.newHashMap();
@ -252,9 +244,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
record.setUpdateBy(SYSTEM_DEFAULT_USER_NAME);
record.setUpdateTime(LocalDateTime.now());
records.add(record);
// 构建ES用户Id信息
batchEsUserIdList.add(String.valueOf(currentUser.getId()));
log.info("处理上游用户修改事件:[{}]结束", thirdPartyUser.getUserId());
}
}));
@ -267,8 +256,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
.forEach(user -> deleteOrganizationMembers.get(user)
.forEach(organization -> organizationMemberRepository
.deleteByOrgIdAndUserId(organization, user)));
// 异步更新ES用户数据
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, String.join(",", batchEsUserIdList));
//保存事件记录
identitySourceEventRecordRepository.batchSave(records);
//@formatter:on
@ -398,7 +385,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
//根据外部ID查询
List<OrganizationEntity> list = organizationRepository
.findByExternalIdIn(organizations.stream().map(Dept::getDeptId).toList());
List<String> userIds = new ArrayList<>();
list.forEach(current -> organizations.forEach(threeParty -> {
//当前三方ID和上游科室对应
if (current.getExternalId().equals(threeParty.getDeptId())) {
@ -434,20 +420,10 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
if (subOrganizations.stream().map(i -> i.getId().equals(current.getId()))
.findAny().isEmpty()) {
organizationRepository.updateIsLeaf(parentOrganization.getId(), true);
// 查询关联用户
List<OrganizationMemberEntity> orgMemberList = organizationMemberRepository
.findAllByOrgId(parentOrganization.getId());
userIds.addAll(orgMemberList.stream()
.map(item -> String.valueOf(item.getUserId())).toList());
}
}
if (parentOrganization.getLeaf()) {
organizationRepository.updateIsLeaf(parentOrganization.getId(), false);
// 查询关联用户
List<OrganizationMemberEntity> orgMemberList = organizationMemberRepository
.findAllByOrgId(parentOrganization.getId());
userIds.addAll(orgMemberList.stream()
.map(item -> String.valueOf(item.getUserId())).toList());
}
//修改基本信息
current.setName(threeParty.getName());
@ -469,17 +445,10 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
record.setUpdateBy(SYSTEM_DEFAULT_USER_NAME);
record.setUpdateTime(LocalDateTime.now());
records.add(record);
// 查询关联用户
List<OrganizationMemberEntity> orgMemberList = organizationMemberRepository
.findAllByOrgId(current.getId());
userIds.addAll(
orgMemberList.stream().map(item -> String.valueOf(item.getUserId())).toList());
}
}));
//批量保存部门信息
organizationRepository.batchUpdate(updateOrganizations);
// 更新es用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, String.join(",", userIds));
//保存事件记录
identitySourceEventRecordRepository.batchSave(records);
}
@ -554,11 +523,6 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
*/
private final IdentitySourceEventRecordRepository identitySourceEventRecordRepository;
/**
* MessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
public DefaultIdentitySourceEventPostProcessor(SmsMsgEventPublish smsMsgEventPublish,
MailMsgEventPublish mailMsgEventPublish,
PasswordEncoder passwordEncoder,
@ -573,8 +537,7 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
OrganizationRepository organizationRepository,
OrganizationMemberRepository organizationMemberRepository,
IdentitySourceEventRecordRepository identitySourceEventRecordRepository,
Storage storage,
UserMessagePublisher userMessagePublisher) {
Storage storage) {
super(smsMsgEventPublish, mailMsgEventPublish, passwordEncoder, passwordGenerator,
transactionDefinition, platformTransactionManager, entityManager,
identitySourceRepository, identitySourceSyncHistoryRepository,
@ -583,6 +546,5 @@ public class DefaultIdentitySourceEventPostProcessor extends AbstractIdentitySou
this.organizationRepository = organizationRepository;
this.organizationMemberRepository = organizationMemberRepository;
this.identitySourceEventRecordRepository = identitySourceEventRecordRepository;
this.userMessagePublisher = userMessagePublisher;
}
}

View File

@ -21,7 +21,6 @@ import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
@ -54,8 +53,6 @@ import cn.topiam.employee.common.repository.identitysource.IdentitySourceSyncRec
import cn.topiam.employee.common.storage.Storage;
import cn.topiam.employee.core.message.mail.MailMsgEventPublish;
import cn.topiam.employee.core.message.sms.SmsMsgEventPublish;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.identitysource.core.domain.User;
import cn.topiam.employee.identitysource.core.processor.IdentitySourceSyncUserPostProcessor;
import cn.topiam.employee.support.repository.domain.IdEntity;
@ -100,19 +97,14 @@ public class DefaultIdentitySourceUserPostProcessor extends AbstractIdentitySour
processData = processData(identitySource, initData);
//校验数据
validateData(processData);
String batchEsUserId = "";
//批量保存用户
if (!CollectionUtils.isEmpty(processData.getCreateUsers())) {
List<UserEntity> createUserList = Lists.newArrayList(processData.getCreateUsers());
batchEsUserId += createUserList.stream().map(user -> String.valueOf(user.getId()))
.collect(Collectors.joining(","));
userRepository.batchSave(createUserList);
}
//批量更新用户
if (!CollectionUtils.isEmpty(processData.getUpdateUsers())) {
List<UserEntity> updateUserList = Lists.newArrayList(processData.getUpdateUsers());
batchEsUserId += updateUserList.stream().map(user -> String.valueOf(user.getId()))
.collect(Collectors.joining(","));
userRepository.batchUpdate(updateUserList);
}
//保存组织成员关系
@ -148,13 +140,6 @@ public class DefaultIdentitySourceUserPostProcessor extends AbstractIdentitySour
saveSyncHistoryRecord(history.getId(), processData);
//提交事务
platformTransactionManager.commit(transactionStatus);
// 异步更新ES用户数据
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, batchEsUserId);
// 异步删除用户ES数据
if (!CollectionUtils.isEmpty(processData.getDeleteUsers())) {
userMessagePublisher.sendUserChangeMessage(UserMessageTag.DELETE,
deleteUserIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
}
if (!CollectionUtils.isEmpty(processData.getCreateUsers())) {
// 发送密码通知
publishMessage(Lists.newArrayList(processData.getCreateUsers()));
@ -734,11 +719,6 @@ public class DefaultIdentitySourceUserPostProcessor extends AbstractIdentitySour
*/
private final UserGroupMemberRepository userGroupMemberRepository;
/**
* MessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
public DefaultIdentitySourceUserPostProcessor(SmsMsgEventPublish smsMsgEventPublish,
MailMsgEventPublish mailMsgEventPublish,
TransactionDefinition transactionDefinition,
@ -754,8 +734,7 @@ public class DefaultIdentitySourceUserPostProcessor extends AbstractIdentitySour
OrganizationMemberRepository organizationMemberRepository,
UserGroupMemberRepository userGroupMemberRepository,
OrganizationRepository organizationRepository,
Storage storage,
UserMessagePublisher userMessagePublisher) {
Storage storage) {
super(smsMsgEventPublish, mailMsgEventPublish, passwordEncoder, passwordGenerator,
transactionDefinition, platformTransactionManager, entityManager,
identitySourceRepository, identitySourceSyncHistoryRepository,
@ -765,6 +744,5 @@ public class DefaultIdentitySourceUserPostProcessor extends AbstractIdentitySour
this.organizationMemberRepository = organizationMemberRepository;
this.userGroupMemberRepository = userGroupMemberRepository;
this.organizationRepository = organizationRepository;
this.userMessagePublisher = userMessagePublisher;
}
}

View File

@ -1,6 +1,6 @@
/*
* eiam-core - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
* eiam-core - Employee Identity and Access Management Program
* Copyright © 2020-2023 TopIAM (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
@ -19,36 +19,23 @@ package cn.topiam.employee.core.security.password.task.impl;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.scheduling.annotation.Scheduled;
import com.google.common.collect.Lists;
import cn.topiam.employee.common.entity.account.UserElasticSearchEntity;
import cn.topiam.employee.common.entity.account.UserEntity;
import cn.topiam.employee.common.entity.setting.SettingEntity;
import cn.topiam.employee.common.enums.UserStatus;
import cn.topiam.employee.common.repository.account.UserRepository;
import cn.topiam.employee.common.repository.setting.SettingRepository;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.core.security.password.task.PasswordExpireTask;
import cn.topiam.employee.support.autoconfiguration.SupportProperties;
import cn.topiam.employee.support.lock.Lock;
import cn.topiam.employee.support.trace.Trace;
import lombok.RequiredArgsConstructor;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import co.elastic.clients.elasticsearch._types.query_dsl.TermsQueryField;
import static cn.topiam.employee.core.setting.constant.PasswordPolicySettingConstants.PASSWORD_POLICY_DEFAULT_SETTINGS;
import static cn.topiam.employee.core.setting.constant.PasswordPolicySettingConstants.PASSWORD_POLICY_VALID_DAYS;
@ -66,48 +53,30 @@ public class PasswordExpireLockTask implements PasswordExpireTask {
/**
*
*/
@Lock(throwException = false)
@Trace
@Scheduled(cron = "0 0 0 * * ?")
@Override
public void execute() {
long start = System.currentTimeMillis();
logger.info("密码过期锁定用户任务开始");
int expireDays = getExpireDays();
// 查询非密码过期锁定和过期锁定用户信息
Query query = QueryBuilders.terms(builder -> {
builder.terms(new TermsQueryField.Builder().value(
Lists.newArrayList(FieldValue.of(UserStatus.PASSWORD_EXPIRED_LOCKED.getCode()),
FieldValue.of(UserStatus.EXPIRED_LOCKED.getCode())))
.build());
builder.field("status");
return builder;
});
List<UserElasticSearchEntity> userElasticSearchList = userRepository
.getAllUserElasticSearchEntity(
IndexCoordinates.of(supportProperties.getUser().getIndexPrefix()), query);
List<String> lockedUserIdList = new ArrayList<>();
Iterator<UserElasticSearchEntity> iterator = userElasticSearchList.iterator();
logger.info("密码过期待锁定用户数量为:{}个", userElasticSearchList.size());
while (!userElasticSearchList.isEmpty()) {
UserElasticSearchEntity entity = iterator.next();
//1、根据提醒时间分页查询即将要过期的密码
List<UserEntity> list = userRepository.findPasswordExpireUser(expireDays);
Iterator<UserEntity> iterator = list.iterator();
logger.info("密码过期待锁定用户数量为:{}个", list.size());
while (!list.isEmpty()) {
UserEntity entity = iterator.next();
//获取到期日期
LocalDateTime expiredDate = entity.getLastUpdatePasswordTime().atOffset(ZoneOffset.MAX)
.plusDays(expireDays).toLocalDateTime();
if (LocalDateTime.now().isBefore(expiredDate)) {
lockedUserIdList.add(entity.getId());
userRepository.updateUserStatus(Long.valueOf(entity.getId()),
UserStatus.PASSWORD_EXPIRED_LOCKED);
logger.info("锁定密码过期用户:{}", entity.getUsername());
entity.setStatus(UserStatus.PASSWORD_EXPIRED_LOCKED);
userRepository.save(entity);
logger.info("锁定密码过期用户:{}", entity.getUsername());
iterator.remove();
}
iterator = userElasticSearchList.iterator();
iterator = list.iterator();
}
// 推送es用户消息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.join(",", lockedUserIdList));
logger.info("密码过期锁定用户任务结束: 冻结用户数量[{}], 耗时:[{}]s", lockedUserIdList.size(),
(System.currentTimeMillis() - start) / 1000);
logger.info("密码过期锁定用户任务结束");
}
/**
@ -126,21 +95,11 @@ public class PasswordExpireLockTask implements PasswordExpireTask {
/**
*
*/
private final SettingRepository settingRepository;
private final SettingRepository settingRepository;
/**
* UserRepository
*/
private final UserRepository userRepository;
/**
* SupportProperties
*/
private final SupportProperties supportProperties;
/**
* UserMessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
private final UserRepository userRepository;
}

View File

@ -1,6 +1,6 @@
/*
* eiam-core - Employee Identity and Access Management
* Copyright © 2022-Present Jinan Yuanchuang Network Technology Co., Ltd. (support@topiam.cn)
* eiam-core - Employee Identity and Access Management Program
* Copyright © 2020-2023 TopIAM (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
@ -19,7 +19,6 @@ package cn.topiam.employee.core.security.password.task.impl;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -29,29 +28,22 @@ import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.client.elc.Queries;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.scheduling.annotation.Scheduled;
import com.google.common.collect.Maps;
import cn.topiam.employee.common.entity.account.UserElasticSearchEntity;
import cn.topiam.employee.common.entity.account.UserEntity;
import cn.topiam.employee.common.entity.setting.SettingEntity;
import cn.topiam.employee.common.enums.MailType;
import cn.topiam.employee.common.enums.SmsType;
import cn.topiam.employee.common.enums.UserStatus;
import cn.topiam.employee.common.repository.account.UserRepository;
import cn.topiam.employee.common.repository.setting.SettingRepository;
import cn.topiam.employee.core.message.mail.MailMsgEventPublish;
import cn.topiam.employee.core.message.sms.SmsMsgEventPublish;
import cn.topiam.employee.core.security.password.task.PasswordExpireTask;
import cn.topiam.employee.support.autoconfiguration.SupportProperties;
import cn.topiam.employee.support.lock.Lock;
import cn.topiam.employee.support.trace.Trace;
import lombok.RequiredArgsConstructor;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import static cn.topiam.employee.core.message.MsgVariable.EXPIRE_DAYS;
import static cn.topiam.employee.core.setting.constant.PasswordPolicySettingConstants.*;
@ -68,59 +60,48 @@ public class PasswordExpireWarnTask implements PasswordExpireTask {
/**
*
*/
@Lock(throwException = false)
@Trace
@Scheduled(cron = "0 0 0 * * ?")
@Override
public void execute() {
long start = System.currentTimeMillis();
logger.info("密码过期前提醒任务开始");
//密码有效期天数
int expireDays = getExpireDays();
//密码过期前提醒天数
int warnExpireDays = getWarnExpireDays();
//1、根据提醒时间分页查询即将要过期的密码
// 查询已启用用户信息
Query query = Queries.termQueryAsQuery("status", UserStatus.ENABLE.getCode());
List<UserElasticSearchEntity> list = userRepository.getAllUserElasticSearchEntity(
IndexCoordinates.of(supportProperties.getUser().getIndexPrefix()), query);
List<UserEntity> list = userRepository
.findPasswordExpireWarnUser(expireDays - warnExpireDays);
logger.info("待提醒用户为:{}个", list.size());
int reminderNumber = 0;
//2、发送通知提醒
for (UserElasticSearchEntity entity : list) {
// 获取到密码期日期
LocalDate expiredDate = entity.getLastUpdatePasswordTime().atOffset(ZoneOffset.MAX)
.plusDays(expireDays).toLocalDate();
LocalDate warnDate = expiredDate.minusDays(warnExpireDays);
//如果当前日期等于密码到期日期前几天的日期
if (LocalDate.now().equals(warnDate)) {
reminderNumber++;
long expiredDays = Duration.between(LocalDate.now().atTime(LocalTime.MIN),
expiredDate.atTime(LocalTime.MIN)).toDays();
//如果邮箱不为空,发送邮件通知
if (StringUtils.isNotBlank(entity.getEmail())) {
logger.info("开始提醒用户:{}", entity.getUsername());
HashMap<String, Object> map = Maps.newHashMap();
//查询两个时间的间距
map.put(EXPIRE_DAYS, expiredDays);
mailMsgEventPublish.publish(MailType.PASSWORD_SOON_EXPIRED_REMIND,
entity.getEmail(), map);
logger.info("结束提醒用户:{}", entity.getUsername());
}
// 短信通知
if (StringUtils.isNotBlank(entity.getPhone())) {
logger.info("开始提醒用户:{}", entity.getUsername());
LinkedHashMap<String, String> map = Maps.newLinkedHashMap();
// 查询两个时间的间距
map.put(EXPIRE_DAYS, String.valueOf(expiredDays));
smsMsgEventPublish.publish(SmsType.PASSWORD_SOON_EXPIRED_REMIND,
entity.getPhone(), map);
logger.info("结束提醒用户:{}", entity.getUsername());
}
for (UserEntity entity : list) {
//如果邮箱不为空,发送邮件通知
if (StringUtils.isNotBlank(entity.getEmail())) {
logger.info("开始提醒用户:{}", entity.getUsername());
//获取到期日期
LocalDate expiredDate = entity.getLastUpdatePasswordTime().atOffset(ZoneOffset.MAX)
.plusDays(expireDays).toLocalDate();
HashMap<String, Object> map = Maps.newHashMap();
//查询两个时间的间距
map.put(EXPIRE_DAYS, Duration.between(LocalDate.now(), expiredDate).toDays());
mailMsgEventPublish.publish(MailType.PASSWORD_SOON_EXPIRED_REMIND,
entity.getEmail(), map);
logger.info("结束提醒用户:{}", entity.getUsername());
}
// 短信通知
if (StringUtils.isNotBlank(entity.getPhone())) {
logger.info("开始提醒用户:{}", entity.getUsername());
// 获取到期日期
LocalDate expiredDate = entity.getLastUpdatePasswordTime().atOffset(ZoneOffset.MAX)
.plusDays(expireDays).toLocalDate();
LinkedHashMap<String, String> map = Maps.newLinkedHashMap();
// 查询两个时间的间距
map.put(EXPIRE_DAYS,
String.valueOf(Duration.between(LocalDate.now(), expiredDate).toDays()));
smsMsgEventPublish.publish(SmsType.PASSWORD_SOON_EXPIRED_REMIND, entity.getPhone(),
map);
logger.info("结束提醒用户:{}", entity.getUsername());
}
}
logger.info("密码过期前提醒任务结束, 提醒用户数量[{}], 耗时:[{}]s", reminderNumber,
(System.currentTimeMillis() - start) / 1000);
logger.info("密码过期前提醒任务结束");
}
/**
@ -169,9 +150,4 @@ public class PasswordExpireWarnTask implements PasswordExpireTask {
*
*/
private final SmsMsgEventPublish smsMsgEventPublish;
/**
* SupportProperties
*/
private final SupportProperties supportProperties;
}

View File

@ -21,7 +21,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -39,10 +38,7 @@ import cn.topiam.employee.audit.context.AuditContext;
import cn.topiam.employee.audit.entity.Target;
import cn.topiam.employee.audit.enums.TargetType;
import cn.topiam.employee.common.entity.account.*;
import cn.topiam.employee.common.repository.account.OrganizationMemberRepository;
import cn.topiam.employee.common.repository.account.OrganizationRepository;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.openapi.constant.OpenApiStatus;
import cn.topiam.employee.openapi.converter.account.OrganizationConverter;
import cn.topiam.employee.openapi.exception.OpenApiException;
@ -117,7 +113,6 @@ public class OrganizationServiceImpl implements OrganizationService {
Optional<OrganizationEntity> optional = this.organizationRepository.findById(param.getId());
if (optional.isPresent()) {
OrganizationEntity entity = optional.get();
String userIds;
//如果修改了名字,递归修改和该组织有关所有节点信息的展示路径
if (!optional.get().getName().equals(param.getName())) {
//修改名称
@ -127,22 +122,10 @@ public class OrganizationServiceImpl implements OrganizationService {
if (!entity.getLeaf()) {
recursiveUpdateDisplayPath(entity.getId(), entity.getId(), param.getName());
}
userIds = organizationRepository
.getOrgMemberList(organization.getId(), QUserEntity.userEntity.id).stream()
.map(String::valueOf).collect(Collectors.joining(","));
} else {
List<OrganizationMemberEntity> orgMemberList = organizationMemberRepository
.findAllByOrgId(entity.getId());
userIds = orgMemberList.stream().map(item -> String.valueOf(item.getUserId()))
.collect(Collectors.joining(","));
}
//修改
BeanUtils.merge(organization, entity, LAST_MODIFIED_BY, LAST_MODIFIED_TIME);
organizationRepository.save(entity);
// 更新用户es信息
if (StringUtils.isNotBlank(userIds)) {
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, userIds);
}
AuditContext.setTarget(
Target.builder().id(entity.getId()).type(TargetType.ORGANIZATION).build());
}
@ -309,25 +292,15 @@ public class OrganizationServiceImpl implements OrganizationService {
.orElseThrow(() -> new OpenApiException(OpenApiStatus.DEPARTMENT_NOT_EXIST));
}
private final JPAQueryFactory jpaQueryFactory;
private final JPAQueryFactory jpaQueryFactory;
/**
*
*/
private final OrganizationConverter organizationConverter;
private final OrganizationConverter organizationConverter;
/**
* OrganizationRepository
*/
private final OrganizationRepository organizationRepository;
/**
* UserMessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
/**
* OrganizationMemberRepository
*/
private final OrganizationMemberRepository organizationMemberRepository;
private final OrganizationRepository organizationRepository;
}

View File

@ -48,8 +48,6 @@ import cn.topiam.employee.common.repository.account.UserRepository;
import cn.topiam.employee.core.message.MsgVariable;
import cn.topiam.employee.core.message.mail.MailMsgEventPublish;
import cn.topiam.employee.core.message.sms.SmsMsgEventPublish;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.openapi.constant.OpenApiStatus;
import cn.topiam.employee.openapi.converter.account.UserConverter;
import cn.topiam.employee.openapi.exception.OpenApiException;
@ -115,8 +113,6 @@ public class UserServiceImpl implements UserService {
}
AuditContext.setTarget(Target.builder().id(id.toString()).type(TargetType.USER).build());
userRepository.updateUserStatus(id, status);
// 更新用户索引数据
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, String.valueOf(id));
}
/**
@ -168,9 +164,6 @@ public class UserServiceImpl implements UserService {
organizationMemberRepository.save(member);
AuditContext.setTarget(Target.builder().type(USER).id(user.getId().toString()).build(),
Target.builder().type(USER_DETAIL).id(detail.getId().toString()).build());
// 保存ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.valueOf(user.getId()));
// 发送短信和邮件的欢迎信息(密码通知)
UserCreateParam.PasswordInitializeConfig passwordInitializeConfig = param
.getPasswordInitializeConfig();
@ -266,9 +259,6 @@ public class UserServiceImpl implements UserService {
userDetailsRepository.save(detail);
AuditContext.setTarget(Target.builder().type(USER).id(user.getId().toString()).build(),
Target.builder().type(USER_DETAIL).id(detail.getId().toString()).build());
// 更新ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.valueOf(user.getId()));
}
/**
@ -294,8 +284,6 @@ public class UserServiceImpl implements UserService {
organizationMemberRepository.deleteByUserId(Long.valueOf(id));
//删除用户组用户详情
userGroupMemberRepository.deleteByUserId(Long.valueOf(id));
// 删除ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.DELETE, id);
}
@Override
@ -427,19 +415,13 @@ public class UserServiceImpl implements UserService {
*/
private final PasswordPolicyManager<UserEntity> passwordPolicyManager;
/**
* UserMessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
public UserServiceImpl(UserConverter userConverter, UserRepository userRepository,
OrganizationMemberRepository organizationMemberRepository,
UserGroupMemberRepository userGroupMemberRepository,
UserDetailRepository userDetailsRepository,
MailMsgEventPublish mailMsgEventPublish,
SmsMsgEventPublish smsMsgEventPublish,
PasswordPolicyManager<UserEntity> passwordPolicyManager,
UserMessagePublisher userMessagePublisher) {
PasswordPolicyManager<UserEntity> passwordPolicyManager) {
this.userConverter = userConverter;
this.userRepository = userRepository;
this.organizationMemberRepository = organizationMemberRepository;
@ -448,6 +430,5 @@ public class UserServiceImpl implements UserService {
this.mailMsgEventPublish = mailMsgEventPublish;
this.smsMsgEventPublish = smsMsgEventPublish;
this.passwordPolicyManager = passwordPolicyManager;
this.userMessagePublisher = userMessagePublisher;
}
}

View File

@ -70,7 +70,6 @@ import cn.topiam.employee.common.repository.authentication.IdentityProviderRepos
import cn.topiam.employee.common.repository.setting.SettingRepository;
import cn.topiam.employee.core.message.mail.MailMsgEventPublish;
import cn.topiam.employee.core.message.sms.SmsMsgEventPublish;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.security.form.FormLoginSecretFilter;
import cn.topiam.employee.core.security.otp.OtpContextHelp;
import cn.topiam.employee.core.security.password.task.PasswordExpireTask;
@ -83,7 +82,6 @@ import cn.topiam.employee.portal.security.handler.PortalAuthenticationSuccessHan
import cn.topiam.employee.portal.security.listener.PortalAuthenticationFailureEventListener;
import cn.topiam.employee.portal.security.listener.PortalAuthenticationSuccessEventListener;
import cn.topiam.employee.portal.security.listener.PortalLogoutSuccessEventListener;
import cn.topiam.employee.support.autoconfiguration.SupportProperties;
import cn.topiam.employee.support.geo.GeoLocationService;
import cn.topiam.employee.support.jackjson.SupportJackson2Module;
import cn.topiam.employee.support.security.authentication.WebAuthenticationDetailsSource;
@ -409,17 +407,12 @@ public class PortalSecurityConfiguration extends AbstractSecurityConfiguration
*
* @param settingRepository {@link SettingRepository}
* @param userRepository {@link UserRepository}
* @param supportProperties {@link SupportProperties}
* @param userMessagePublisher {@link UserMessagePublisher}
* @return {@link PasswordExpireTask}
*/
@Bean
public PasswordExpireTask passwordExpireLockTask(SettingRepository settingRepository,
UserRepository userRepository,
SupportProperties supportProperties,
UserMessagePublisher userMessagePublisher) {
return new PasswordExpireLockTask(settingRepository, userRepository, supportProperties,
userMessagePublisher);
UserRepository userRepository) {
return new PasswordExpireLockTask(settingRepository, userRepository);
}
@Bean
@ -445,10 +438,9 @@ public class PortalSecurityConfiguration extends AbstractSecurityConfiguration
public PasswordExpireTask passwordExpireWarnTask(SettingRepository settingRepository,
UserRepository userRepository,
MailMsgEventPublish mailMsgEventPublish,
SmsMsgEventPublish smsMsgEventPublish,
SupportProperties supportProperties) {
SmsMsgEventPublish smsMsgEventPublish) {
return new PasswordExpireWarnTask(settingRepository, userRepository, mailMsgEventPublish,
smsMsgEventPublish, supportProperties);
smsMsgEventPublish);
}
/**

View File

@ -52,8 +52,6 @@ import cn.topiam.employee.common.repository.account.UserIdpRepository;
import cn.topiam.employee.common.repository.account.UserRepository;
import cn.topiam.employee.common.repository.authentication.IdentityProviderRepository;
import cn.topiam.employee.core.message.sms.SmsMsgEventPublish;
import cn.topiam.employee.core.mq.UserMessagePublisher;
import cn.topiam.employee.core.mq.UserMessageTag;
import cn.topiam.employee.core.security.otp.OtpContextHelp;
import cn.topiam.employee.portal.converter.AccountConverter;
import cn.topiam.employee.portal.pojo.request.*;
@ -108,9 +106,6 @@ public class AccountServiceImpl implements AccountService {
toUserDetailsEntity.setId(detail.getId());
BeanUtils.merge(toUserDetailsEntity, detail, LAST_MODIFIED_BY, LAST_MODIFIED_TIME);
userDetailsRepository.save(detail);
// 更新ES用户信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.valueOf(detail.getId()));
return true;
}
@ -182,8 +177,6 @@ public class AccountServiceImpl implements AccountService {
}
Long id = Long.valueOf(SecurityUtils.getCurrentUser().getId());
userRepository.updateUserPhone(id, param.getPhone());
// 更新ES用户手机号信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE, String.valueOf(id));
// 修改手机号成功发送短信
LinkedHashMap<String, String> parameter = Maps.newLinkedHashMap();
parameter.put(USERNAME, user.getUsername());
@ -239,9 +232,6 @@ public class AccountServiceImpl implements AccountService {
}
userRepository.updateUserEmail(Long.valueOf(SecurityUtils.getCurrentUser().getId()),
param.getEmail());
// 更新ES用户邮箱信息
userMessagePublisher.sendUserChangeMessage(UserMessageTag.SAVE,
String.valueOf(user.getId()));
return true;
}
@ -476,11 +466,6 @@ public class AccountServiceImpl implements AccountService {
*/
private final UserIdpRepository userIdpRepository;
/**
* MessagePublisher
*/
private final UserMessagePublisher userMessagePublisher;
public AccountServiceImpl(AsyncConfigurer asyncConfigurer, AccountConverter accountConverter,
PasswordEncoder passwordEncoder, UserRepository userRepository,
UserDetailRepository userDetailsRepository,
@ -489,8 +474,7 @@ public class AccountServiceImpl implements AccountService {
StringRedisTemplate stringRedisTemplate,
PasswordPolicyManager<UserEntity> passwordPolicyManager,
IdentityProviderRepository identityProviderRepository,
UserIdpRepository userIdpRepository,
UserMessagePublisher userMessagePublisher) {
UserIdpRepository userIdpRepository) {
this.executor = asyncConfigurer.getAsyncExecutor();
this.accountConverter = accountConverter;
this.passwordEncoder = passwordEncoder;
@ -503,6 +487,5 @@ public class AccountServiceImpl implements AccountService {
this.passwordPolicyManager = passwordPolicyManager;
this.identityProviderRepository = identityProviderRepository;
this.userIdpRepository = userIdpRepository;
this.userMessagePublisher = userMessagePublisher;
}
}