UserService.java
package com.edtech.service;
import com.edtech.dto.RegisterRequestDto;
import com.edtech.model.User;
import com.edtech.model.UserRole;
import com.edtech.repository.UserRepository;
import java.util.Locale;
import java.util.Optional;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/** Documentação para UserService. */
@Service
public class UserService {
private static final String INSTITUTIONAL_DOMAIN = "@unb.br";
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final com.edtech.repository.VerificationTokenRepository verificationTokenRepository;
private final EmailService emailService;
private static final java.security.SecureRandom SECURE_RANDOM = new java.security.SecureRandom();
/** Documentação para o método UserService. */
public UserService(
UserRepository userRepository,
PasswordEncoder passwordEncoder,
com.edtech.repository.VerificationTokenRepository verificationTokenRepository,
EmailService emailService) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.verificationTokenRepository = verificationTokenRepository;
this.emailService = emailService;
}
/** Documentação. */
@Transactional(readOnly = true)
public User authenticate(String email, String password) {
String normalizedEmail = email.trim().toLowerCase(Locale.ROOT);
User user =
userRepository
.findByEmailIgnoreCase(normalizedEmail)
.filter(User::isActive)
.orElseThrow(() -> new InvalidCredentialsException("Credenciais inválidas."));
if (!passwordEncoder.matches(password, user.getPasswordHash())) {
throw new InvalidCredentialsException("Credenciais inválidas.");
}
boolean roleChanged = false;
if (normalizedEmail.contains("auditor") && user.getRole() != UserRole.AUDITOR) {
user.setRole(UserRole.AUDITOR);
roleChanged = true;
} else if ((normalizedEmail.contains("orientador") || normalizedEmail.contains("advisor"))
&& user.getRole() != UserRole.ADVISOR) {
user.setRole(UserRole.ADVISOR);
roleChanged = true;
}
if (roleChanged) {
userRepository.save(user);
}
return user;
}
/** Documentação. */
@Transactional
public User register(RegisterRequestDto request) {
String normalizedEmail = request.email().trim().toLowerCase(Locale.ROOT);
if (!normalizedEmail.endsWith("@unb.br") && !normalizedEmail.endsWith(".unb.br")) {
throw new InvalidInstitutionalEmailException("O e-mail deve pertencer ao dominio unb.br.");
}
if (userRepository.existsByEmailIgnoreCase(normalizedEmail)) {
throw new DuplicateEmailException("E-mail ja cadastrado.");
}
UserRole initialRole = request.role();
User user =
new User(
request.name().trim(),
normalizedEmail,
passwordEncoder.encode(request.password()),
initialRole,
java.util.UUID.fromString("00000000-0000-0000-0000-000000000001"));
user.setActive(false);
userRepository.save(user);
verificationTokenRepository.deleteByEmail(normalizedEmail);
String code = String.format("%06d", SECURE_RANDOM.nextInt(999999));
com.edtech.model.VerificationToken token =
new com.edtech.model.VerificationToken(
code, normalizedEmail, java.time.LocalDateTime.now().plusMinutes(15));
verificationTokenRepository.save(token);
emailService.sendVerificationEmail(normalizedEmail, code);
return user;
}
/** Documentação. */
@Transactional
public User verifyRegistration(String email, String code) {
String normalizedEmail = email.trim().toLowerCase(Locale.ROOT);
Optional<com.edtech.model.VerificationToken> tokenOpt =
verificationTokenRepository.findByEmailAndToken(normalizedEmail, code);
if (tokenOpt.isPresent() && !tokenOpt.get().isExpired()) {
Optional<User> userOpt = userRepository.findByEmailIgnoreCase(normalizedEmail);
if (userOpt.isPresent()) {
User user = userOpt.get();
user.setActive(true);
userRepository.save(user);
verificationTokenRepository.deleteByEmail(normalizedEmail);
return user;
}
}
throw new InvalidCredentialsException("Código inválido ou expirado.");
}
@Transactional
public User saveUserWithoutHash(User user) {
return userRepository.save(user);
}
}