From 506a474819c5f6b653072b59b567b315b9b22c65 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Fri, 25 Feb 2022 22:18:05 +0100 Subject: [PATCH] Added change password page. --- pom.xml | 2 +- .../coyotecredit/ctl/user/UserPage.java | 18 +++++++++--- .../ctl/user/dto/ChangePasswordPayload.java | 6 ++++ .../nl/andrewl/coyotecredit/model/User.java | 2 +- .../coyotecredit/service/UserService.java | 28 +++++++++++++++++++ .../templates/exchange/create_account.html | 2 +- src/main/resources/templates/user.html | 4 +++ .../templates/user/change_password.html | 24 ++++++++++++++++ 8 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 src/main/java/nl/andrewl/coyotecredit/ctl/user/dto/ChangePasswordPayload.java create mode 100644 src/main/resources/templates/user/change_password.html diff --git a/pom.xml b/pom.xml index 677d35d..17d80df 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ nl.andrewl coyotecredit - 1.3.1 + 1.3.2 coyotecredit Banking and stock trading application to teach students. diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/user/UserPage.java b/src/main/java/nl/andrewl/coyotecredit/ctl/user/UserPage.java index a18e064..e4560fd 100644 --- a/src/main/java/nl/andrewl/coyotecredit/ctl/user/UserPage.java +++ b/src/main/java/nl/andrewl/coyotecredit/ctl/user/UserPage.java @@ -1,15 +1,13 @@ package nl.andrewl.coyotecredit.ctl.user; import lombok.RequiredArgsConstructor; +import nl.andrewl.coyotecredit.ctl.user.dto.ChangePasswordPayload; import nl.andrewl.coyotecredit.model.User; import nl.andrewl.coyotecredit.service.UserService; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.*; @Controller @RequestMapping(path = "/users/{userId}") @@ -22,4 +20,16 @@ public class UserPage { model.addAttribute("user", userService.getUser(userId, user)); return "user"; } + + @GetMapping(path = "/changePassword") + public String getChangePasswordPage(@PathVariable long userId, @AuthenticationPrincipal User user) { + userService.ensureCanChangePassword(user, userId); + return "user/change_password"; + } + + @PostMapping(path = "/changePassword") + public String postChangePassword(@PathVariable long userId, @AuthenticationPrincipal User user, @ModelAttribute ChangePasswordPayload payload) { + userService.changePassword(user, userId, payload); + return "redirect:/users/" + userId; + } } diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/user/dto/ChangePasswordPayload.java b/src/main/java/nl/andrewl/coyotecredit/ctl/user/dto/ChangePasswordPayload.java new file mode 100644 index 0000000..e85ac2b --- /dev/null +++ b/src/main/java/nl/andrewl/coyotecredit/ctl/user/dto/ChangePasswordPayload.java @@ -0,0 +1,6 @@ +package nl.andrewl.coyotecredit.ctl.user.dto; + +public record ChangePasswordPayload( + String currentPassword, + String newPassword +) {} diff --git a/src/main/java/nl/andrewl/coyotecredit/model/User.java b/src/main/java/nl/andrewl/coyotecredit/model/User.java index ddf78b6..8a87463 100644 --- a/src/main/java/nl/andrewl/coyotecredit/model/User.java +++ b/src/main/java/nl/andrewl/coyotecredit/model/User.java @@ -30,7 +30,7 @@ public class User implements UserDetails { @Column(nullable = false, unique = true) private String username; - @Column(nullable = false) + @Column(nullable = false) @Setter private String passwordHash; @Column(nullable = false) diff --git a/src/main/java/nl/andrewl/coyotecredit/service/UserService.java b/src/main/java/nl/andrewl/coyotecredit/service/UserService.java index f754bdf..abcb75a 100644 --- a/src/main/java/nl/andrewl/coyotecredit/service/UserService.java +++ b/src/main/java/nl/andrewl/coyotecredit/service/UserService.java @@ -3,6 +3,7 @@ package nl.andrewl.coyotecredit.service; import lombok.RequiredArgsConstructor; import nl.andrewl.coyotecredit.ctl.exchange.dto.InvitationData; import nl.andrewl.coyotecredit.ctl.dto.RegisterPayload; +import nl.andrewl.coyotecredit.ctl.user.dto.ChangePasswordPayload; import nl.andrewl.coyotecredit.ctl.user.dto.UserData; import nl.andrewl.coyotecredit.ctl.user.dto.UserNotificationData; import nl.andrewl.coyotecredit.dao.*; @@ -164,4 +165,31 @@ public class UserService { } notificationRepository.saveAll(notifications); } + + @Transactional(readOnly = true) + public void ensureCanChangePassword(User user, long userId) { + User changingUser = userRepository.findById(userId) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + if (!(user.isAdmin() || user.getId().equals(changingUser.getId()))) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + } + + @Transactional + public void changePassword(User user, long userId, ChangePasswordPayload payload) { + User changingUser = userRepository.findById(userId) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); + if (!(user.isAdmin() || user.getId().equals(changingUser.getId()))) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + if (!passwordEncoder.matches(payload.currentPassword(), changingUser.getPasswordHash())) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Current password is incorrect."); + } + if (payload.currentPassword().equals(payload.newPassword())) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "New password is the same as the current password."); + } + changingUser.setPasswordHash(passwordEncoder.encode(payload.newPassword())); + userRepository.save(changingUser); + notificationRepository.save(new UserNotification(changingUser, "Your password has just been updated.")); + } } diff --git a/src/main/resources/templates/exchange/create_account.html b/src/main/resources/templates/exchange/create_account.html index ef9ed8e..07b7a91 100644 --- a/src/main/resources/templates/exchange/create_account.html +++ b/src/main/resources/templates/exchange/create_account.html @@ -2,7 +2,7 @@

Create Account

diff --git a/src/main/resources/templates/user.html b/src/main/resources/templates/user.html index a84971e..428abf9 100644 --- a/src/main/resources/templates/user.html +++ b/src/main/resources/templates/user.html @@ -62,4 +62,8 @@
+ +
+ Change Password +
diff --git a/src/main/resources/templates/user/change_password.html b/src/main/resources/templates/user/change_password.html new file mode 100644 index 0000000..99f4ca8 --- /dev/null +++ b/src/main/resources/templates/user/change_password.html @@ -0,0 +1,24 @@ + + +
+

Change Password

+

+ Change the password to your account. +

+
+
+ + + You must enter your current password to confirm your access to the account. +
+
+ + +
+ +
+