Labwork06 MVC is done.

This commit is contained in:
Yuee Shiness 2023-06-17 03:50:47 +04:00
parent 9d4f79f1ae
commit 475875c357
26 changed files with 392 additions and 164 deletions

Binary file not shown.

View File

@ -16,6 +16,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.214'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'junit:junit:4.13.2'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-devtools'

Binary file not shown.

View File

@ -1,52 +0,0 @@
package ru.ulstu.is.sbapp.Customer.Controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import ru.ulstu.is.sbapp.WebConfiguration;
import java.util.List;
@RestController
@RequestMapping(WebConfiguration.REST_API + "/customer")
@ControllerAdvice(annotations = RestController.class)
public class CustomerController {
private final CustomerService customerService;
public CustomerController(CustomerService customerService)
{
this.customerService = customerService;
}
@GetMapping("/{id}")
public CustomerDTO getCustomer(@PathVariable Long id) {
return new CustomerDTO(customerService.findCustomer(id));
}
@GetMapping
public List<CustomerDTO> getCustomers() {
return customerService.findAllCustomers().stream().map(CustomerDTO::new).toList();
}
@PostMapping
public CustomerDTO createCustomer(@RequestParam("fullName") String fullName, @RequestParam("password") String password ) {
return new CustomerDTO(customerService.addCustomer(fullName,password));
}
@PutMapping("/{id}")
public CustomerDTO updateCustomer(@PathVariable Long id, @RequestParam("fullName") String fullName) {
return new CustomerDTO(customerService.updateCustomer(id,fullName));
}
@DeleteMapping("/{id}")
public CustomerDTO deleteCustomer(@PathVariable Long id) {
return new CustomerDTO(customerService.deleteCustomer(id));
}
@GetMapping("/movies/{customerId}")
public List<MovieDTO> getCustomerMovies(@PathVariable("customerId") Long customerId) {
return customerService.findCustomerMovies(customerId).stream()
.map(MovieDTO::new)
.toList();
}
}

View File

@ -2,6 +2,7 @@ package ru.ulstu.is.sbapp.Customer.Controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import java.util.List;
@ -10,11 +11,13 @@ public class CustomerDTO {
private final long id;
private final String username;
private final String password;
private final CustomerRole role;
private final List<MovieDTO> movies;
public CustomerDTO(Customer customer) {
this.id = customer.getId();
this.username = customer.getUsername();
this.password = customer.getPassword();
this.role = customer.getRole();
this.movies = customer.getMovies().stream().map(MovieDTO::new).toList();
}
@ -31,6 +34,10 @@ public class CustomerDTO {
return password;
}
public CustomerRole getRole() {
return role;
}
public List<MovieDTO> getMovies() {
return movies;
}

View File

@ -0,0 +1,41 @@
package ru.ulstu.is.sbapp.Customer.Controller;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import javax.persistence.Column;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class CustomerSignupDTO {
@NotBlank(message = "Username can't be null or empty")
@Size(min = 3, max = 64)
private String username;
@NotBlank(message = "Password can't be empty")
@Size(min = 6, max = 64)
private String password;
private CustomerRole role;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public CustomerRole getRole() {
return role;
}
public void setRole(CustomerRole role) {
this.role = role;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -1,14 +1,23 @@
package ru.ulstu.is.sbapp.Customer.MVC;
import org.aspectj.lang.annotation.RequiredTypes;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Customer.Controller.CustomerDTO;
import ru.ulstu.is.sbapp.Customer.Controller.CustomerSignupDTO;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import ru.ulstu.is.sbapp.Utilities.CookiesManagement;
import ru.ulstu.is.sbapp.Utilities.validation.ValidationException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
@Controller
@ -23,22 +32,34 @@ public class CustomerMVC {
this.cookiesManagement = new CookiesManagement();
}
@GetMapping("/{id}")
public String getCustomer(@PathVariable Long id, Model model) {
model.addAttribute("customer",new CustomerDTO(customerService.findCustomer(id)));
return "customer-details";
@GetMapping
public String showSignupForm(Model model) {
model.addAttribute("customerDTO", new CustomerSignupDTO());
return "Registration";
}
@GetMapping
public String getCustomers(Model model) {
model.addAttribute("customers", customerService.findAllCustomers().stream().map(CustomerDTO::new).toList());
return "Login";
@GetMapping("/find/{username}")
public Long findCustomer(@PathVariable String username) {
return customerService.findByLogin(username).getId();
}
@PostMapping
public String createCustomer(@RequestParam("fullName") String fullName, @RequestParam("password") String password ) {
customerService.addCustomer(fullName,password);
return "redirect:/customer";
public String createCustomer(@ModelAttribute("customerDTO") @Valid CustomerSignupDTO customerSignupDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "Registration";
}
try {
final Customer customer = customerService.createCustomer(
customerSignupDTO.getUsername(), customerSignupDTO.getPassword(),customerSignupDTO.getRole());
return "redirect:/Login?created=" + customer.getUsername();
} catch (ValidationException e) {
model.addAttribute("errors", e.getMessage());
return "Registration";
}
}
@PutMapping("/{id}")
@ -53,13 +74,22 @@ public class CustomerMVC {
}
@GetMapping("/movies")
public String getCustomerMovies(HttpServletRequest request, Model model) {
public String getCustomerMovies(Model model) {
Long userId = Long.parseLong(cookiesManagement.GetUserID(request));
model.addAttribute("movies", customerService.findCustomerMovies(userId).stream()
String username = null;
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
if (principal instanceof UserDetails) {
username = ((UserDetails)principal). getUsername();
} else {
username = principal. toString();
}
model.addAttribute("movies", customerService.findCustomerMovies(customerService.findByLogin(username).getId()).stream()
.map(MovieDTO::new)
.toList());
model.addAttribute("customerId",userId);
model.addAttribute("customerId",customerService.findByLogin(username).getId());
return "Librarypage";
}

View File

@ -8,6 +8,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
@Entity
public class Customer
@ -15,12 +16,16 @@ public class Customer
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
@Column(nullable = false, unique = true, length = 64)
@NotBlank(message = "Username can't be null or empty")
@Size(min = 3, max = 64)
private String username;
@Column
@Column(nullable = false, length = 64)
@NotBlank(message = "Password can't be empty")
@Size(min = 6, max = 64)
private String password;
private CustomerRole role;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Movie> movies;
@ -29,14 +34,15 @@ public class Customer
{
}
public Customer(String username,String password)
public Customer(String username,String password,CustomerRole role)
{
this.username = username;
this.password = password;
this.role = role;
this.movies = new ArrayList<>();
}
public Long getId()
{
return id;
@ -48,6 +54,10 @@ public class Customer
return username;
}
public CustomerRole getRole() {
return role;
}
public void setUsername(String username)
{
this.username = username;

View File

@ -0,0 +1,20 @@
package ru.ulstu.is.sbapp.Customer.Model;
import org.springframework.security.core.GrantedAuthority;
public enum CustomerRole implements GrantedAuthority {
ADMIN,
USER;
private static final String PREFIX = "ROLE_";
@Override
public String getAuthority() {
return PREFIX + this.name();
}
public static final class AsString {
public static final String ADMIN = PREFIX + "ADMIN";
public static final String USER = PREFIX + "USER";
}
}

View File

@ -4,4 +4,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
public interface CustomerRepository extends JpaRepository<Customer, Long> {
Customer findOneByUsernameIgnoreCase(String login);
}

View File

@ -1,53 +1,67 @@
package ru.ulstu.is.sbapp.Customer.Service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import ru.ulstu.is.sbapp.Utilities.validation.ValidationException;
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
import javax.persistence.EntityNotFoundException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
@Service
public class CustomerService
public class CustomerService implements UserDetailsService
{
private final CustomerRepository customerRepository;
private final PasswordEncoder passwordEncoder;
private final ValidatorUtil validatorUtil;
public CustomerService(CustomerRepository customerRepository, ValidatorUtil validatorUtil) {
public CustomerService(CustomerRepository customerRepository, ValidatorUtil validatorUtil, PasswordEncoder passwordEncoder) {
this.customerRepository = customerRepository;
this.validatorUtil = validatorUtil;
this.passwordEncoder = passwordEncoder;
}
@Transactional
public Customer addCustomer(String fullName,String password)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
public Customer findByLogin(String login) {
return customerRepository.findOneByUsernameIgnoreCase(login);
}
if(!StringUtils.hasText(password))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
public Customer createCustomer(String login, String password, CustomerRole role){
if (findByLogin(login) != null) {
throw new ValidationException(String.format("Customer '%s' already exists", login));
}
final Customer customer = new Customer(fullName,password);
final Customer customer = new Customer(login,passwordEncoder.encode(password), role);
validatorUtil.validate(customer);
return customerRepository.save(customer);
}
@Transactional(readOnly = true)
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
final Customer customerEntity = findByLogin(username);
if (customerEntity == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(
customerEntity.getUsername(), customerEntity.getPassword(), Collections.singleton(customerEntity.getRole()));
}
/*@Transactional(readOnly = true)
public Customer findCustomer(Long id)
{
final Optional<Customer> student = customerRepository.findById(id);
return student.orElseThrow(() -> new CustomerNotFoundException(id));
}
}*/
@Transactional(readOnly = true)
public List<Customer> findAllCustomers()

View File

@ -48,9 +48,4 @@ public class GenreMVC {
return "redirect:/genre";
}
@GetMapping("/fill")
public String insertGenres() {
genreService.fillRepo();
return "redirect:/movies/fill";
}
}

View File

@ -1,8 +1,14 @@
package ru.ulstu.is.sbapp.Movie.MVC;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.Genre.Controller.GenreDTO;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
@ -20,11 +26,13 @@ import java.util.Objects;
public class MovieMVC {
private final MovieService movieService;
private final GenreService genreService;
private final CustomerService customerService;
private final CookiesManagement cookiesManagement;
public MovieMVC(MovieService movieService, GenreService genreService)
public MovieMVC(MovieService movieService, GenreService genreService,CustomerService customerService)
{
this.movieService = movieService;
this.genreService = genreService;
this.customerService = customerService;
this.cookiesManagement = new CookiesManagement();
}
@ -35,16 +43,25 @@ public class MovieMVC {
}
@GetMapping
public String getMovies(HttpServletRequest request, Model model) {
public String getMovies(Model model) {
genreService.fillRepo();
movieService.fillRepo();
String username = null;
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
if (principal instanceof UserDetails) {
username = ((UserDetails)principal). getUsername();
} else {
username = principal. toString();
}
String userId = null;
userId = cookiesManagement.GetUserID(request);
model.addAttribute("movies", movieService.findAllMovies().stream()
.map(MovieDTO::new)
.toList());
model.addAttribute("userId", userId);
model.addAttribute("userId", customerService.findByLogin(username).getId());
return "Mainpage";
}
@ -85,29 +102,43 @@ public class MovieMVC {
}
@PostMapping("/movie/delete/{id}")
@Secured({CustomerRole.AsString.ADMIN})
public String deleteMovie(@PathVariable("id") Long id) {
movieService.deleteMovie(id);
return "redirect:/movie";
return "redirect:/movies";
}
@PostMapping("/customer/{id}")
public String assignMovie(HttpServletRequest request,@PathVariable("id") Long id) {
public String assignMovie(@PathVariable("id") Long id) {
Long customerId = Long.parseLong(cookiesManagement.GetUserID(request));
movieService.assignMovie(customerId, id);
String username = null;
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
if (principal instanceof UserDetails) {
username = ((UserDetails)principal). getUsername();
} else {
username = principal. toString();
}
movieService.assignMovie(customerService.findByLogin(username).getId(), id);
return "redirect:/movies";
}
@PostMapping("/customer/delete/{id}")
public String deleteMovieCustomer(HttpServletRequest request, @PathVariable("id") Long id) {
Long customerId = Long.parseLong(cookiesManagement.GetUserID(request));
movieService.deleteMovieCustomer(id, customerId);
public String deleteMovieCustomer(@PathVariable("id") Long id) {
String username = null;
Object principal = SecurityContextHolder. getContext(). getAuthentication(). getPrincipal();
if (principal instanceof UserDetails) {
username = ((UserDetails)principal). getUsername();
} else {
username = principal. toString();
}
movieService.deleteMovieCustomer(id, customerService.findByLogin(username).getId());
return "redirect:/customer/movies";
}
@GetMapping("/fill")
public String insertMovies() {
movieService.fillRepo();
return "redirect:/movies";
}
}

View File

@ -162,12 +162,15 @@ public class MovieService
specificMovie.getGenre().getMovies().remove(specificMovie);
movieRepository.delete(specificMovie);
final List<Customer> customers = customerRepository.findAll();
customers.forEach(customer -> {
customer.getMovies().remove(specificMovie);
});
movieRepository.delete(specificMovie);
return specificMovie;
}

View File

@ -0,0 +1,14 @@
package ru.ulstu.is.sbapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PasswordEncoderConfiguration {
@Bean
public PasswordEncoder createPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -0,0 +1,53 @@
package ru.ulstu.is.sbapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final String LOGIN_URL = "/Login";
private static final String SIGNUP_URL = "/customer";
private final CustomerService customerService;
public SecurityConfiguration(CustomerService customerService) {
this.customerService = customerService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().sameOrigin().and()
.cors().and()
.csrf().disable()
.authorizeRequests()
.antMatchers(SIGNUP_URL).permitAll()
.antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage(LOGIN_URL).permitAll()
.and()
.logout().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customerService);
}
@Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers("/css/**")
.antMatchers("/js/**")
.antMatchers("/templates/**")
.antMatchers("/webjars/**");
}
}

View File

@ -6,4 +6,7 @@ public class ValidationException extends RuntimeException {
public ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
public <T> ValidationException(String error) {
super(error);
}
}

View File

@ -2,12 +2,18 @@ package ru.ulstu.is.sbapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
public static final String REST_API = "/api";
@Override
public void addViewControllers(ViewControllerRegistry registry) {
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("Login");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}

View File

@ -4,28 +4,38 @@
</head>
<div layout:fragment="content">
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
User isn't found or password isn't correct
</div>
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
Successful logout
</div>
<div th:if="${param.created}" class="alert alert-success margin-bottom">
User '<span th:text="${param.created}"></span>' was successfully created
</div>
<div class="flex-container" style="flex-direction: column; display: flex; ">
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex; align-items: center; justify-content: center; gap: 20px;">
<h1 for="userSelect" style="color: white;">Select User:</h1>
<select id="userSelect" style="width: 100px;">
<option th:each="customer : ${customers}" th:value="${customer.getID()}" th:text="${customer.username}"></option>
</select>
<button style="margin-top: 50px;" onclick="handleLogin()">Login</button>
<form th:action="@{/Login}" method="post" class="container-padding">
<div class="mb-3">
<input type="text" name="username" id="username" class="form-control"
placeholder="Login" required="true" autofocus="true"/>
</div>
<div class="mb-3">
<input type="password" name="password" id="password" class="form-control"
placeholder="Password" required="true"/>
</div>
<button type="submit" class="btn btn-success button-fixed" >Login</button>
<a class="btn btn-primary button-fixed" href="/customer">Registration</a>
</form>
</div>
</div>
</div>
<th:block layout:fragment="scripts">
<script>
function handleLogin() {
localStorage.clear();
var selectedUserId = document.getElementById("userSelect").value;
document.cookie = "userID=" + selectedUserId;
window.location.href = "/genre/fill";
}
</script>
</th:block>
</html>

View File

@ -5,22 +5,25 @@
<div layout:fragment="content">
<div class="flex-container min-vh-100" style="flex-direction: row; display: flex; margin-left: 20px; margin-top: 50px;">
<div th:if="${not #lists.isEmpty(movies)}" style="flex-direction: row; display: flex; flex-wrap: wrap; justify-content: space-between;">
<div th:each="movie : ${movies}" style="margin-bottom: 20px;">
<div className="flex-containerB" style="flex-direction: column; display: flex; width: 250px; height: 350px; gap:40px; align-items:center;">
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" alt = "cover" width="100%" height="300px"/>
<h3><a th:href="@{/movies/movie/{movieId}(movieId=${movie.getID()})}"
th:text="${movie.title}" style="text-decoration: none; color: white;"></a></h3>
<button type="button" th:attr="data-movie-id=${movie.getID()}" onclick="handleAcquireMovie(event)">Acquire</button>
<div th:if="${not #lists.isEmpty(movies)}" style="flex-direction: row; display: flex; flex-wrap: wrap; justify-content: space-between;">
<div th:each="movie : ${movies}" style="margin-bottom: 20px;">
<div className="flex-containerB" style="flex-direction: column; display: flex; width: 250px; height: 350px; gap:40px; align-items:center;">
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" alt = "cover" width="100%" height="300px"/>
<h3><a th:href="@{/movies/movie/{movieId}(movieId=${movie.getID()})}"
th:text="${movie.title}" style="text-decoration: none; color: white;"></a></h3>
<button type="btn btn-primary" th:attr="data-movie-id=${movie.getID()}" onclick="handleAcquireMovie(event)">Acquire</button>
<button type="btn btn-primary" th:attr="data-movie-id=${movie.getID()}" onclick="handleDeleteMovie(event)">Delete</button>
</div>
</div>
</div>
</div>
<h1 th:unless="${not #lists.isEmpty(movies)}" style="color: white;">No movies available</h1>
<h1 th:unless="${not #lists.isEmpty(movies)}" style="color: white;">No movies available</h1>
</div>
</div>
<th:block layout:fragment="scripts">
@ -34,6 +37,16 @@
}) ;
}
function handleDeleteMovie(movieId){
var movieId = event.target.getAttribute("data-movie-id");
var url = "/movies/movie/delete/" + movieId;
fetch(url,{
method: "POST",
}) ;
window.location.href = "/movies"
location.reload();
}
</script>
</th:block>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{Template}">
<head>
</head>
<div layout:fragment="content">
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
<div class="flex-container" style="flex-direction: column; display: flex;">
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex;">
<main style="display: flex; flex: 1;">
<aside class="flex-item2" style="flex: 2;"></aside>
<div class="flex-item3 align-self-center" style="flex: 3;"><img src="https://i.pinimg.com/736x/57/ee/6a/57ee6a23a455b12eff3aa13d63f104cd.jpg" alt="cover" width="100%" height="600px"/></div>
<section class="flex-container align-self-center" style="height: 660px; flex: 4; background-color: #ffd79d; flex-direction: column; display: flex;">
<form action="#" th:action="@{/customer}" th:object="${customerDTO}" method="post">
<section class="flex-itemR1" style="color: #320D3E; font-size: 50px; font-weight: bold; padding-left: 30px; padding-top: 10px;">SIGN UP</section>
<section class="flex-itemR2" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">USERNAME</label>
</section>
<section class="flex-itemR3" style="display: flex; width: 320px; padding-left: 30px;">
<input class="form-control" id="inputUsername" type="string" name="username" placeholder="Enter username" th:field="${customerDTO.username}" required="true" autofocus="true" maxlength="64"/>
</section>
<section class="flex-itemR6" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">PASSWORD</label>
</section>
<section class="flex-itemR7" style="display: flex; width: 320px; padding-left: 30px;">
<input class="form-control" id="inputPassword" type="password" name="password" placeholder="Enter password" th:field="${customerDTO.password}" required="true" minlength="6" maxlength="64"/>
</section>
<section class="flex-itemR8" style="display: flex; width: 320px; padding-left: 30px;">
<select id="genre-select" th:field="${customerDTO.role}" required="true">
<option value="USER">USER</option>
<option value="ADMIN">ADMIN</option>
</select>
</section>
<button class="btn btn-primary" type="submit" id="register" style="font-size: 20px; margin-left: 30px; margin-top: 15px; width: 150px; background-color: #320D3E; color: white; font-weight: bold;">Register</button>
<a href="/Login">Sign in</a>
</form>
</section>
<aside class="flex-item5" style="flex: 2;"></aside>
</main>
</div>
</div>
</div>
</html>

View File

@ -1,7 +1,8 @@
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8"/>
<title>I'M TIRED OF IP</title>
@ -12,7 +13,7 @@
<div style="background-image: url('https://img.freepik.com/premium-vector/grainy-gradient-background-using-different-colors_606954-9.jpg');">
<nav class="navbar navbar-expand-lg navbar-dark">
<ul class="navbar-nav mr-auto">
<ul class="navbar-nav mr-auto" sec:authorize="isAuthenticated()">
<li class="nav-item active">
<a class="nav-link" href="/movies" th:classappend="${#strings.equals(activeLink, '/movies')} ? 'active' : ''">
Main Page
@ -29,7 +30,7 @@
</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="/" th:classappend="${#strings.equals(activeLink, '/')} ? 'active' : ''">
<a class="nav-link" href="/customer" th:classappend="${#strings.equals(activeLink, '/')} ? 'active' : ''">
Registration Page
</a>
</li>

View File

@ -4,34 +4,16 @@
</head>
<div layout:fragment="content">
<div class="flex-container" style="flex-direction: column; display: flex;">
<div class="flex-container min-vh-100" style="flex-direction: column; display: flex;">
<main style="display: flex; flex: 1;">
<aside class="flex-item2" style="flex: 2;"></aside>
<div class="flex-item3 align-self-center" style="flex: 3;"><img src="https://i.pinimg.com/736x/57/ee/6a/57ee6a23a455b12eff3aa13d63f104cd.jpg" alt="cover" width="100%" height="600px"/></div>
<section class="flex-container align-self-center" style="height: 660px; flex: 4; background-color: #ffd79d; flex-direction: column; display: flex;">
<form action="#" th:action="@{/customer}" method="post">
<section class="flex-itemR1" style="color: #320D3E; font-size: 50px; font-weight: bold; padding-left: 30px; padding-top: 10px;">SIGN UP</section>
<section class="flex-itemR2" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">USERNAME</label>
</section>
<section class="flex-itemR3" style="display: flex; width: 320px; padding-left: 30px;">
<input class="form-control" id="inputUsername" type="string" name="fullName" placeholder="Enter username" th:value="${inputUsername}"/>
</section>
<section class="flex-itemR6" style="color: #320D3E; font-size: 35px; font-weight: bold; padding-left: 30px; padding-top: 10px;">
<label style="color: #320D3E; font-size: 32px; font-weight: bold;">PASSWORD</label>
</section>
<section class="flex-itemR7" style="display: flex; width: 320px; padding-left: 30px;">
<input class="form-control" id="inputPassword" type="password" name="password" placeholder="Enter password" th:value="${inputPassword}"/>
</section>
<button class="btn btn-primary" type="submit" id="register" style="font-size: 20px; margin-left: 30px; margin-top: 15px; width: 150px; background-color: #320D3E; color: white; font-weight: bold;">Register</button>
<a href="/customer">Sign in</a>
</form>
</section>
<aside class="flex-item5" style="flex: 2;"></aside>
</main>
<div class="flex-container min-vh-100" style="flex-direction: row; display: flex; margin-left: 20px; margin-top: 50px;">
<h1 style="color: white;">THE BEST ONLINE-CINEMA</h1>
</div>
</div>
</div>
</html>