@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private OldPasswordsService oldPasswordsService;
Optional<OldPasswords> list = oldPasswordsService.findEncryptedPassword(passwordEncoder.encode("new password entered form web reset form"));
OldPasswords value = list.get();
boolean matches = passwordEncoder.matches("new password entered form web reset form", value.getEncryptedPassword());
if (matches)
{
return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
}
else
{
OldPasswords oldPasswords = new OldPasswords();
oldPasswords.setEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
oldPasswordsService.save(oldPasswords);
}
Table for old passwords:
@Table(name = "old_passwords")
public class OldPasswords implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
@Column(name = "encrypted_password", length = 255)
private String encryptedPassword;
@Column(name = "password_owner_id", length = 4)
private Integer passwordOwnerId;
@Column(name = "created_at")
@Convert(converter = LocalDateTimeConverter.class)
private LocalDateTime createdAt;
But I get java.util.NoSuchElementException: No value present.
Do you know how I can implement a logic which compares old and new passwords?
EDIT: I tried this design:
SQL query:
public List<OldPasswords> findByOwnerId(Integer ownerId) {
String hql = "select e from " + OldPasswords.class.getName() + " e where e.passwordOwnerId = :passwordOwnerId ORDER BY e.createdAt DESC";
TypedQuery<OldPasswords> query = entityManager.createQuery(hql, OldPasswords.class).setMaxResults(3).setParameter("passwordOwnerId", ownerId);
List<OldPasswords> list = query.getResultList();
return list;
}
Endpoint:
@PostMapping("reset_password")
public ResponseEntity<?> reset(@RequestBody PasswordResetDTO resetDTO) {
return this.userService.findByLogin(resetDTO.getName()).map(user -> {
Integer userId = user.getId();
List<OldPasswords> list = oldPasswordsService.findByOwnerId(userId);
if(!list.isEmpty() && !list.isEmpty()) {
for (int i = 0; i<list.size(); i++){
OldPasswords value = list.get(i);
boolean matches = passwordEncoder.matches(resetDTO.getPassword(), value.getEncryptedPassword());
if (matches) {
return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
}
}
}
OldPasswords oldPasswords = new OldPasswords();
oldPasswords.setEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
oldPasswords.setPasswordOwnerId(userId);
oldPasswordsService.save(oldPasswords);
user.setEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
user.setResetPasswordToken(null);
userService.save(user);
return ok().build();
}).orElseGet(() -> notFound().build());
}
But when I change the code several times with the same password the error PASSWORD_ALREADY_USED is not shown.