Add profile prototype

This commit is contained in:
Denis Natusch 2023-11-01 12:32:54 +01:00 committed by Simon Bruder
parent eec4066dd0
commit 16f5ff20e3
Signed by: simon
GPG key ID: 8D3C82F9F309F8EC
8 changed files with 362 additions and 1 deletions

View file

@ -0,0 +1,102 @@
package catering.users;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.OneToOne;
import org.salespointframework.useraccount.UserAccount;
import org.salespointframework.core.AbstractAggregateRoot;
import catering.users.User.UserIdentifier;
import java.io.Serializable;
import java.util.UUID;
import org.jmolecules.ddd.types.Identifier;
@Entity
public class User extends AbstractAggregateRoot<UserIdentifier> {
private @EmbeddedId UserIdentifier id = new UserIdentifier();
private String address;
@OneToOne
private UserAccount userAccount;
@SuppressWarnings("unused")
private User() {}
public User(UserAccount userAccount,String address){
this.address = address;
this.userAccount = userAccount;
};
public String getAddress(){
return address;
}
public boolean setAddress(String address){
this.address = address;
return true;
// NOTE: the return type is boolean,
// because in the future we may want to check if the input is a real address
};
public String getUsername() {
return userAccount.getUsername();
};
public boolean setUsername(String name){
userAccount.setUsername(name);
return true;
}
public UserAccount getUserAccount(){
return this.userAccount;
}
@Override
public UserIdentifier getId() {
return id;
}
@Embeddable
public static final class UserIdentifier implements Identifier, Serializable {
private static final long serialVersionUID = 7740660930809051850L;
private final @SuppressWarnings("unused") UUID identifier;
UserIdentifier() {
this(UUID.randomUUID());
}
UserIdentifier(UUID identifier) {
this.identifier = identifier;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (identifier == null ? 0 : identifier.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof UserIdentifier that)) {
return false;
}
return this.identifier.equals(that.identifier);
}
}
}

View file

@ -0,0 +1,54 @@
package catering.users;
import org.springframework.ui.Model;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class UserController {
private final UserManagement userManagement;
UserController(UserManagement userManagerment){
this.userManagement = userManagerment;
};
@GetMapping("/profile")
public String index(Model model) {
model.addAttribute("user", userManagement.getUsers().findAll().toList().get(0));
return "profile";
}
@PostMapping("/profile")
public String editProfile(@RequestParam String password, @RequestParam String address, @RequestParam String username) {
User userAccount = userManagement.getUsers().findAll().toList().get(0);
if (!username.isBlank()){
userAccount.setUsername(username);
}
if (!address.isBlank()){
userAccount.setAddress(address);
}
if (!password.isBlank()){
userManagement.setPassword(password, userAccount.getUserAccount());
}
userManagement.save(userAccount);
return "redirect:/profile";
}
@GetMapping("/profile/delete")
public String deleteUser() {
User userAccount = userManagement.getUsers().findAll().toList().get(0);
userManagement.deleteUser(userAccount);
return "redirect:/";
}
}

View file

@ -0,0 +1,37 @@
package catering.users;
import org.salespointframework.core.DataInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.salespointframework.useraccount.AuthenticationManagement;
import org.springframework.web.bind.annotation.SessionAttributes;
@Component
@Order(10)
@SessionAttributes("profile")
class UserDataInitializer implements DataInitializer {
private static final Logger LOG = LoggerFactory.getLogger(UserDataInitializer.class);
private final UserManagement userManagement;
UserDataInitializer(UserManagement userManagement, AuthenticationManagement auth) {
Assert.notNull(userManagement, "UserRepository must not be null!");
this.userManagement = userManagement;
}
@Override
public void initialize() {
LOG.info("Creating default user.");
userManagement.createUser("Hans","123","Baum Weg");
}
}

View file

@ -0,0 +1,50 @@
package catering.users;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.salespointframework.useraccount.UserAccount;
import org.salespointframework.useraccount.Password.UnencryptedPassword;
import org.salespointframework.useraccount.Role;
import org.salespointframework.useraccount.UserAccountManagement;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
@SessionAttributes("profile")
public class UserManagement {
private final UserRepository users;
private final UserAccountManagement userAccounts;
UserManagement(UserRepository users, UserAccountManagement userAccounts) {
this.users = users;
this.userAccounts = userAccounts;
}
public User createUser(String name, String Password, String address) {
var password = UnencryptedPassword.of(Password);
var userAccount = userAccounts.create(name, password, Role.of("CUSTOMER"));
return users.save(new User(userAccount, address));
}
public User save(User user){
return users.save(user);
}
public boolean setPassword(String password, UserAccount userAccount) {
userAccounts.changePassword(userAccount, UnencryptedPassword.of(password));
return true;
};
public UserRepository getUsers(){
return users;
}
public void deleteUser(User user){
users.deleteById(user.getId());
}
}

View file

@ -0,0 +1,11 @@
package catering.users;
import catering.users.User.UserIdentifier;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.util.Streamable;
interface UserRepository extends CrudRepository<User, UserIdentifier> {
@Override
Streamable<User> findAll();
}

View file

@ -1,4 +1,4 @@
# ATTENTION:
# ATTENTION:
# Spring Boot expects this file to be UTF-8 encoded 👍 However, some IDEs will open it in
# the wrong mode. For example, IntelliJ users must go to Preferences > Editor > File Encodings
# and set "Default encoding for properties files" to "UTF-8".
@ -9,3 +9,13 @@
welcome.title = Welcome back!
welcome.text = If umlauts such as äöü are not displayed correctly, something is broken
profile.title = Dein Profil
profile.danger_zone = Danger Zone
profile.edit = Bearbeiten
profile.delete = Account löschen
profile.username = Nutzername
profile.password = Passwort
profile.address = Adresse
profile.authentification = Authentifikation
profile.userinformation = Nutzerinformationen

View file

@ -0,0 +1,57 @@
/* CSS RESET */
* {
margin: 0;
padding: 0;
}
body {
margin: 0 auto;
width: 940px;
font: 13px/22px Helvetica, Arial, sans-serif;
background: #f0f0f0;
}
h1 {
font-size: 3em;
line-height: 3.2em;
text-align:center;
}
table {
border-collapse: separate;
border-spacing: 5 2em;
padding: 20px;
padding-left: 50px;
font-size: 20px;
}
h2 {
margin: 10px;
}
th, td {
padding: 15px;
}
.horizontal_center {
display: flex;
justify-content: center;
align-items: center;
}
div.danger_zone {
margin-bottom: 50px;
}
button.danger_zone {
padding-top: 15px;
padding-bottom: 15px;
padding-right: 25px;
padding-left: 25px;
margin-left: 40px;
margin-right: 40px;
color: red;
border: 2px solid red;
border-radius: 4px;
}

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" th:href="@{/resources/css/profile/style.css}" />
<title th:text="#{profile.title}" />
</head>
<body>
<form th:action="@{/profile}" method="post" >
<h1 th:text="#{profile.title}"></h1>
<h2 class="settings" th:text="#{profile.authentification}"></h2>
<table>
<tr>
<td th:text="#{profile.username}"></td>
<td><input name="username" th:value="${user.username}" type="text"/></td>
</tr>
<tr>
<td th:text="#{profile.password}"></td>
<td><input name="password" type="password"/></td>
</tr>
</table>
<h2 class="settings" th:text="#{profile.userinformation}"></h2>
<table>
<tr>
<td th:text="#{profile.address}"></td>
<td><input name="address" th:value="${user.address}" type="text"/></td>
</tr>
</table>
<div class="danger_zone">
<h1 class="danger_zone" th:text="#{profile.danger_zone}"></h1>
<div class="horizontal_center">
<button class="danger_zone" th:text="#{profile.edit}" type="submit"></button>
<a th:href="@{/profile/delete}">
<button class="danger_zone" th:text="#{profile.delete}" type="button"></button>
</a>
</div>
</div>
</form>
</body>
</html>