From aec02f027afebe466697e71b94ae80af1cb73f7e Mon Sep 17 00:00:00 2001 From: Dmitry Isaenko Date: Sat, 30 Dec 2023 22:27:48 +0300 Subject: [PATCH] Add form for creating users to ManageUsers page. Fix delete users bug, add login-in-use validations --- .../marinesco/AdministatorAddUserForm.java | 35 ++++++++++++++ src/main/java/ru/redrise/marinesco/User.java | 6 +-- .../security/ManageUsersController.java | 46 +++++++++++++++---- .../security/RegistrationController.java | 12 +++-- .../resources/templates/manage_users.html | 29 +++++++++++- .../resources/templates/registration.html | 2 + 6 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 src/main/java/ru/redrise/marinesco/AdministatorAddUserForm.java diff --git a/src/main/java/ru/redrise/marinesco/AdministatorAddUserForm.java b/src/main/java/ru/redrise/marinesco/AdministatorAddUserForm.java new file mode 100644 index 0000000..57ed0b8 --- /dev/null +++ b/src/main/java/ru/redrise/marinesco/AdministatorAddUserForm.java @@ -0,0 +1,35 @@ +package ru.redrise.marinesco; + +import org.springframework.security.crypto.password.PasswordEncoder; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Data; +import ru.redrise.marinesco.data.RolesRepository; +import ru.redrise.marinesco.security.UserRole; + +//TODO: refactor along with RegistrationForm.java +@Data +public class AdministatorAddUserForm { + + @NotNull + @Size(min=3, max=32, message="Username must be at least 3 characters long. Should not exceed 32 characters.") + private String username; + + @NotNull + @Size(min=8, max = 32, message="Password must be at least 8 characters long. Should not exceed 32 characters.") + private String password; + + @NotNull + @NotEmpty(message = "Display name could not be blank") + private String displayname; + + public User toUser(PasswordEncoder passwordEncoder, RolesRepository rolesRepo){ + return new User( + username, + passwordEncoder.encode(password), + displayname, + rolesRepo.findByType(UserRole.Type.USER)); + } +} diff --git a/src/main/java/ru/redrise/marinesco/User.java b/src/main/java/ru/redrise/marinesco/User.java index 6de9738..bc95d06 100644 --- a/src/main/java/ru/redrise/marinesco/User.java +++ b/src/main/java/ru/redrise/marinesco/User.java @@ -2,21 +2,19 @@ package ru.redrise.marinesco; import java.util.List; +import org.hibernate.annotations.ManyToAny; import org.springframework.security.core.userdetails.UserDetails; -import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.ManyToMany; import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.Data; import lombok.NoArgsConstructor; -import lombok.val; import ru.redrise.marinesco.security.UserRole; @Data @@ -37,7 +35,7 @@ public class User implements UserDetails{ private String password; private String displayname; - @ManyToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER) + @ManyToAny(fetch = FetchType.EAGER) private final List authorities; public User(String username, String password, String displayname, List authorities){ diff --git a/src/main/java/ru/redrise/marinesco/security/ManageUsersController.java b/src/main/java/ru/redrise/marinesco/security/ManageUsersController.java index 0e238fe..43d0fff 100644 --- a/src/main/java/ru/redrise/marinesco/security/ManageUsersController.java +++ b/src/main/java/ru/redrise/marinesco/security/ManageUsersController.java @@ -4,19 +4,23 @@ import java.util.ArrayList; import java.util.List; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.validation.Errors; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import ru.redrise.marinesco.AdministatorAddUserForm; import ru.redrise.marinesco.User; import ru.redrise.marinesco.UserGenerified; +import ru.redrise.marinesco.data.RolesRepository; import ru.redrise.marinesco.data.UserRepository; - //TODO @Slf4j @Controller @@ -24,10 +28,16 @@ import ru.redrise.marinesco.data.UserRepository; @PreAuthorize("hasRole('ADMIN')") public class ManageUsersController { - private UserRepository userRepository; + private final UserRepository userRepository; + private final RolesRepository rolesRepository; + private final PasswordEncoder passwordEncoder; - public ManageUsersController(UserRepository userRepository){ + public ManageUsersController(UserRepository userRepository, + RolesRepository rolesRepository, + PasswordEncoder passwordEncoder) { this.userRepository = userRepository; + this.rolesRepository = rolesRepository; + this.passwordEncoder = passwordEncoder; } @ModelAttribute(name = "userGenerified") @@ -36,18 +46,19 @@ public class ManageUsersController { } @ModelAttribute - public void addTitle(Model model){ + public void addTitle(Model model) { model.addAttribute("header_text", "Manage users"); + model.addAttribute("administatorAddUserForm", new AdministatorAddUserForm()); } @ModelAttribute - public void addUsers(Model model){ + public void addUsers(Model model) { Iterable users = userRepository.findAll(); List usersGen = new ArrayList<>(); - for (User user : users){ - usersGen.add(new UserGenerified(user)); // TODO: ADD ARRAY INSTEAD OF ONE! + for (User user : users) { + usersGen.add(new UserGenerified(user)); } - model.addAttribute("USR", usersGen); // TODO: ADD ARRAY INSTEAD OF ONE! + model.addAttribute("USR", usersGen); } @GetMapping @@ -56,11 +67,28 @@ public class ManageUsersController { } @PostMapping("/delete") - public String processDelete(UserGenerified userGenerified){ + public String processDelete(UserGenerified userGenerified) { log.info(userGenerified.toString()); userRepository.deleteById(userGenerified.getId()); return "redirect:/manage_users"; } + + @PostMapping + public String processNewUser(@Valid AdministatorAddUserForm form, Errors errors, Model model) { + if (userRepository.findByUsername(form.getUsername()) != null) { + model.addAttribute("loginOccupied", "Login already in use. Please choose another one"); + return "manage_users"; + } + if (errors.hasErrors()) { + log.info(errors.getAllErrors().toString()); + return "manage_users"; + } + + User user = userRepository.save(form.toUser(passwordEncoder, rolesRepository)); + log.info("Added user {} {} {}", user.getId(), user.getUsername(), user.getDisplayname()); + // Reloads page therefore new records appears + return "redirect:/manage_users"; + } } diff --git a/src/main/java/ru/redrise/marinesco/security/RegistrationController.java b/src/main/java/ru/redrise/marinesco/security/RegistrationController.java index cefd8c7..c06ab0d 100644 --- a/src/main/java/ru/redrise/marinesco/security/RegistrationController.java +++ b/src/main/java/ru/redrise/marinesco/security/RegistrationController.java @@ -46,19 +46,23 @@ public class RegistrationController { } @PostMapping - public String postMethodName(@Valid RegistrationForm registerForm, Errors errors, Model model) { - if (registerForm.isPasswordsNotEqual()) { + public String postMethodName(@Valid RegistrationForm form, Errors errors, Model model) { + if (form.isPasswordsNotEqual()) { model.addAttribute("passwordsMismatch", "Passwords must be the same."); return "registration"; } + if (userRepo.findByUsername(form.getUsername()) != null){ + model.addAttribute("loginOccupied", "Login already in use. Please choose another one"); + return "registration"; + } if (errors.hasErrors()) { return "registration"; } - User user = userRepo.save(registerForm.toUser(passwordEncoder, rolesRepo)); + User user = userRepo.save(form.toUser(passwordEncoder, rolesRepo)); log.info("Added user {} {} {}", user.getId(), user.getUsername(), user.getDisplayname()); - if (registerForm.auth(request)) + if (form.auth(request)) return "redirect:/"; return "redirect:/login"; } diff --git a/src/main/resources/templates/manage_users.html b/src/main/resources/templates/manage_users.html index 5f9e7d4..51ffa08 100644 --- a/src/main/resources/templates/manage_users.html +++ b/src/main/resources/templates/manage_users.html @@ -26,10 +26,37 @@ - +
+
+ Add user +
+ pew + Error +
+ +
+ + Error +
+ +
+ Error +
+ +
+ +

+ +

+ +
+
diff --git a/src/main/resources/templates/registration.html b/src/main/resources/templates/registration.html index 7f2fbee..7ba740d 100644 --- a/src/main/resources/templates/registration.html +++ b/src/main/resources/templates/registration.html @@ -14,6 +14,8 @@

Register

+ pew Error