override fun updatePassword(userPrincipal: UserPrincipal, request: UpdatePasswordRequest): Any {
val user = userRepository.findByIdOrNull(userPrincipal.id) ?: throw ModelNotFoundException ("UserId", userPrincipal.id)
if (!passwordEncoder.matches(request.oldPassword, user.password)) {
throw IllegalArgumentException ("비밀번호가 틀렸습니다.")
}
if (passwordEncoder.matches(request.newPassword, request.confirmPassword)) {
throw IllegalArgumentException("새 비밀번호와 확인 비밀번호가 다릅니다.")
}
if (user.oldPasswords.any { passwordEncoder.matches(request.newPassword, it)}) {
throw IllegalStateException("3회 안에 사용되었던 비밀번호를 재사용할 수 없습니다.")
}
user.password = passwordEncoder.encode(request.newPassword)
user.oldPasswords.add(user.password)
if (user.oldPasswords.size > 3) {
user.oldPasswords.removeAt(0)
}
userRepository.save(user)
return "비밀번호 변경 완료"
}
이전 비밀번호를 관리할 수 있는 기능을 추가했다.
검증 과정을 모두 마치면, UserEntity의 oldPasswords 리스트에 변경한 비밀번호를 추가한다.
UserEntity에는 아래와 같이 추가했다.
@ElementCollection
@CollectionTable(name = "user_old_passwords", joinColumns = [JoinColumn(name="user_id")])
@Column(name = "old_passwords")
val oldPasswords: MutableList<String> = mutableListOf(),
@ElementCollection
해당 필드가 '컬렉션'이라는 것을 의미한다.
컬렉션은 여러 값을 담을 수 있는 자료형을 뜻하며,
MutableList<String>
이니 여러개의 문자 열을 담을 수 있다.
@CollectionTable
이 어노테이션은 컬렉션에 대한 별도의 테이블을 연결할 때 사용한다.
기존 @Table
과 동일하지만 컬렉션을 테이블로 저장하겠다는 뜻이다.
JoinColumns = [JoinColumn(name="user_id")]
를 통해
어떤 다른 테이블과 연결된 상태인 지를 설명해 주었다.
1) 사용자의 이전 비밀번호를 저장하는 oldPasswords라는 컬럼을 가진
user_old_passwords라는 테이블과 연결했고,
2) 이 테이블은 user_id라는 컬럼을 통해 다른 테이블과 연결된다
각 사용자 별 이전에 사용했던 비밀번호들을 따로 저장할 수 있게 설정했다.
각 비밀번호는 passwordEncoder로 암호화 된 상태로 저장하며,
passwordEncoder를 사용하여 일치 여부를 확인해야 한다.