package eu.eudat.logic.managers; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserToken; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; import eu.eudat.exceptions.emailconfirmation.TokenExpiredException; import eu.eudat.logic.builders.entity.UserTokenBuilder; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.models.data.security.Principal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.transaction.Transactional; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @Component public class UnlinkEmailConfirmationManager { private static Logger logger = LoggerFactory.getLogger(UnlinkEmailConfirmationManager.class); private ApiContext apiContext; private DatabaseRepository databaseRepository; @Autowired public UnlinkEmailConfirmationManager(ApiContext apiContext) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); } @Transactional public void confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { EmailConfirmation loginConfirmationEmail = apiContext.getOperationsContext() .getDatabaseRepository().getLoginConfirmationEmailDao().asQueryable() .where((builder, root) -> builder.equal(root.get("token"), UUID.fromString(token))).getSingle(); if (loginConfirmationEmail.getExpiresAt().compareTo(new Date()) < 0) throw new TokenExpiredException("Token has expired."); if(loginConfirmationEmail.getIsConfirmed()) throw new HasConfirmedEmailException("Email is already confirmed."); // UserInfo userAskingForUnlink = databaseRepository.getUserInfoDao().asQueryable() // .where((builder, root) -> builder.equal(root.get("id"), loginConfirmationEmail.getUserId())).getSingle(); try { Map map = new ObjectMapper().readValue(loginConfirmationEmail.getData(), new TypeReference>() {}); String emailTobeUnlinked = (String) map.get("email"); Integer provider = Integer.valueOf((String) map.get("provider")); unlinkUser(emailTobeUnlinked, provider); loginConfirmationEmail.setIsConfirmed(true); databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); } catch (Exception e) { logger.error(e.getMessage(), e); } } @Transactional private void unlinkUser(String emailTobeUnlinked, Integer provider){ Credential credential = databaseRepository.getCredentialDao().asQueryable() .where((builder, root) -> builder.and(builder.equal(root.get("email"), emailTobeUnlinked), builder.equal(root.get("provider"), provider))).getSingle(); if(credential != null) { databaseRepository.getCredentialDao().delete(credential); } } public void sendConfirmationEmail(String email, Principal principal, UUID userId, Integer provider) { UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); if (user.getEmail() != null && !user.getEmail().equals(email)) { apiContext.getUtilitiesService().getConfirmationEmailService().createUnlinkConfirmationEmail( databaseRepository.getLoginConfirmationEmailDao(), apiContext.getUtilitiesService().getMailService(), email, userId, principal, provider ); } } }