diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java index ed1b8e747..907ceac18 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java @@ -1,50 +1,90 @@ package eu.eudat.logic.managers; +import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.LoginConfirmationEmail; 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.services.ApiContext; +import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.models.data.security.Principal; +import eu.eudat.queryable.QueryableList; +import eu.eudat.queryable.jpa.predicates.OrderByPredicate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; +import java.util.List; import java.util.UUID; @Component public class EmailConfirmationManager { private ApiContext apiContext; + private DatabaseRepository databaseRepository; @Autowired public EmailConfirmationManager(ApiContext apiContext) { this.apiContext = apiContext; + this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); } public void confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { LoginConfirmationEmail 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."); - UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().asQueryable() + + UserInfo user = databaseRepository.getUserInfoDao().asQueryable() .where((builder, root) -> builder.equal(root.get("id"), loginConfirmationEmail.getUserId())).getSingle(); + if (user.getEmail() != null) throw new HasConfirmedEmailException("User already has confirmed his Email."); + loginConfirmationEmail.setIsConfirmed(true); + + // Checks if mail is used by another user. If it is, merges the new the old. + UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle(); + if (oldUser != null) { + mergeNewUserToOld(user, oldUser); + expireUserToken(user); + databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); + return; + } + user.setEmail(loginConfirmationEmail.getEmail()); - apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().createOrUpdate(user); - apiContext.getOperationsContext().getDatabaseRepository().getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); + databaseRepository.getUserInfoDao().createOrUpdate(user); + databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); } public void sendConfirmationEmail(String email, Principal principal) throws HasConfirmedEmailException { UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); if (user.getEmail() != null) throw new HasConfirmedEmailException("User already has confirmed his Email."); + apiContext.getUtilitiesService().getConfirmationEmailService().createConfirmationEmail( - apiContext.getOperationsContext().getDatabaseRepository().getLoginConfirmationEmailDao(), + databaseRepository.getLoginConfirmationEmailDao(), apiContext.getUtilitiesService().getMailService(), email, - principal.getId()); + principal.getId() + ); + } + + private void mergeNewUserToOld(UserInfo newUser, UserInfo oldUser) { + Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), newUser)).getSingle(); + credential.setUserInfo(oldUser); + databaseRepository.getCredentialDao().createOrUpdate(credential); + } + + private void expireUserToken(UserInfo user) { + UserToken userToken = databaseRepository.getUserTokenDao().asQueryable() + .where((builder, root) -> builder.equal(root.get("user"), user)) + .orderBy((builder, root) -> builder.desc(root.get("issuedAt"))) + .take(1) + .getSingle(); + userToken.setExpiresAt(new Date()); + databaseRepository.getUserTokenDao().createOrUpdate(userToken); } }