Неожиданное возвращаемое значение - PullRequest
0 голосов
/ 12 марта 2020

Я пытаюсь осуществить сравнение паролей. Сначала я попробовал это:

@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()));
                oldPasswords.setCreatedAt(LocalDateTime.now());
                oldPasswordsService.save(oldPasswords);
            }

Таблица для старых паролей:

@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;

Я попытался реализовать это:

......
return this.userService.findByLogin(resetDTO.getName()).map(user -> {
            Optional<OldPasswords> list = oldPasswordsService.findEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
            list.ifPresent(value -> {
                boolean matches = passwordEncoder.matches(resetDTO.getPassword(), value.getEncryptedPassword());
                if (matches) {
                    return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
                }
            }).orElse(() -> {
                OldPasswords oldPasswords = new OldPasswords();
                oldPasswords.setEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
                oldPasswordsService.save(oldPasswords);
            });
         return ok().build();

}).orElseGet(() -> notFound().build());
}

Но я получаю для этой строки:

return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);

Ошибка

Unexpected return value

Знаете, как я могу это исправить?

1 Ответ

1 голос
/ 13 марта 2020

Это это вероятно 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...