This commit is contained in:
Zastian Pretorius
2022-08-29 19:32:02 +01:00
parent 7ab3526d50
commit d664201875
28 changed files with 346 additions and 10 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

18
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="registration-login-spring-boot-security-thymeleaf" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="registration-login-spring-boot-security-thymeleaf" options="-parameters" />
</option>
</component>
</project>

6
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
</component>
</project>

20
.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

6
.idea/jpa-buddy.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JpaBuddyIdeaProjectConfig">
<option name="defaultUnitInitialized" value="true" />
</component>
</project>

15
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="18" project-jdk-type="JavaSDK" />
<component name="ProjectType">
<option name="id" value="jpab" />
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -41,7 +41,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() http.authorizeRequests()
.antMatchers("/admin").hasRole("ADMIN") .antMatchers(
"/admin",
"/deleteEmployee",
"/showFormForUpdate",
"/saveUser")
.hasRole("ADMIN")
.antMatchers( .antMatchers(
"/registration**", "/registration**",
"/js/**", "/js/**",

View File

@@ -1,10 +1,19 @@
package net.javaguides.springboot.service; package net.javaguides.springboot.service;
import org.springframework.data.domain.Page;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import net.javaguides.springboot.model.User; import net.javaguides.springboot.model.User;
import net.javaguides.springboot.web.dto.UserRegistrationDto; import net.javaguides.springboot.web.dto.UserRegistrationDto;
import java.util.List;
public interface UserService extends UserDetailsService{ public interface UserService extends UserDetailsService{
User save(UserRegistrationDto registrationDto); User save(UserRegistrationDto registrationDto);
List<User> getAllUsers();
Page<User> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);
User getUserById(long id);
void deleteUserById(long id);
void saveUser(User user);
} }

View File

@@ -2,9 +2,15 @@ package net.javaguides.springboot.service;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
@@ -53,4 +59,41 @@ public class UserServiceImpl implements UserService{
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList()); return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList());
} }
@Override
public Page<User> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection) {
Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortField).ascending() :
Sort.by(sortField).descending();
Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
return this.userRepository.findAll(pageable);
}
@Override
public List<User> getAllUsers() {
return userRepository.findAll();
}
@Override
public User getUserById(long id) {
Optional<User> optional = userRepository.findById(id);
User user = null;
if (optional.isPresent()) {
user = optional.get();
} else {
throw new RuntimeException(" Employee not found for id :: " + id);
}
return user;
}
@Override
public void deleteUserById(long id) {
this.userRepository.deleteById(id);
}
@Override
public void saveUser(User user) {
this.userRepository.save(user);
}
} }

View File

@@ -1,10 +1,28 @@
package net.javaguides.springboot.web; package net.javaguides.springboot.web;
import net.javaguides.springboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
import net.javaguides.springboot.model.User;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import net.javaguides.springboot.service.UserService;
@Controller @Controller
public class MainController { public class MainController {
@Autowired
private UserService userService;
@GetMapping("/login") @GetMapping("/login")
public String login() { public String login() {
@@ -13,11 +31,43 @@ public class MainController {
@GetMapping("/") @GetMapping("/")
public String home() { public String home() {
return "index"; return "index";
} }
@GetMapping("/admin") @GetMapping("/admin")
public String admin() { public String admin(Model model) {
List<User> listUsers = userService.getAllUsers();
model.addAttribute("listUsers", listUsers);
return "admin"; return "admin";
} }
@GetMapping("/deleteEmployee/{id}")
public String deleteEmployee(@PathVariable (value = "id") long id) {
// call delete employee method
this.userService.deleteUserById(id);
return "redirect:/admin";
}
@GetMapping("/showFormForUpdate/{id}")
public String showFormForUpdate(@PathVariable ( value = "id") long id, Model model) {
User user = userService.getUserById(id);
model.addAttribute("user",user);
return "update_user";
}
@PostMapping("/saveUser")
public String saveUser(@ModelAttribute("employee") User user) {
// save employee to database
userService.saveUser(user);
return "redirect:/";
}
} }

View File

@@ -37,9 +37,26 @@
<br> <br>
<br> <br>
<div class="container"> <table class="table table-dark">
<h1>The good shit</h1> <thead>
Welcome <span sec:authentication="principal.username"> Admin</span> <tr>
</div> <th scope="col">#</th>
<th scope="col">FirstName</th>
<th scope="col">LastName</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${listUsers}">
<th th:text="${user.id}"></th>
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
<td th:text="${user.email}"></td>
<td> <a th:href="@{/showFormForUpdate/{id}(id=${user.id})}" class="btn btn-primary">Update</a>
<a th:href="@{/deleteEmployee/{id}(id=${user.id})}" class="btn btn-danger">Delete</a>
</td>
</tr>
</tbody>
</table>
</body> </body>
</html> </html>

View File

@@ -29,6 +29,7 @@
<div id="navbar" class="collapse navbar-collapse"> <div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li sec:authorize="isAuthenticated()"><a th:href="@{/logout}">Logout</a></li> <li sec:authorize="isAuthenticated()"><a th:href="@{/logout}">Logout</a></li>
<li sec:authorize="isAuthenticated()"><a th:href="@{/admin}">Admin</a></li>
</ul> </ul>
</div> </div>
</div> </div>
@@ -41,8 +42,6 @@
<h1>Registration and Login with Spring Boot, Spring Security, <h1>Registration and Login with Spring Boot, Spring Security,
Thymeleaf, Hibernate and MySQL</h1> Thymeleaf, Hibernate and MySQL</h1>
Welcome <span sec:authentication="principal.username"> User</span> Welcome <span sec:authentication="principal.username"> User</span>
<button type="button" class="btn btn-primary"
th:href="@{/admin}">admin</button>
</div> </div>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Employee Management System</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Employee Management System</h1>
<hr>
<h2>Update Employee</h2>
<form action="#" th:action="@{/saveUser}" th:object="${user}"
method="POST" th:href="@{/admin}">
<!-- Add hidden form field to handle update -->
<input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{firstName}" class="form-control mb-4 col-4">
<input type="text" th:field="*{lastName}" class="form-control mb-4 col-4">
<input type="text" th:field="*{email}" class="form-control mb-4 col-4">
<input type="text" th:field="*{password}" class="form-control mb-4 col-4">
<button type="submit" class="btn btn-info col-2" th:href = "@{/admin}"> Update User</button>
</form>
<hr>
<a th:href = "@{/admin}"> Back to User List</a>
</div>
</body>
</html>

View File

@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<meta charset="ISO-8859-1">
<title>Registration and Login App</title>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
</head>
<body>
<!-- create navigation bar ( header) -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#navbar" aria-expanded="false"
aria-controls="navbar">
<span class="sr-only">Toggle navigation</span> <span
class="icon-bar"></span> <span class="icon-bar"></span> <span
class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#" th:href="@{/}">Registration and
Login Module</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li sec:authorize="isAuthenticated()"><a th:href="@{/logout}">Logout</a></li>
</ul>
</div>
</div>
</nav>
<br>
<br>
<table class="table table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">FirstName</th>
<th scope="col">LastName</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${listUsers}">
<th th:text="${user.id}"></th>
<td th:text="${user.firstName}"></td>
<td th:text="${user.lastName}"></td>
<td th:text="${user.email}"></td>
<td> <a th:href="@{/showFormForUpdate/{id}(id=${user.id})}" class="btn btn-primary">Update</a>
<a th:href="@{/deleteEmployee/{id}(id=${user.id})}" class="btn btn-danger">Delete</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@@ -29,6 +29,7 @@
<div id="navbar" class="collapse navbar-collapse"> <div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li sec:authorize="isAuthenticated()"><a th:href="@{/logout}">Logout</a></li> <li sec:authorize="isAuthenticated()"><a th:href="@{/logout}">Logout</a></li>
<li sec:authorize="isAuthenticated()"><a th:href="@{/admin}">Admin</a></li>
</ul> </ul>
</div> </div>
</div> </div>
@@ -41,8 +42,6 @@
<h1>Registration and Login with Spring Boot, Spring Security, <h1>Registration and Login with Spring Boot, Spring Security,
Thymeleaf, Hibernate and MySQL</h1> Thymeleaf, Hibernate and MySQL</h1>
Welcome <span sec:authentication="principal.username"> User</span> Welcome <span sec:authentication="principal.username"> User</span>
<button type="button" class="btn btn-primary"
th:href="@{/admin}">admin</button>
</div> </div>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Employee Management System</title>
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Employee Management System</h1>
<hr>
<h2>Update Employee</h2>
<form action="#" th:action="@{/saveUser}" th:object="${user}"
method="POST" th:href="@{/admin}">
<!-- Add hidden form field to handle update -->
<input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{firstName}" class="form-control mb-4 col-4">
<input type="text" th:field="*{lastName}" class="form-control mb-4 col-4">
<input type="text" th:field="*{email}" class="form-control mb-4 col-4">
<input type="text" th:field="*{password}" class="form-control mb-4 col-4">
<button type="submit" class="btn btn-info col-2" th:href = "@{/admin}"> Update User</button>
</form>
<hr>
<a th:href = "@{/admin}"> Back to User List</a>
</div>
</body>
</html>