Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// list the requests/endpoints need to be authenticated
.authorizeHttpRequests(auth -> auth
.requestMatchers("/authenticate").permitAll()
.requestMatchers("/mvc/person/update/**", "/mvc/person/delete/**").hasAnyAuthority("ROLE_PLAYER")
.requestMatchers("/api/person/delete/**").hasAnyAuthority("ROLE_PLAYER")
.requestMatchers("/reading").hasAnyAuthority("ROLE_ADMIN")
.requestMatchers("/mvc/person/update/**", "/mvc/person/delete/**").hasAnyAuthority("ROLE_ADMIN")
.requestMatchers("/api/person/delete/**").hasAnyAuthority("ROLE_ADMIN")
.requestMatchers("/**").permitAll()
)
// support cors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,60 @@
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.nighthawk.spring_portfolio.mvc.person.Person;
import com.nighthawk.spring_portfolio.mvc.person.PersonDetailsService;
import com.nighthawk.spring_portfolio.mvc.person.PersonJpaRepository;
@Controller // HTTP requests are handled as a controller, using the @Controller annotation
public class readcontroller {

@Autowired
private PersonJpaRepository repository;

// @GetMapping handles GET request for /greet, maps it to greeting() method
@GetMapping("/reading")
// @RequestParam handles variables binding to frontend, defaults, etc
public String read(@RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
@PreAuthorize("isAuthenticated()")

// model attributes are visible to Thymeleaf when HTML is "pre-processed"
model.addAttribute("person", name);
//@PreAuthorize("hasRole('ROLE_ADMIN')")
// @RequestParam handles variables binding to frontend, defaults, etc
public String person(Model model) {
List<Person> persons = repository.findAllByOrderByNameAsc();
model.addAttribute("persons", persons);
// System.out.println(persons.toString()); for testing purposes
return "reading";
}

// load HTML VIEW (greet.html)
return "reading";
@GetMapping("/delete/{id}")
public String deletePerson(@PathVariable Long id) {
if(id < 7)
{
System.out.println("can't delete admins!");
return "redirect:/reading";
}
else {
repository.deleteById(id);
return "redirect:/reading";
}
}


}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.nighthawk.spring_portfolio.controllers;
/* MVC code that shows defining a simple Model, calling View, and this file serving as Controller
* Web Content with Spring MVCSpring Example: https://spring.io/guides/gs/serving-web-con
*/

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.nighthawk.spring_portfolio.mvc.person.Person;
import com.nighthawk.spring_portfolio.mvc.person.PersonDetailsService;
import com.nighthawk.spring_portfolio.mvc.person.PersonJpaRepository;
@Controller // HTTP requests are handled as a controller, using the @Controller annotation
public class updatecontroller {

@Autowired
private PersonJpaRepository repository;

// @GetMapping handles GET request for /greet, maps it to greeting() method
@GetMapping("/updating")
@PreAuthorize("isAuthenticated()")
//@PreAuthorize("hasRole('ROLE_ADMIN')")
// @RequestParam handles variables binding to frontend, defaults, etc
public String person(Model model) {
List<Person> persons = repository.findAllByOrderByNameAsc();
model.addAttribute("persons", persons);
// System.out.println(persons.toString()); for testing purposes
return "reading";
}


}
2 changes: 1 addition & 1 deletion src/main/resources/templates/layouts/nav.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<div class="collapse navbar-collapse" id="login">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" th:href="@{/mvc/person/read/}">read<span class="sr-only"></span></a>
<a class="nav-link" th:href="@{/reading}">read<span class="sr-only"></span></a>
</li>
</ul>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/person/read.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ <h2>Person Viewer</h2>
</tr>
</thead>
<tbody>
<tr th:each="person : ${list}">
<tr th:each="person : ${persons}">
<td th:text="${person.id}">Person ID</td>
<td th:text="${person.email}">Birth Date</td>
<td th:text="${person.name}">Name</td>
Expand Down
21 changes: 10 additions & 11 deletions src/main/resources/templates/reading.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,28 @@

<div class="container py-4 text-light bg-success">

<h2>Person Viewer</h2>
<a th:href="@{/mvc/person/create/}">Create Person</a>
<h2>Person Viewer + console (cannot delete admins)</h2>
<a th:href="@{/creating}">Create Person</a>
<a th:href="@{/updating}">Update Person</a>
<a th:href="@{/deleting}">Delete Person</a>
<div class="row align-items-md-stretch">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>User ID</th>
<th>Email</th>
<th>Person</th>
<th>Age</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="person : ${list}">
<tr th:each="person : ${persons}">
<td th:text="${person.id}">Person ID</td>
<td th:text="${person.email}">Birth Date</td>
<td th:text="${person.email}">Birth Email</td>
<td th:text="${person.name}">Name</td>
<td th:if="${person.getAge() != -1}" th:text="${person.getAge()}">Age</td>
<td th:unless="${person.getAge() != -1}" th:text="Unknown">Unknown Age</td>
<td>
<a th:href="@{/delete/{id}(id=${person.id})}">Delete</a>
<a th:href="@{/update/{id}(id=${person.id})}">updating</a>
<!--- <a th:href="@{/mvc/notes/{id}(id = ${person.id})}">Notes</a> -->
<a th:href="@{/mvc/person/update/{id}(id = ${person.id})}">Update</a>
<a th:href="@{/mvc/person/delete/{id}(id = ${person.id})}">Delete</a>
</td>
</tr>
</tbody>
Expand All @@ -57,4 +55,5 @@ <h2>Person Viewer</h2>
</th:block>
</body>


</html>
89 changes: 89 additions & 0 deletions src/main/resources/templates/updating.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!-- This page is illustrative and contains ideas about HTML formatting -->
<!DOCTYPE HTML>
<!-- Signals to the Layout Dialect which layout should be used to decorate this View -->
<html xmlns:layout="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml"
layout:decorate="~{layouts/base}" lang="en">

<head>
<title>Person Update</title>
</head>

<body>
<th:block layout:fragment="body" th:remove="tag">
<!-- Page specific body additions -->
<div class="container">

<div class="row justify-content-md-center">
<h2>Welcome, Update The Persons Details</h2>
</div>

<div class="row justify-content-md-center">
<div class="col8">
<div class="jumbotron">
<!-- ThymeLeaf allows person abject of the Class Person to be acted upon by the form
This is known as a “bean-backed form” or "form-backing bean".
th:object - the backend form object (bean object)
There are two fields in the Person bean,
th:field="*{name}"
th:field="*{age}".
Each field has supporting line for to show errors in validation
th:errors - form input errors added when validation errors occur
Reference for CRUD
https://www.baeldung.com/spring-boot-crud-thymeleaf
Get started with dialects in 5 minutes
https://www.thymeleaf.org/doc/articles/standarddialect5minutes.html
Reference Bootstrap Form
https://getbootstrap.com/docs/4.0/components/forms/#readonly-plain-text
-->
<!--Read Only Section -->
<h3 th:text="'ID: ' + ${person.id}"></h3>
<table>
<tr th:if="${person.roles.empty}">
<td colspan="2"> No Roles </td>
</tr>
<tr th:each="role : ${person.roles}">
<td><span th:text="${role.name}"> Name </span></td>
</tr>
</table>
<!--Update Form -->
<form class="form-inline" action="#" th:action="@{/mvc/person/update}" th:object="${person}" method="POST">
<!-- Hidden Section, stuff we need to reference to preserve on Update -->
<div class="form-group mb-2 mr-sm-2">
<label for="id" hidden></label>
<input type="text" th:field="*{id}" id="id" hidden class="form-control-plaintext" >
<label for="roles" hidden></label>
<input type="text" th:field="*{roles}" id="roles" hidden class="form-control-plaintext" >
</div>
<!--Update Section -->
<div class="form-group mb-2 mr-sm-2">
<label for="email">Email:</label>
<input type="email" th:field="*{email}" id="email" >
<small th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email Error</small>
</div>
<div sec:authorize="hasRole('ADMIN')" class="form-group mb-2 mr-sm-2">
<label for="password">Password:</label>
<input type="password" th:field="*{password}" id="password">
<small th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Password Error</small>
</div>
<div class="form-group mb-2 mr-sm-2">
<label for="name">Name:</label>
<input type="text" th:field="*{name}" id="name">
<small th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</small>
</div>
<div class="form-group mb-2 mr-sm-2">
<label for="dob">Birth Date:</label>
<input type="date" th:field="*{dob}" id="dob">
<small th:if="${#fields.hasErrors('dob')}" th:errors="*{dob}">Birth Date Error</small>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
</div>
</div>
</div>
</div>

</th:block>
</body>


</html>