Spring Boot Hibernate не может удалить токен подтверждения - PullRequest
0 голосов
/ 07 мая 2020

Используя весеннюю загрузку, Java и спящий режим.

Проще говоря, я могу подтвердить пользователя, отправить электронное письмо с подтверждением, и когда пользователь перейдет по ссылке, они будут отправлены по электронной почте. Он переводит их на страницу подтверждения. На этой странице они перенаправляются в зависимости от того, вошли они в систему или нет, и были ли они проверены ранее или нет.

Каждый экземпляр, токен должен быть удален. Я не знаю, что я делаю неправильно в коде.

Это VerifyController

import com.blah.app.models.Alert;
import com.blah.app.models.AlertType;
import com.blah.app.models.entities.User;
import com.blah.app.models.entities.VerificationToken;
import com.blah.app.repositories.UserRepository;
import com.blah.app.repositories.VerificationTokenRepository;
import java.util.Base64;
import java.util.Collections;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@AllArgsConstructor
@Controller
@Slf4j
@RequestMapping("/user-verification")
public class VerificationController {

  private final MessageSource messageSource;
  private final HttpServletRequest request;
  private final VerificationTokenRepository verificationTokenRepository;
  private final UserRepository userRepository;


  @GetMapping
  public String verificationRedirect(@RequestParam("token") String token,
                                     RedirectAttributes redirectAttributes) {

Base64.Decoder decoder = Base64.getDecoder();
UUID uuidToken = UUID.fromString(new String(decoder.decode(token)));


Optional<VerificationToken> optionalVerificationToken =
    this.verificationTokenRepository.findByToken(uuidToken);

if (optionalVerificationToken.isPresent()) {
  VerificationToken verificationToken = optionalVerificationToken.get();
  User user = verificationToken.getUser();


  if (user.isEnabled() == true) {
    //user enabled

    if (request.getUserPrincipal() != null) {
    //user signed in and enable
      this.verificationTokenRepository.delete(verificationToken);

      Alert alert = Alert.builder()
          .type(AlertType.WARNING)
          .message(this.messageSource
              .getMessage("messages.verifiedAlready", null, 
LocaleContextHolder.getLocale()))
          .closable(true)
          .build();
      redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));
      this.verificationTokenRepository.delete(verificationToken);

      return "redirect:app";
    } else {
      //user signed out and enabled
      this.verificationTokenRepository.delete(verificationToken);

      Alert alert = Alert.builder()
          .type(AlertType.WARNING)
          .message(this.messageSource
              .getMessage("messages.verifiedAlreadySignedOut", null,
                  LocaleContextHolder.getLocale()))
          .closable(true)
          .build();

      redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));

      return "redirect:sign-in";
    }

  } else {
    //user not enabled


    if (request.getUserPrincipal() != null) {
      //user is signed in
  //        FIXME: needs to redirect to app
      user.setEnabled(true);
      this.verificationTokenRepository.delete(verificationToken);


      Alert alert = Alert.builder()
          .type(AlertType.SUCCESS)
          .message(this.messageSource
              .getMessage("messages.verificationSuccess", null,
                  LocaleContextHolder.getLocale()))
          .closable(true)
          .build();

      redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));

      return "redirect:app";
    } else {
      //uesr not signed in
      user.setEnabled(true);
      this.verificationTokenRepository.delete(verificationToken);
      Alert alert = Alert.builder()
          .type(AlertType.SUCCESS)
          .message(this.messageSource
              .getMessage("messages.verificationSuccessSignedOut", null,
                  LocaleContextHolder.getLocale()))
          .closable(true)
          .build();
      redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));

      return "redirect:sign-in";
    }


  }
  }
  Alert alert = Alert.builder()
    .type(AlertType.WARNING)
    .message(this.messageSource
        .getMessage("messages.verifiedInvalidToken", null, LocaleContextHolder.getLocale()))
    .closable(true)
    .build();

redirectAttributes.addFlashAttribute("alerts", Collections.singletonList(alert));

return "redirect:sign-in";
   }
}


User entity



import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import lombok.Getter;
import lombok.Setter;

 @Getter
 @Setter
 @Entity
 @Table(name = "user_account")
 public class User extends BaseEntity {

  @Column(columnDefinition = "text")
  private String forename;

  @Column(columnDefinition = "text")
  private String surname;

  @Column(nullable = false, columnDefinition = "text", unique=true)
  private String email;

  @Transient
  private String password;

  @Transient
  private String confirmPassword;

  @Column(nullable = false, length = 60)
  private String passwordHash;

  @Column(name = "enabled")
  private boolean enabled;

  public User() {
    super();
    this.enabled=false;
  }

  @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  private List<UserRole> roles;

  @OneToOne(cascade=CascadeType.ALL, mappedBy="user")
  private VerificationToken verificationToken;

};

объект токена проверки

import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToOne;
import javax.persistence.Table;


import lombok.Getter;
import lombok.Setter;

@Getter
@Entity
@Setter
@Table(name = "user_verification_token")
public class VerificationToken extends BaseEntity  {

  @Column(updatable = false, nullable = false)
  private UUID token;

  @OneToOne(optional = false)
  private User user;

}

1 Ответ

0 голосов
/ 07 мая 2020

Исправлено, полностью удалив каскад, изначально я добавил каскад к токену проверки вот так ..

 @OneToOne(cascade=CascadeType.ALL, optional = false)
  private User user;

Это, конечно, означало, что удаление токена удаляло пользователя. Когда я удалил каскад, это позволило удалить токен без удаления пользователя.

  @OneToOne(optional = false)
      private User user;


 @OneToOne( mappedBy="user")
  private VerificationToken verificationToken;
...