Вроде MVC готов (единственное после входа в аккаунт пнг на всю страницу отображает почему то (странно :) ))
This commit is contained in:
parent
6012934a86
commit
c30e8182f9
@ -12,7 +12,7 @@ public class CommentDto {
|
||||
{
|
||||
this.id= comment.getId();
|
||||
this.Text=comment.getText();
|
||||
this.userName=comment.getUser().getFirstName() + " " + comment.getUser().getLastName();
|
||||
this.userName=comment.getUser().getLogin();
|
||||
this.postId=comment.getPost().getId();
|
||||
}
|
||||
public Long getId()
|
||||
|
@ -0,0 +1,14 @@
|
||||
package ru.ulstu.is.sbapp.Configuration;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package ru.ulstu.is.sbapp.Configuration;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import ru.ulstu.is.sbapp.User.controller.UserSignupMvcController;
|
||||
import ru.ulstu.is.sbapp.User.model.UserRole;
|
||||
import ru.ulstu.is.sbapp.User.service.UserService;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity(
|
||||
securedEnabled = true
|
||||
)
|
||||
public class SecurityConfiguration {
|
||||
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
|
||||
private static final String LOGIN_URL = "/login";
|
||||
private final UserService userService;
|
||||
|
||||
public SecurityConfiguration(UserService userService) {
|
||||
this.userService = userService;
|
||||
createAdminOnStartup();
|
||||
}
|
||||
|
||||
private void createAdminOnStartup() {
|
||||
final String admin = "admin";
|
||||
if (userService.findByLogin(admin) == null) {
|
||||
log.info("Admin user successfully created");
|
||||
userService.addUser(admin, "adminemail@gmail.com", admin, admin, UserRole.ADMIN);
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.headers().frameOptions().sameOrigin().and()
|
||||
.cors().and()
|
||||
.csrf().disable()
|
||||
.authorizeHttpRequests()
|
||||
.requestMatchers(UserSignupMvcController.SIGNUP_URL).permitAll()
|
||||
.requestMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage(LOGIN_URL).permitAll()
|
||||
.and()
|
||||
.logout().permitAll();
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManagerBean(HttpSecurity http) throws Exception {
|
||||
AuthenticationManagerBuilder authenticationManagerBuilder = http
|
||||
.getSharedObject(AuthenticationManagerBuilder.class);
|
||||
authenticationManagerBuilder.userDetailsService(userService);
|
||||
return authenticationManagerBuilder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
||||
return (web) -> web.ignoring()
|
||||
.requestMatchers("/css/**")
|
||||
.requestMatchers("/js/**")
|
||||
.requestMatchers("/templates/**")
|
||||
.requestMatchers("/webjars/**");
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package ru.ulstu.is.sbapp;
|
||||
package ru.ulstu.is.sbapp.Configuration;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
@ -11,6 +11,7 @@ public class WebConfiguration implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
WebMvcConfigurer.super.addViewControllers(registry);
|
||||
registry.addViewController("login");
|
||||
}
|
||||
|
||||
@Override
|
@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Comment.model.CommentDto;
|
||||
import ru.ulstu.is.sbapp.Post.model.PostDto;
|
||||
import ru.ulstu.is.sbapp.Post.service.PostService;
|
||||
import ru.ulstu.is.sbapp.WebConfiguration;
|
||||
import ru.ulstu.is.sbapp.Configuration.WebConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -7,6 +7,7 @@ import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import ru.ulstu.is.sbapp.Comment.model.Comment;
|
||||
import ru.ulstu.is.sbapp.Comment.model.CommentDto;
|
||||
import ru.ulstu.is.sbapp.Comment.service.CommentService;
|
||||
import ru.ulstu.is.sbapp.Post.model.PostDto;
|
||||
@ -15,10 +16,11 @@ import ru.ulstu.is.sbapp.User.model.UserDto;
|
||||
import ru.ulstu.is.sbapp.User.service.UserService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.Base64;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/post")
|
||||
@RequestMapping("/index")
|
||||
public class PostMvcController {
|
||||
private final PostService postService;
|
||||
private final UserService userService;
|
||||
@ -54,7 +56,7 @@ public class PostMvcController {
|
||||
userService.findAllUsers().stream()
|
||||
.map(UserDto::new)
|
||||
.toList());
|
||||
return "post";
|
||||
return "index";
|
||||
}
|
||||
@GetMapping("/filter")
|
||||
public String getFileteredPosts(@RequestParam(value = "searchValue") String searchValue,Model model)
|
||||
@ -67,29 +69,18 @@ public class PostMvcController {
|
||||
userService.findAllUsers().stream()
|
||||
.map(UserDto::new)
|
||||
.toList());
|
||||
return "post";
|
||||
return "index";
|
||||
}
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
@GetMapping(value = {"/edit/{id}"})
|
||||
public String editPost(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("postDto", new PostDto());
|
||||
model.addAttribute("users",
|
||||
userService.findAllUsers().stream()
|
||||
.map(UserDto::new)
|
||||
.toList());
|
||||
return "post-create";
|
||||
} else {
|
||||
model.addAttribute("postId", id);
|
||||
model.addAttribute("postDto", new PostDto(postService.findPost(id)));
|
||||
return "post-edit";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/user/", "/{id}"})
|
||||
@PostMapping(value = {"/{id}"})
|
||||
public String savePost(@PathVariable(required = false) Long id,
|
||||
@RequestParam(value = "userId",required = false) Long userId,
|
||||
@RequestParam(value = "multipartFile") MultipartFile multipartFile,
|
||||
@ModelAttribute @Valid PostDto postDto,
|
||||
BindingResult bindingResult,
|
||||
@ -98,27 +89,28 @@ public class PostMvcController {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "post-edit";
|
||||
}
|
||||
if (id == null || id <= 0 && userId!=null) {
|
||||
postDto.setImage("data:" + multipartFile.getContentType() + ";base64," + Base64.getEncoder().encodeToString(multipartFile.getBytes()));
|
||||
userService.addNewPost(userId,postDto);
|
||||
} else {
|
||||
postDto.setImage("data:" + multipartFile.getContentType() + ";base64," + Base64.getEncoder().encodeToString(multipartFile.getBytes()));
|
||||
postService.updatePost(id, postDto);
|
||||
}
|
||||
return "redirect:/post";
|
||||
return "redirect:/user";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{postId}")
|
||||
public String deletePost(
|
||||
@PathVariable Long postId) {
|
||||
postService.deletePost(postId);
|
||||
return "redirect:/post";
|
||||
return "redirect:/user";
|
||||
}
|
||||
@PostMapping("/deleteComment/{postId}/{commentId}")
|
||||
public String deleteComment(@PathVariable Long postId,
|
||||
@PathVariable Long commentId) {
|
||||
@PathVariable Long commentId,
|
||||
Principal principal,Model model) {
|
||||
Comment comment = commentService.findComment(commentId);
|
||||
if(!comment.getUser().getLogin().equals(principal.getName())){
|
||||
model.addAttribute("error", new Exception("Вы не можете удалить не ваш комментарий"));
|
||||
return "error";
|
||||
}
|
||||
postService.removeCommentFromPost(postId,commentId);
|
||||
return "redirect:/post/{postId}";
|
||||
return "redirect:/index/{postId}";
|
||||
}
|
||||
|
||||
@GetMapping("/userPosts")
|
||||
@ -132,48 +124,61 @@ public class PostMvcController {
|
||||
userService.findAllUsers().stream()
|
||||
.map(UserDto::new)
|
||||
.toList());
|
||||
return "post";
|
||||
return "index";
|
||||
}
|
||||
|
||||
|
||||
@GetMapping(value = {"/addComment/{postId}", "/editComment/{id}"})
|
||||
public String editComment(@PathVariable(required = false) Long id,
|
||||
@PathVariable(required = false) Long postId,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("postId", postId);
|
||||
model.addAttribute("users",
|
||||
userService.findAllUsers().stream()
|
||||
.map(UserDto::new)
|
||||
.toList());
|
||||
model.addAttribute("commentDto", new CommentDto());
|
||||
return "comment-create.html";
|
||||
} else {
|
||||
model.addAttribute("id", id);
|
||||
model.addAttribute("commentDto", new CommentDto(commentService.findComment(id)));
|
||||
@GetMapping("/addComment/{postId}")
|
||||
public String showCreateCommentInfo(@PathVariable(value = "postId") Long postId, Model model) {
|
||||
model.addAttribute("postId", postId);
|
||||
model.addAttribute("commentDto", new CommentDto());
|
||||
return "comment-create.html";
|
||||
}
|
||||
@PostMapping("/createComment/{postId}")
|
||||
public String createPost(@PathVariable(value = "postId") Long postId,
|
||||
@ModelAttribute @Valid CommentDto commentDto,
|
||||
BindingResult bindingResult,
|
||||
Principal principal,
|
||||
Model model) throws IOException
|
||||
{
|
||||
Long userId = userService.findByLogin(principal.getName()).getId();
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "post-create";
|
||||
}
|
||||
postService.addCommentToPost(postId,userId,commentDto.getText());
|
||||
return "redirect:/index";
|
||||
}
|
||||
|
||||
@GetMapping("/editComment/{Id}")
|
||||
public String showEditCommentInfo(@PathVariable(value = "Id") Long Id, Model model,Principal principal) throws Exception {
|
||||
model.addAttribute("Id", Id);
|
||||
CommentDto commentDto = new CommentDto(commentService.findComment(Id));
|
||||
model.addAttribute("commentDto",commentDto);
|
||||
if(!commentDto.getUser().equals(principal.getName())){
|
||||
model.addAttribute("error", new Exception("Вы не можете изменить не ваш комментарий"));
|
||||
return "error";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "comment-edit";
|
||||
}
|
||||
|
||||
}
|
||||
@PostMapping(value = {"/comment/{postId}/user", "/comment/{id}"})
|
||||
public String saveComment(@PathVariable(required = false) Long id,
|
||||
@RequestParam(value = "userId",required = false) Long userId,
|
||||
@PathVariable(required = false) Long postId,
|
||||
@ModelAttribute @Valid CommentDto commentDto,
|
||||
BindingResult bindingResult,
|
||||
Model model,
|
||||
HttpServletRequest request) {
|
||||
|
||||
@PostMapping("/updateComment/{Id}")
|
||||
public String updateComment(@PathVariable(value = "Id") Long Id,
|
||||
@ModelAttribute @Valid CommentDto commentDto,
|
||||
BindingResult bindingResult,
|
||||
Principal principal,
|
||||
Model model) throws IOException
|
||||
{
|
||||
Long userId = userService.findByLogin(principal.getName()).getId();
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "comment-edit";
|
||||
}
|
||||
if (id == null || id <= 0 && userId!=null) {
|
||||
postService.addCommentToPost(postId,userId,commentDto.getText());
|
||||
return "redirect:/post/"+ postId;
|
||||
} else {
|
||||
commentService.updateComment(id, commentDto.getText());
|
||||
return "redirect:/post";
|
||||
}
|
||||
|
||||
commentService.updateComment(Id,commentDto.getText());
|
||||
return "redirect:/user";
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import ru.ulstu.is.sbapp.Post.model.PostDto;
|
||||
import ru.ulstu.is.sbapp.User.model.UserDto;
|
||||
import ru.ulstu.is.sbapp.User.service.UserService;
|
||||
import ru.ulstu.is.sbapp.WebConfiguration;
|
||||
import ru.ulstu.is.sbapp.Configuration.WebConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -42,11 +42,10 @@ public class UserController {
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public UserDto updateClient(@PathVariable Long id,
|
||||
@RequestParam("firstName") String firstName,
|
||||
@RequestParam("lastName") String lastname,
|
||||
@RequestParam("firstName") String login,
|
||||
@RequestParam("email") String email,
|
||||
@RequestParam("password") String password){
|
||||
return new UserDto(userService.updateUser(id, firstName, lastname,email,password));
|
||||
return new UserDto(userService.updateUser(id, login,email,password));
|
||||
}
|
||||
@PostMapping("/{id}/Post")
|
||||
public void addPost(@PathVariable Long id,
|
||||
|
@ -1,13 +1,31 @@
|
||||
package ru.ulstu.is.sbapp.User.controller;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.ValidationException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.security.access.annotation.Secured;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import ru.ulstu.is.sbapp.Comment.model.CommentDto;
|
||||
import ru.ulstu.is.sbapp.Post.model.PostDto;
|
||||
import ru.ulstu.is.sbapp.User.model.User;
|
||||
import ru.ulstu.is.sbapp.User.model.UserDto;
|
||||
import ru.ulstu.is.sbapp.User.model.UserRole;
|
||||
import ru.ulstu.is.sbapp.User.service.UserService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/user")
|
||||
public class UserMvcController {
|
||||
@ -16,45 +34,82 @@ public class UserMvcController {
|
||||
{
|
||||
this.userService=userService;
|
||||
}
|
||||
@GetMapping(value = "/all")
|
||||
@Secured({UserRole.AsString.ADMIN})
|
||||
public String getUsers(@RequestParam(defaultValue = "1") int page,
|
||||
@RequestParam(defaultValue = "5") int size,
|
||||
Principal principal, Model model) {
|
||||
final Page<UserDto> users = userService.findAllPages(page, size)
|
||||
.map(UserDto::new);
|
||||
model.addAttribute("users", users);
|
||||
final int totalPages = users.getTotalPages();
|
||||
final List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
|
||||
.boxed()
|
||||
.toList();
|
||||
model.addAttribute("pages", pageNumbers);
|
||||
model.addAttribute("totalPages", totalPages);
|
||||
return "users";
|
||||
}
|
||||
@GetMapping
|
||||
public String getUsers(Model model) {
|
||||
model.addAttribute("users",
|
||||
userService.findAllUsers().stream()
|
||||
.map(UserDto::new)
|
||||
.toList());
|
||||
public String showUpdateUserForm(Principal principal, Model model) {
|
||||
UserDto userDto = new UserDto(userService.findByLogin(principal.getName()));
|
||||
Long id = userService.findByLogin(principal.getName()).getId();
|
||||
model.addAttribute("userId",id);
|
||||
model.addAttribute("userDto", userDto);
|
||||
model.addAttribute("posts",userService.GetUserPosts(id).stream()
|
||||
.map(PostDto::new)
|
||||
.toList());
|
||||
return "user";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editUser(@PathVariable(required = false) Long id,
|
||||
Model model) {
|
||||
if (id == null || id <= 0) {
|
||||
model.addAttribute("userDto", new UserDto());
|
||||
} else {
|
||||
model.addAttribute("userId", id);
|
||||
model.addAttribute("userDto", new UserDto(userService.findUser(id)));
|
||||
}
|
||||
return "user-edit";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"/", "/{id}"})
|
||||
public String saveUser(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute @Valid UserDto userDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
@PostMapping
|
||||
public String updateUser(@ModelAttribute @Valid UserDto userDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "user-edit";
|
||||
return "user";
|
||||
}
|
||||
if (id == null || id <= 0) {
|
||||
userService.addUser(userDto.getFirstName(), userDto.getLastName(),userDto.getEmail(),userDto.getPassword());
|
||||
} else {
|
||||
userService.updateUser(id, userDto.getFirstName(), userDto.getLastName(),userDto.getEmail(),userDto.getPassword());
|
||||
try {
|
||||
userService.updateUser(userDto);
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<SimpleGrantedAuthority> nowAuthorities =
|
||||
(Collection<SimpleGrantedAuthority>)SecurityContextHolder.getContext()
|
||||
.getAuthentication()
|
||||
.getAuthorities();
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
new UsernamePasswordAuthenticationToken(userDto.getLogin(), userDto.getPassword(), nowAuthorities);
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
} catch (ValidationException e) {
|
||||
model.addAttribute("errors", e.getMessage());
|
||||
}
|
||||
return "redirect:/user";
|
||||
return "user";
|
||||
}
|
||||
|
||||
@GetMapping("/post")
|
||||
public String showCreatePostInfo(Principal principal, Model model) {
|
||||
Long id = userService.findByLogin(principal.getName()).getId();
|
||||
model.addAttribute("userId",id);
|
||||
model.addAttribute("postDto", new PostDto());
|
||||
return "post-create";
|
||||
}
|
||||
@PostMapping("/createPost/{userId}")
|
||||
public String createPost(@PathVariable(value = "userId") Long id,
|
||||
@ModelAttribute @Valid PostDto postDto,
|
||||
@RequestParam(value = "multipartFile") MultipartFile multipartFile,
|
||||
BindingResult bindingResult,
|
||||
Model model) throws IOException
|
||||
{
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "post-create";
|
||||
}
|
||||
postDto.setImage("data:" + multipartFile.getContentType() + ";base64," + Base64.getEncoder().encodeToString(multipartFile.getBytes()));
|
||||
userService.addNewPost(id,postDto);
|
||||
return "redirect:/user";
|
||||
}
|
||||
@PostMapping("/delete/{id}")
|
||||
@Secured({UserRole.AsString.ADMIN})
|
||||
public String deleteUser(@PathVariable Long id) {
|
||||
userService.deleteUser(id);
|
||||
return "redirect:/user";
|
||||
|
@ -0,0 +1,51 @@
|
||||
package ru.ulstu.is.sbapp.User.controller;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.ValidationException;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import ru.ulstu.is.sbapp.User.model.User;
|
||||
import ru.ulstu.is.sbapp.User.model.UserRole;
|
||||
import ru.ulstu.is.sbapp.User.model.UserSignupDto;
|
||||
import ru.ulstu.is.sbapp.User.service.UserService;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(UserSignupMvcController.SIGNUP_URL)
|
||||
public class UserSignupMvcController
|
||||
{
|
||||
public static final String SIGNUP_URL = "/signup";
|
||||
private final UserService userService;
|
||||
|
||||
public UserSignupMvcController(UserService userService) {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String showSignupForm(Model model) {
|
||||
model.addAttribute("userDto", new UserSignupDto());
|
||||
return "signup";
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public String signup(@ModelAttribute("userDto") @Valid UserSignupDto userSignupDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "signup";
|
||||
}
|
||||
try {
|
||||
final User user = userService.addUser(userSignupDto.getLogin(),userSignupDto.getEmail(),
|
||||
userSignupDto.getPassword(), userSignupDto.getPasswordConfirm(), UserRole.USER);
|
||||
return "redirect:/login?created=" + user.getLogin();
|
||||
} catch (ValidationException e) {
|
||||
model.addAttribute("errors", e.getMessage());
|
||||
return "signup";
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package ru.ulstu.is.sbapp.User.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import ru.ulstu.is.sbapp.Comment.model.Comment;
|
||||
import ru.ulstu.is.sbapp.Post.model.Post;
|
||||
@ -16,14 +17,12 @@ public class User {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
@Column()
|
||||
@NotBlank(message = "firstName cannot be null")
|
||||
private String firstName;
|
||||
@NotBlank(message = "lastName cannot be null")
|
||||
private String lastName;
|
||||
@NotBlank(message = "Login can't be null or empty")
|
||||
@Size(min = 3, max = 64, message = "Incorrect login length")
|
||||
private String login;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 64)
|
||||
@NotBlank(message = "email cannot be null")
|
||||
@Pattern(regexp = "^(.+)@(\\S+)$", message = "Incorrect email value")
|
||||
private String email;
|
||||
|
||||
@Column(nullable = false, length = 64)
|
||||
@ -41,37 +40,26 @@ public class User {
|
||||
|
||||
public User() {
|
||||
}
|
||||
public User(String firstName,String lastName,String email, String password) {
|
||||
this(firstName,lastName,email, password, UserRole.USER);
|
||||
public User(String login,String email, String password) {
|
||||
this(login,email, password, UserRole.USER);
|
||||
}
|
||||
public User(String firstName, String lastName, String email,String password,UserRole role) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
public User(String login,String email,String password,UserRole role) {
|
||||
this.login=login;
|
||||
this.email=email;
|
||||
this.password=password;
|
||||
this.role=role;
|
||||
}
|
||||
|
||||
public User(UserSignupDto userSignupDto) {
|
||||
this.login = userSignupDto.getLogin();
|
||||
this.email = userSignupDto.getEmail();
|
||||
this.password = userSignupDto.getPassword();
|
||||
this.role = UserRole.USER;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
public List<Post> getPosts()
|
||||
{
|
||||
return posts;
|
||||
@ -112,6 +100,14 @@ public class User {
|
||||
return Objects.equals(id, user.id);
|
||||
}
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
@ -121,8 +117,7 @@ public class User {
|
||||
public String toString() {
|
||||
return "Client{" +
|
||||
"id=" + id +
|
||||
", firstName='" + firstName + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
", login='" + login + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", posts=" + posts +'\''+
|
||||
|
@ -10,9 +10,7 @@ import java.util.List;
|
||||
public class UserDto {
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private String lastName;
|
||||
private String login;
|
||||
|
||||
private String email;
|
||||
|
||||
@ -27,8 +25,7 @@ public class UserDto {
|
||||
public UserDto(){}
|
||||
public UserDto(User user) {
|
||||
this.id=user.getId();
|
||||
this.firstName = user.getFirstName();
|
||||
this.lastName = user.getLastName();
|
||||
this.login = user.getLogin();
|
||||
this.email= user.getEmail();
|
||||
this.role=user.getRole();
|
||||
this.password=user.getPassword();
|
||||
@ -37,12 +34,8 @@ public class UserDto {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public String getPassword(){
|
||||
@ -78,13 +71,10 @@ public class UserDto {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public void setComments(List<Comment> comments) {
|
||||
this.comments = comments;
|
||||
|
@ -0,0 +1,40 @@
|
||||
package ru.ulstu.is.sbapp.User.model;
|
||||
|
||||
public class UserSignupDto {
|
||||
private String login;
|
||||
private String email;
|
||||
private String password;
|
||||
private String passwordConfirm;
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getPasswordConfirm() {
|
||||
return passwordConfirm;
|
||||
}
|
||||
|
||||
public void setPasswordConfirm(String passwordConfirm) {
|
||||
this.passwordConfirm = passwordConfirm;
|
||||
}
|
||||
}
|
@ -12,4 +12,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
||||
@Query("Select p from Post p where user.id = :id")
|
||||
List<Post> getUsersPosts(Long id);
|
||||
|
||||
User findOneByLoginIgnoreCase(String login);
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
package ru.ulstu.is.sbapp.User.service;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import ru.ulstu.is.sbapp.Comment.service.CommentService;
|
||||
@ -7,40 +14,72 @@ import ru.ulstu.is.sbapp.Post.model.PostDto;
|
||||
import ru.ulstu.is.sbapp.Post.model.Post;
|
||||
import ru.ulstu.is.sbapp.Post.repository.PostRepository;
|
||||
import ru.ulstu.is.sbapp.User.model.User;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import ru.ulstu.is.sbapp.User.model.UserDto;
|
||||
import ru.ulstu.is.sbapp.User.model.UserRole;
|
||||
import ru.ulstu.is.sbapp.User.model.UserSignupDto;
|
||||
import ru.ulstu.is.sbapp.User.repository.UserRepository;
|
||||
import ru.ulstu.is.sbapp.Util.validation.ValidatorUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class UserService {
|
||||
public class UserService implements UserDetailsService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
private final PostRepository postRepository;
|
||||
|
||||
private final CommentService commentService;
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public UserService(UserRepository userRepository, ValidatorUtil validatorUtil, PostRepository postRepository, CommentService commentService)
|
||||
public UserService(UserRepository userRepository, ValidatorUtil validatorUtil, PostRepository postRepository, CommentService commentService,PasswordEncoder passwordEncoder)
|
||||
{
|
||||
this.userRepository=userRepository;
|
||||
this.validatorUtil=validatorUtil;
|
||||
this.postRepository = postRepository;
|
||||
this.commentService = commentService;
|
||||
this.passwordEncoder=passwordEncoder;
|
||||
}
|
||||
public User findByLogin(String login) {
|
||||
return userRepository.findOneByLoginIgnoreCase(login);
|
||||
}
|
||||
public Page<User> findAllPages(int page, int size) {
|
||||
return userRepository.findAll(PageRequest.of(page - 1, size, Sort.by("id").ascending()));
|
||||
}
|
||||
public User addUser(String firstName, String lastName, String email, String password) {
|
||||
return addUser(firstName,lastName, email, password, UserRole.USER);
|
||||
}
|
||||
@Transactional
|
||||
public User addUser(String firstName, String lastName, String email, String password, UserRole role) {
|
||||
final User user = new User(firstName, lastName, email,password,role);
|
||||
public User addUser(String login, String email, String password,String passwordConfirm, UserRole role) {
|
||||
if (findByLogin(login) != null) {
|
||||
throw new ValidationException(String.format("User '%s' already exists", login));
|
||||
}
|
||||
if (!Objects.equals(password, passwordConfirm)) {
|
||||
throw new ValidationException("Passwords not equals");
|
||||
}
|
||||
final User user = new User(login,email,passwordEncoder.encode(password),role);
|
||||
validatorUtil.validate(user);
|
||||
return userRepository.save(user);
|
||||
}
|
||||
@Transactional
|
||||
public User addUser(UserSignupDto userSignupDto) {
|
||||
if (findByLogin(userSignupDto.getLogin()) != null) {
|
||||
throw new ValidationException(String.format("User '%s' already exists", userSignupDto.getLogin()));
|
||||
}
|
||||
if (!Objects.equals(userSignupDto.getPassword(), userSignupDto.getPasswordConfirm())) {
|
||||
throw new ValidationException("Passwords not equals");
|
||||
}
|
||||
final User user = new User(userSignupDto);
|
||||
validatorUtil.validate(user);
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public User findUser(Long id) {
|
||||
@ -54,15 +93,29 @@ public class UserService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public User updateUser(Long id, String firstName, String lastName, String email,String password) {
|
||||
public User updateUser(Long id, String firstName, String email,String password) {
|
||||
final User currentUser = findUser(id);
|
||||
currentUser.setFirstName(firstName);
|
||||
currentUser.setLastName(lastName);
|
||||
currentUser.setLogin(firstName);
|
||||
currentUser.setEmail(email);
|
||||
currentUser.setPassword(password);
|
||||
validatorUtil.validate(currentUser);
|
||||
return userRepository.save(currentUser);
|
||||
}
|
||||
@Transactional
|
||||
public User updateUser(UserDto userDto) {
|
||||
final User currentUser = findUser(userDto.getId());
|
||||
final User sameUser = findByLogin(userDto.getLogin());
|
||||
if (sameUser != null && !Objects.equals(sameUser.getId(), currentUser.getId())) {
|
||||
throw new ValidationException(String.format("User '%s' already exists", userDto.getLogin()));
|
||||
}
|
||||
if (!passwordEncoder.matches(userDto.getPassword(), currentUser.getPassword())) {
|
||||
throw new ValidationException("Incorrect password");
|
||||
}
|
||||
currentUser.setLogin(userDto.getLogin());
|
||||
currentUser.setEmail(userDto.getEmail());
|
||||
validatorUtil.validate(currentUser);
|
||||
return userRepository.save(currentUser);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteUser(Long id) {
|
||||
@ -98,4 +151,14 @@ public class UserService {
|
||||
public void deletePost(Long id, Long postId) {
|
||||
postRepository.deleteById(postId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
final User userEntity = findByLogin(username);
|
||||
if (userEntity == null) {
|
||||
throw new UsernameNotFoundException(username);
|
||||
}
|
||||
return new org.springframework.security.core.userdetails.User(
|
||||
userEntity.getLogin(), userEntity.getPassword(), Collections.singleton(userEntity.getRole()));
|
||||
}
|
||||
}
|
||||
|
@ -8,18 +8,10 @@
|
||||
<div layout:fragment="content">
|
||||
<div class="mx-auto my-3">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{'/post/comment/' + ${postId} + '/user'}" th:object="${commentDto}" method="post">
|
||||
<div class="mb-3 my-2">
|
||||
<label for="selectBox" class="form-label">Пользователь</label>
|
||||
<select th:name="userId" id="selectBox" class="form-select">
|
||||
<option th:each="value: ${users}" th:selected="${selectBox} == ${value}" th:value="${value.id}">
|
||||
<span th:text="${value.firstName}"></span>
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<form action="#" th:action="@{'/index/createComment/' + ${postId}}" th:object="${commentDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<div>
|
||||
<input class="form-control" id="commentText" th:field="${commentDto.text}" type="text" defaultValue="" required/>
|
||||
<input class="form-control" id="commentText" th:field="${commentDto.text}" type="text" defaultValue="" required/>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div layout:fragment="content">
|
||||
<div class="mx-auto my-3">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/post/comment/{id}(id=${id})}" th:object="${commentDto}" method="post">
|
||||
<form action="#" th:action="@{/index/updateComment/{Id}(Id=${Id})}" th:object="${commentDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<div>
|
||||
<input class="form-control" id="commentText" th:field="${commentDto.text}" type="text" defaultValue="" required/>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<html lang="ru"
|
||||
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="">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Школа</title>
|
||||
@ -9,14 +9,14 @@
|
||||
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
|
||||
<link rel="stylesheet" href="/style.css"/>
|
||||
<link rel="stylesheet" href="/css/style.css"/>
|
||||
</head>
|
||||
<body class="body_app">
|
||||
<header class="fs-4 fw-bold p-1 text-white bg-primary bg-gradient">
|
||||
<div><img class="img-fluid float-start" src="/img/Emblema.png" alt="Emblema"/>
|
||||
<p class="fs-5 Cont">Муниципальное бюджетное общеобразовательное учреждение средняя общеобразовательная школа №10</p>
|
||||
</div>
|
||||
<nav class="navbar navbar-expand-md navbar-dark">
|
||||
<nav class="navbar navbar-expand-md navbar-dark" sec:authorize="isAuthenticated()">
|
||||
<div class="container-fluid">
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span></button>
|
||||
<nav class="headers-problem navbar navbar-expand-lg d-flex">
|
||||
@ -27,8 +27,15 @@
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<a class="btn btn-outline-light mx-1" href="/user"> Авторизация </a>
|
||||
<a class="btn btn-outline-light mx-1" href="/post">Новости</a>
|
||||
<a class="btn btn-outline-light mx-1" href="/user/all" sec:authorize="hasRole('ROLE_ADMIN')"
|
||||
th:classappend="${#strings.equals(activeLink, '/user')} ? 'active' : ''">
|
||||
Пользователи
|
||||
</a>
|
||||
<a class="btn btn-outline-light mx-1" href="/user"
|
||||
th:classappend="${#strings.equals(activeLink, '/user')} ? 'active' : ''">
|
||||
Профиль
|
||||
</a>
|
||||
<a class="btn btn-outline-light mx-1" href="/index">Новости</a>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div><span th:text="${error}"></span></div>
|
||||
<a href="/">На главную</a>
|
||||
<a href="/index">На главную</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -9,28 +9,21 @@
|
||||
|
||||
<div layout:fragment="content">
|
||||
<div class="d-flex float-start my-1">
|
||||
<form th:action="@{/post/filter}" class="d-flex">
|
||||
<form th:action="@{/index/filter}" class="d-flex">
|
||||
<div class="mx-3"><input type="text" th:name="searchValue" id="search" class="form-control" required /></div>
|
||||
<button type="submit" class="btn btn-outline-primary text-center mx-2">
|
||||
<i class="fa-solid fa-magnifying-glass"></i>
|
||||
</button>
|
||||
</form>
|
||||
<form th:action="@{/post/userPosts}" id="myForm" class="d-flex">
|
||||
<form th:action="@{/index/userPosts}" id="myForm" class="d-flex">
|
||||
<div class="mx-3">
|
||||
<select id="selectBox" th:name="userId">
|
||||
<option value="" disabled selected>Select your option</option>
|
||||
<option th:each="value: ${users}" th:selected="${selectBox} == ${value}" th:text="${value.firstName}" th:value="${value.Id}">
|
||||
<option th:each="value: ${users}" th:selected="${selectBox} == ${value}" th:text="${value.login}" th:value="${value.Id}">
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<a class="btn btn-outline-primary text-center mx-2"
|
||||
th:href="@{/post/edit}">
|
||||
<!--Сам понимаешь что здесь надо сделать-->
|
||||
+
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<!--здесь тоже надо сделать нормальный вывод-->
|
||||
@ -66,20 +59,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-flex flex-row justify-content-end ">
|
||||
<a class="btn btn-outline-primary text-center mx-2"
|
||||
th:href="@{/post/edit/{id}(id=${post.id})}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-primary text-center mx-2"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${post.id}').click()|">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
<form th:action="@{'/post/delete/' + ${post.id}}" method="post">
|
||||
<button th:id="'remove-' + ${post.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
<a th:href=@{/post/{id}(id=${post.id})} class='btn btn-outline-primary mx-2'><i class="fa-solid fa-envelopes-bulk"></i></a>
|
||||
<a th:href=@{/index/{id}(id=${post.id})} class='btn btn-outline-primary mx-2'><i class="fa-solid fa-envelopes-bulk"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
41
src/main/resources/templates/login.html
Normal file
41
src/main/resources/templates/login.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
|
||||
User not found
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
|
||||
Logout success
|
||||
</div>
|
||||
<div th:if="${param.created}" class="alert alert-success margin-bottom">
|
||||
User '<span th:text="${param.created}"></span>' was successfully created
|
||||
</div>
|
||||
<form th:action="@{/login}" method="post">
|
||||
<div class="mb-3">
|
||||
<p class="mb-1">Login</p>
|
||||
<input name="username" id="username" class="form-control"
|
||||
type="text" required autofocus />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<p class="mb-1">Password</p>
|
||||
<input name="password" id="password" class="form-control"
|
||||
type="password" required />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-success">
|
||||
Sing in
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<span>Not a member yet?</span>
|
||||
<a href="/signup">Sing Up here</a>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -7,15 +7,7 @@
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/post/user/}" th:object="${postDto}" method="post" enctype="multipart/form-data">
|
||||
<div class="mb-3 my-2">
|
||||
<label for="selectBox" class="form-label">Пользователь</label>
|
||||
<select th:name="userId" id="selectBox" class="form-select">
|
||||
<option th:each="value: ${users}" th:selected="${selectBox} == ${value}" th:value="${value.id}">
|
||||
<span th:text="${value.firstName}"></span>
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<form action="#" th:action="@{/user/createPost/{userId}(userId=${userId})}" th:object="${postDto}" method="post" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label for="image" class="form-label">Картинка</label>
|
||||
<input type="file" th:name="multipartFile" class="form-control" id="image" required="true">
|
||||
|
@ -7,7 +7,7 @@
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/post/{id}(id=${id})}" th:object="${postDto}" method="post" enctype="multipart/form-data">
|
||||
<form action="#" th:action="@{/index/{id}(id=${id})}" th:object="${postDto}" method="post" enctype="multipart/form-data">
|
||||
<div class="mb-3">
|
||||
<label for="image" class="form-label">Картинка</label>
|
||||
<input type="file" th:name="multipartFile" class="form-control" id="image" required="true">
|
||||
|
@ -16,7 +16,7 @@
|
||||
</div>
|
||||
<!--Вот тут кнопка для добавления комментариев (для будущего тебя)-->
|
||||
<a class="btn btn-outline-primary text-center mx-2"
|
||||
th:href="@{/post/addComment/{postId}(postId=${post.id})}">
|
||||
th:href="@{/index/addComment/{postId}(postId=${post.id})}">
|
||||
+
|
||||
</a>
|
||||
<div className="d-flex mx-2">
|
||||
@ -38,7 +38,7 @@
|
||||
<td style="width: 10%">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<!--НУЖНО СДЕЛАТЬ!!!-->
|
||||
<a class="btn btn-outline-light text-center mx-2" th:href="@{/post/editComment/{id}(id=${comment.id})}">
|
||||
<a class="btn btn-outline-light text-center mx-2" th:href="@{/index/editComment/{Id}(Id=${comment.id})}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-light text-center mx-2"
|
||||
@ -46,7 +46,7 @@
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
</div>
|
||||
<form th:action="@{'/post/deleteComment/' + ${comment.postId} + '/' + ${comment.id}}" method="post">
|
||||
<form th:action="@{'/index/deleteComment/' + ${comment.postId} + '/' + ${comment.id}}" method="post">
|
||||
<button th:id="'remove-' + ${comment.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
|
43
src/main/resources/templates/signup.html
Normal file
43
src/main/resources/templates/signup.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
|
||||
<form action="#" th:action="@{/signup}" th:object="${userDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="login" class="mb-1">Login</label>
|
||||
<input id="login" th:field="${userDto.login}" class="form-control"
|
||||
type="text" required maxlength="64" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="mb-1">Email</label>
|
||||
<input id="email" th:field="${userDto.email}" class="form-control"
|
||||
type="text" required />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="mb-1">Password</label>
|
||||
<input id="password" th:field="${userDto.password}" class="form-control"
|
||||
type="password" required minlength="3" maxlength="64" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="passwordConfirm" class="mb-1">Confirm Password</label>
|
||||
<input id="passwordConfirm" th:field="${userDto.passwordConfirm}" class="form-control"
|
||||
type="password" required minlength="3" maxlength="64" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-success">
|
||||
Create account
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<span>Already have an account?</span>
|
||||
<a href="/login">Sing In here</a>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,39 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||
<form action="#" th:action="@{/user/{id}(id=${id})}" th:object="${userDto}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="firstName" class="form-label">Имя</label>
|
||||
<input type="text" class="form-control" id="firstName" th:field="${userDto.firstName}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="lastName" class="form-label">Фамилия</label>
|
||||
<input type="text" class="form-control" id="lastName" th:field="${userDto.lastName}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Почта</label>
|
||||
<input type="text" class="form-control" id="email" th:field="${userDto.email}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Пароль</label>
|
||||
<input type="text" class="form-control" id="password" th:field="${userDto.password}" required="true">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary button-fixed">
|
||||
<span th:if="${id == null}">Добавить</span>
|
||||
<span th:if="${id != null}">Обновить</span>
|
||||
</button>
|
||||
<a class="btn btn-secondary button-fixed" th:href="@{/user}">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,57 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}"
|
||||
xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div>
|
||||
<a class="btn btn-outline-light text-center mx-2 my-2"
|
||||
th:href="@{/user/edit}">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
<div class="border-bottom pb-3 mb-3 mx-2">
|
||||
<a class="btn btn-primary" href="/logout">
|
||||
Log Out
|
||||
</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Имя</th>
|
||||
<th scope="col">Почта</th>
|
||||
<th scope="col">Пароль</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="user, iterator: ${users}">
|
||||
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||
<td th:text="${user.id}"/>
|
||||
<td th:text="${user.firstName} + ' ' + ${user.lastName}" style="width: 60%"/>
|
||||
<td th:text="${user.email}" style="width: 60%"/>
|
||||
<td th:text="${user.password}" style="width: 60%"/>
|
||||
<td style="width: 10%">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<a class="btn btn-outline-light text-center mx-2"
|
||||
th:href="@{/user/edit/{id}(id=${user.id})}">
|
||||
<h4>Данные профиля</h4>
|
||||
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
|
||||
<form action="/user" th:object="${userDto}" method="post">
|
||||
<input th:field="${userDto.id}" type="number" style="display: none;" />
|
||||
<div class="mb-3">
|
||||
<label for="login" class="form-label">Логин</label>
|
||||
<input id="login" th:field="${userDto.login}" class="form-control"
|
||||
required type="text" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label">Почта</label>
|
||||
<input id="email" th:field="${userDto.email}" class="form-control"
|
||||
required type="text" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Пароль (введите для подтверждения изменения данных)</label>
|
||||
<input id="password" th:field="${userDto.password}" class="form-control"
|
||||
required type="password" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-success">
|
||||
Изменить
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<a class="btn btn-outline-primary text-center mx-2"
|
||||
th:href="@{/user/post}">
|
||||
<!--Сам понимаешь что здесь надо сделать-->
|
||||
+
|
||||
</a>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<!--здесь тоже надо сделать нормальный вывод-->
|
||||
<div class="container-fluid">
|
||||
<div th:each="post, iterator: ${posts}" class="card border-dark mb-3 d-flex flex-row text-black justify-content-between">
|
||||
<div>
|
||||
<img class="col" style="width:300px;height:200px" th:src="${post.image}"/>
|
||||
</div>
|
||||
<div class="d-flex flex-grow-1 flex-column">
|
||||
<div class="flex-grow-1 mx-2">
|
||||
<h th:text="${post.heading}"></h>
|
||||
</div>
|
||||
<div class="flex-grow-1 mx-2">
|
||||
<p th:text="${post.content}"></p>
|
||||
</div>
|
||||
<div class="flex-grow-1 mx-2">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">Пользователь</th>
|
||||
<th scope="col">Текст</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="comment, iterator: ${post.comments}">
|
||||
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||
<td th:text="${comment.user}" style="width: 60%"/>
|
||||
<td th:text="${comment.text}" style="width: 60%"/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-flex flex-row justify-content-end ">
|
||||
<a class="btn btn-outline-primary text-center mx-2"
|
||||
th:href="@{/index/edit/{id}(id=${post.id})}">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||
</a>
|
||||
<button type="button" class="btn btn-outline-light text-center mx-2"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${user.id}').click()|">
|
||||
<button type="button" class="btn btn-outline-primary text-center mx-2"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${post.id}').click()|">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
<form th:action="@{'/index/delete/' + ${post.id}}" method="post">
|
||||
<button th:id="'remove-' + ${post.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
<a th:href=@{/index/{id}(id=${post.id})} class='btn btn-outline-primary mx-2'><i class="fa-solid fa-envelopes-bulk"></i></a>
|
||||
</div>
|
||||
<form th:action="@{/user/delete/{id}(id=${user.id})}" method="post">
|
||||
<button th:id="'remove-' + ${user.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<th:block layout:fragment="scripts">
|
||||
<script type="module">
|
||||
</script>
|
||||
</th:block>
|
||||
|
||||
</html>
|
||||
|
54
src/main/resources/templates/users.html
Normal file
54
src/main/resources/templates/users.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">Логин</th>
|
||||
<th scope="col">Почта</th>
|
||||
<th scope="col">Пароль</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="user, iterator: ${users}">
|
||||
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||
<td th:text="${user.id}"/>
|
||||
<td th:text="${user.login}" style="width: 60%"/>
|
||||
<td th:text="${user.email}" style="width: 60%"/>
|
||||
<td style="width: 10%">
|
||||
<div class="btn-group" role="group" aria-label="Basic example">
|
||||
<button type="button" class="btn btn-outline-light text-center mx-2"
|
||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${user.id}').click()|">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||
</button>
|
||||
</div>
|
||||
<form th:action="@{/user/delete/{id}(id=${user.id})}" method="post">
|
||||
<button th:id="'remove-' + ${user.id}" type="submit" style="display: none">
|
||||
Удалить
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div th:if="${totalPages > 0}" class="pagination">
|
||||
<span style="float: left; padding: 5px 5px;">Pages:</span>
|
||||
<a th:each="page : ${pages}"
|
||||
th:href="@{/user/all(page=${page}, size=${users.size})}"
|
||||
th:text="${page}"
|
||||
th:class="${page == users.number + 1} ? active">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user