Это это вероятно List
! Итак, с:
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private OldPasswordsService oldPasswordsService;
... и
@Autowired
private UserXXXService userService;
... предположим, вы на самом деле пытаетесь:
@RequestMapping(...)
public ResponseEntity<String> resetPassword(ResetPasswordDTO dto) {
...
... это как бы я пробалби go об этом:
final Optional<User> user = this.userService.findByLogin(dto.getName()); // Optional or null?, let's assume Optional
// if user (login) exists:
if(user.isPresent()) {
// check old passwords, the method name/data structure lets assume it's rather List than Optional:
java.util.List<OldPasswords> list = oldPasswordsService.findEncryptedPassword(passwordEncoder.encode(dto.getPassword()));
if(list.isEmpty()) {// list is empty...
// do your things..
OldPasswords oP= new OldPasswords();
oP.setEncryptedPassword(passwordEncoder.encode(dto.getPassword()));
oldPasswordsService.save(oP);
return ResonseEntity.ok().build(); // ok!
} else {// otherwise:
return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
}
} else { // otherwise (user.login not exists)
return ResponseEntity<>.notFound().build();
}
}
(ни проверено, ни скомпилировано)
.. один технический вопрос / деталь остается / скрыт: я скучаю по "связыванию" из " user "and" old_password "... так, стоит ли проверять старые пароли одного пользователя или всех?
1-й звучит более справедливо / правильно: старые пароли должны быть «основаны на пользователях»:
@Entity
// some unique constraints, when you have..., would be nice
public class OldPasswords implements Serializable { // singular is better for entity/table names!
....
@ManyToOne
@JoinColumn("user_id") // if you don't want to map the entity (for some reasons), you should still map the "id".
private User user;
// getter/setter ...
}
...
(с наименьшим влиянием, ) тогда вы могли бы:
public interface OldPasswordsRepository extends Repository<OldPasswords, Integer> { // <- Integer ???
List<OldPasswords> findByUserAndEncryptedPassword(User user, String pwd); // to use that...
}
РЕДАКТИРОВАТЬ : Для сопоставления с последними тремя паролями, @Peter, вашей структуре данных требуется (дополнительно к user
) некоторая «подстройка» - как created
timestamp !;) (лучший выбор, чем «столбец версии / возраста»)
@Column(nullable = false) // final + instantiation is suited here
final Date created = new Date(); //long, LocalDateTime, DateTime... Timestamp, java.sql.Date... and many alternatives.
// getter
.. тогда вы могли бы (в хранилище):
// untested!
List<OldPasswords> findTop3ByUserOrderByCreatedDesc(User user);
..и использовать его в контроллере / сервисе, например:
... // if user is present
List<OldPasswords> list = oldPasswordsRpository.findTop3ByUserOrderByCreatedDesc(user);
for(OldPasswords opw:list) {
// compare opw to dto.getPasword if match: return "bad request"
}
// after that (no bad request), store new (& old) password... (everywhere relevant),
// ...and when nothing fails:
return ResponseEntity.ok().build();
// else: user not present -> return not found