CommonAccountValidator.java
package io.featureprobe.api.auth;
import io.featureprobe.api.base.enums.MemberSourceEnum;
import io.featureprobe.api.base.enums.MemberStatusEnum;
import io.featureprobe.api.base.enums.OperationType;
import io.featureprobe.api.base.enums.OrganizationRoleEnum;
import io.featureprobe.api.base.model.OrganizationMemberModel;
import io.featureprobe.api.dao.entity.Member;
import io.featureprobe.api.dao.entity.OperationLog;
import io.featureprobe.api.dao.entity.Organization;
import io.featureprobe.api.dao.entity.OrganizationMember;
import io.featureprobe.api.dao.repository.OrganizationRepository;
import io.featureprobe.api.service.MemberService;
import io.featureprobe.api.service.OperationLogService;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Component("common")
@AllArgsConstructor
public class CommonAccountValidator implements AccountValidator {
private MemberService memberService;
private OrganizationRepository organizationRepository;
private OperationLogService operationLogService;
@Override
public Authentication authenticate(Authentication authentication) {
UserPasswordAuthenticationToken token = (UserPasswordAuthenticationToken) authentication;
if (StringUtils.isNotBlank(token.getAccount()) && StringUtils.isNotBlank(token.getPassword())) {
Optional<Member> memberOptional = memberService.findByAccount(token.getAccount());
OperationLog log = new OperationLog(OperationType.LOGIN.name() + "_" + token.getSource(),
token.getAccount());
if (!memberOptional.isPresent() || isAccessTokenNumber(memberOptional)) {
throw new UsernameNotFoundException("Account not found.");
}
Member member = memberOptional.get();
Member immutableMember = new Member();
BeanUtils.copyProperties(member, immutableMember);
if (!MemberStatusEnum.ACTIVE.name().equals(member.getStatus().name())) {
throw new BadCredentialsException("Credentials are incorrect.");
}
if (CollectionUtils.isEmpty(member.getOrganizations())) {
if (token.isInitializeOrganization()) {
Organization organization = Organization.createDefaultOrganization();
organization = organizationRepository.save(organization);
List<OrganizationMember> organizationMembers = new ArrayList<>(1);
organizationMembers.add(
new OrganizationMember(organization, member, OrganizationRoleEnum.OWNER,
true, null));
member.setOrganizationMembers(organizationMembers);
member = memberService.save(member);
} else {
throw new OrganizationEmptyException("Organization is empty.");
}
}
boolean passwordMatched = new BCryptPasswordEncoder().matches(token.getPassword(),
member.getPassword());
boolean organizationChecked = true;
OrganizationMemberModel organizationMemberModel = null;
if (StringUtils.isNotBlank(token.getOrganizationId())) {
Long organizationId = Long.parseLong(token.getOrganizationId());
for (OrganizationMember organizationMember : member.getOrganizationMembers()) {
if (organizationMember.getOrganization().getId().equals(organizationId)) {
Organization organization = organizationMember.getOrganization();
organizationMemberModel = new OrganizationMemberModel(organization.getId(),
organization.getName(), organizationMember.getRole());
}
}
if (Objects.isNull(organizationMemberModel)) {
throw new BadCredentialsException("Credentials are incorrect.");
}
}
if (Objects.isNull(organizationMemberModel)) {
OrganizationMember organizationMember = member.getOrganizationMembers().get(0);
organizationMemberModel = new OrganizationMemberModel(organizationMember.getOrganization().getId(),
organizationMember.getOrganization().getName(), organizationMember.getRole());
}
if (organizationChecked && passwordMatched) {
memberService.updateLoginTime(member, organizationMemberModel.getOrganizationId());
operationLogService.save(log);
return new UserPasswordAuthenticationToken(AuthenticatedMember.create(immutableMember,
organizationMemberModel), Collections.emptyList());
}
}
throw new BadCredentialsException("Credentials are incorrect.");
}
private boolean isAccessTokenNumber(Optional<Member> member) {
return StringUtils.equalsIgnoreCase(member.get().getSource(), MemberSourceEnum.ACCESS_TOKEN.name());
}
}