Use form for editing customer profile

This commit is contained in:
Denis Natusch 2024-01-06 20:34:15 +01:00
parent 6297f3c073
commit 13641bc6a2
No known key found for this signature in database
GPG key ID: 5E57BD8EDACFA985
4 changed files with 106 additions and 69 deletions

View file

@ -7,6 +7,8 @@ import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils; import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import catering.users.UserForm.UserFormWithPassword;
@Component @Component
public class FormValidator<F extends UserForm> implements Validator { public class FormValidator<F extends UserForm> implements Validator {
@ -22,6 +24,8 @@ public class FormValidator<F extends UserForm> implements Validator {
ValidationUtils.rejectIfEmptyOrWhitespace(e, "username", "username must not be empty"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "username", "username must not be empty");
ValidationUtils.rejectIfEmptyOrWhitespace(e, "address", "address must not be empty"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "address", "address must not be empty");
ValidationUtils.rejectIfEmptyOrWhitespace(e, "fullName", "fullName must not be empty"); ValidationUtils.rejectIfEmptyOrWhitespace(e, "fullName", "fullName must not be empty");
form.validatePassword(e); if (form instanceof UserFormWithPassword formWithPassword){
formWithPassword.validatePassword(e);
}
} }
} }

View file

@ -2,8 +2,9 @@
// SPDX-FileCopyrightText: 2023 swt23w23 // SPDX-FileCopyrightText: 2023 swt23w23
package catering.users; package catering.users;
import static catering.users.UserForm.RegistrationForm; import static catering.users.UserForm.UserFormWithPassword.RegistrationForm;
import static catering.users.UserForm.ProfileForm; import static catering.users.UserForm.UserFormWithPassword.ProfileForm;
import static catering.users.UserForm.AdminForm;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.salespointframework.useraccount.Role; import org.salespointframework.useraccount.Role;
import org.salespointframework.useraccount.UserAccount; import org.salespointframework.useraccount.UserAccount;
@ -41,6 +42,11 @@ public class UserController {
binder.setValidator(new FormValidator<RegistrationForm>()); binder.setValidator(new FormValidator<RegistrationForm>());
} }
@InitBinder("adminForm")
private void initAdminBinder(WebDataBinder binder) {
binder.setValidator(new FormValidator<AdminForm>());
}
@GetMapping("/unauthorized") @GetMapping("/unauthorized")
String unauthorized(){ String unauthorized(){
return "unauthorized"; return "unauthorized";
@ -124,16 +130,20 @@ public class UserController {
@GetMapping("/customers/edit/{id}") @GetMapping("/customers/edit/{id}")
@PreAuthorize("hasRole('ADMIN')") @PreAuthorize("hasRole('ADMIN')")
public String editCustomer(@PathVariable("id") User user, Model model) { public String editCustomer(@PathVariable("id") User user, Model model) {
model.addAttribute("customer", user); model.addAttribute("id", user.getId());
model.addAttribute("adminForm", new AdminForm(user.getUsername(), user.getAddress(), user.getFullName()));
return "edit-customer"; return "edit-customer";
} }
@PostMapping("/customers/edit/{id}") @PostMapping("/customers/edit/{id}")
@PreAuthorize("hasRole('ADMIN')") @PreAuthorize("hasRole('ADMIN')")
public String updateCustomer(@PathVariable("id") User user, @RequestParam String fullName, @RequestParam String username, @RequestParam String address) { public String updateCustomer(@PathVariable("id") User user, @Valid AdminForm form, Errors result) {
user.setUsername(username); if (result.hasErrors()){
user.setAddress(address); return "edit-customer";
user.setFullName(fullName); }
user.setUsername(form.getUsername());
user.setAddress(form.getAddress());
user.setFullName(form.getFullName());
userManagement.save(user); userManagement.save(user);
return "redirect:/customers"; return "redirect:/customers";
} }

View file

@ -15,13 +15,12 @@ import org.springframework.validation.Errors;
*/ */
public abstract class UserForm { public abstract class UserForm {
private final String username, address, fullName, password; private final String username, address, fullName;
public UserForm(String username, String address, String fullName, String password) { public UserForm(String username, String address, String fullName) {
this.username = username; this.username = username;
this.address = address; this.address = address;
this.fullName = fullName; this.fullName = fullName;
this.password = password;
} }
public String getUsername() { public String getUsername() {
@ -36,6 +35,17 @@ public abstract class UserForm {
return fullName; return fullName;
} }
/**
* An extension of {@link UserForm} with a password attribute.
*/
public abstract static class UserFormWithPassword extends UserForm {
private final String password;
public UserFormWithPassword(String username, String address, String fullName, String password) {
super(username, address, fullName);
this.password = password;
}
public String getPassword() { public String getPassword() {
return password; return password;
} }
@ -62,17 +72,17 @@ public abstract class UserForm {
public abstract void validatePasswordGeneric(Errors e); public abstract void validatePasswordGeneric(Errors e);
/** /**
* An extension of {@link UserForm} to validate input during registration. * An extension of {@link UserFormWithPassword} to validate input during registration.
* *
* It requires the password to be not empty. * It requires the password to be not empty.
*/ */
public static class RegistrationForm extends UserForm { public static class RegistrationForm extends UserFormWithPassword {
RegistrationForm(String username, String address, String fullName, String password) { RegistrationForm(String username, String address, String fullName, String password) {
super(username, address, fullName, password); super(username, address, fullName, password);
} }
public static RegistrationForm empty() { public static RegistrationForm empty() {
return new UserForm.RegistrationForm("", "", "", ""); return new UserFormWithPassword.RegistrationForm("", "", "", "");
} }
public void validatePasswordGeneric(Errors e) { public void validatePasswordGeneric(Errors e) {
@ -81,11 +91,11 @@ public abstract class UserForm {
} }
/** /**
* An extension of {@link UserForm} to validate input during profile editing. * An extension of {@link UserFormWithPassword} to validate input during profile editing.
* *
* The password can be empty. * The password can be empty.
*/ */
public static class ProfileForm extends UserForm { public static class ProfileForm extends UserFormWithPassword {
ProfileForm(String username, String address, String fullName, String password) { ProfileForm(String username, String address, String fullName, String password) {
super(username, address, fullName, password); super(username, address, fullName, password);
} }
@ -96,4 +106,14 @@ public abstract class UserForm {
} }
} }
} }
}
/**
* An extension of {@link UserForm} to validate input during customer profile editing.
*/
public static class AdminForm extends UserForm {
AdminForm(String username, String address, String fullName) {
super(username, address, fullName);
}
}
} }

View file

@ -11,20 +11,23 @@ SPDX-FileCopyrightText: 2023 swt23w23
</head> </head>
<body> <body>
<div layout:fragment="content"> <div layout:fragment="content">
<form method="post"> <form th:object="${adminForm}" th:action="@{/customers/edit/{id}(id=${id})}" method="post">
<div class="mb-3"> <div class="mb-3">
<label class="form-label" for="username">Nutzername</label> <label class="form-label" for="username">Nutzername</label>
<input class="form-control" type="text" name="username" th:value="${customer.username}"/> <input class="form-control" th:field="*{username}" th:errorclass="is-invalid" type="text" required>
<div th:if="${#fields.hasErrors('username')}" class="invalid-feedback">Ungültiger Nutzername</div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label" for="fullName">Name</label> <label class="form-label" for="fullName">Name</label>
<input class="form-control" type="fullName" name="fullName" th:value="${customer.fullName}"/> <input class="form-control" th:field="*{fullName}" th:errorclass="is-invalid" type="text" required>
<div th:if="${#fields.hasErrors('fullName')}" class="invalid-feedback">Ungültiger Name</div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label" for="address">Adresse</label> <label class="form-label" for="address">Adresse</label>
<textarea class="form-control" name="address" th:text="${customer.address}" rows="3" required></textarea> <textarea class="form-control" th:field="*{address}" th:errorclass="is-invalid" th:placeholder="*{address}" rows="3" required></textarea>
<div th:if="${#fields.hasErrors('address')}" class="invalid-feedback">Ungültige Addresse</div>
</div> </div>
<button class="btn btn-primary" type="submit">Speichern</button> <button class="btn btn-primary" type="submit">Bearbeiten</button>
</form> </form>
</div> </div>
</body> </body>