Compare commits
No commits in common. "794388d0f63f189e10cf067878cbf82d070b17d0" and "8ae10007bb0cbdae3547c8d519b13a6faeea2d2e" have entirely different histories.
794388d0f6
...
8ae10007bb
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
3828
data.trace.db
Normal file
3828
data.trace.db
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,5 @@
|
|||||||
package com.webproglabs.lab1;
|
package com.webproglabs.lab1;
|
||||||
|
|
||||||
import com.webproglabs.lab1.models.UserRole;
|
|
||||||
import com.webproglabs.lab1.mvc.UserSignupMvcController;
|
|
||||||
import com.webproglabs.lab1.services.UserService;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -32,47 +29,47 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
|
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
|
||||||
private static final String LOGIN_URL = "/login";
|
private static final String LOGIN_URL = "/login";
|
||||||
public static final String SPA_URL_MASK = "/{path:[^\\.]*}";
|
public static final String SPA_URL_MASK = "/{path:[^\\.]*}";
|
||||||
private final UserService userService;
|
// private final ProfileService userService;
|
||||||
|
//
|
||||||
|
// public SecurityConfiguration(ProfileService userService) {
|
||||||
|
// this.userService = userService;
|
||||||
|
// createAdminOnStartup();
|
||||||
|
// }
|
||||||
|
|
||||||
public SecurityConfiguration(UserService userService) {
|
// private void createAdminOnStartup() {
|
||||||
this.userService = userService;
|
// final String admin = "admin";
|
||||||
createAdminOnStartup();
|
// if (userService.findByLogin(admin) == null) {
|
||||||
}
|
// log.info("Admin user successfully created");
|
||||||
|
// try {
|
||||||
|
// userService.createUser(admin, admin, admin, UserRole.ADMIN);
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// throw new RuntimeException(e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
private void createAdminOnStartup() {
|
// @Override
|
||||||
final String admin = "admin";
|
// protected void configure(HttpSecurity http) throws Exception {
|
||||||
if (userService.findUserByLogin(admin) == null) {
|
//
|
||||||
log.info("Admin user successfully created");
|
// http.exceptionHandling().authenticationEntryPoint(delegatingEntryPoint());
|
||||||
try {
|
// http.headers().frameOptions().sameOrigin().and()
|
||||||
userService.createUser(admin, admin, admin, UserRole.ADMIN);
|
// .cors().and()
|
||||||
} catch (Exception e) {
|
// .csrf().disable()
|
||||||
throw new RuntimeException(e);
|
// .authorizeRequests()
|
||||||
}
|
// .antMatchers(UserSignupMvcController.SIGNUP_URL).permitAll()
|
||||||
}
|
// .antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
|
||||||
}
|
// .anyRequest().authenticated()
|
||||||
|
// .and()
|
||||||
|
// .formLogin()
|
||||||
|
// .loginPage(LOGIN_URL).permitAll()
|
||||||
|
// .and()
|
||||||
|
// .logout().permitAll();
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
// auth.userDetailsService(userService);
|
||||||
http.exceptionHandling().authenticationEntryPoint(delegatingEntryPoint());
|
// }
|
||||||
http.headers().frameOptions().sameOrigin().and()
|
|
||||||
.cors().and()
|
|
||||||
.csrf().disable()
|
|
||||||
.authorizeRequests()
|
|
||||||
.antMatchers(UserSignupMvcController.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(userService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(WebSecurity web) {
|
public void configure(WebSecurity web) {
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dao;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.models.Comment;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface CommentRepository extends JpaRepository<Comment, Long> {
|
|
||||||
List<Comment> findByTextLike(String text);
|
|
||||||
Optional<Comment> findById(Long Id);
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dao;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
import com.webproglabs.lab1.models.Topic;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface PostRepository extends JpaRepository<Post, Long> {
|
|
||||||
List<Post> findByTextLike(String text);
|
|
||||||
Optional<Post> findById(Long Id);
|
|
||||||
|
|
||||||
@Query("SELECT p FROM Post p WHERE p.topic = :topic AND p.text LIKE %:text%")
|
|
||||||
List<Post> findPostsByTextInTopic(@Param("text") String text, @Param("topic") Topic topic);
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dao;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
import com.webproglabs.lab1.models.Topic;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface TopicRepository extends JpaRepository<Topic, Long> {
|
|
||||||
Optional<Topic> findById(Long Id);
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dao;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.models.User;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface UserRepository extends JpaRepository<User, Long> {
|
|
||||||
Optional<User> findOneByLoginIgnoreCase(String login);
|
|
||||||
Optional<User> findById(Long Id);
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.webproglabs.lab1.models.Comment;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
|
|
||||||
public class CommentDto {
|
|
||||||
private Long id;
|
|
||||||
@NotBlank
|
|
||||||
private String text;
|
|
||||||
@NotBlank
|
|
||||||
private String authorLogin;
|
|
||||||
|
|
||||||
public CommentDto(Comment comment) {
|
|
||||||
this.id = comment.getId();
|
|
||||||
this.text = comment.getText();
|
|
||||||
this.authorLogin = comment.getOwner().getLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getText() {return text;}
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
public String getAuthor() {return authorLogin;}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.webproglabs.lab1.models.Comment;
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PostDto {
|
|
||||||
private Long id;
|
|
||||||
@NotBlank
|
|
||||||
private String text;
|
|
||||||
@NotNull
|
|
||||||
private List<CommentDto> comments = new ArrayList<>();
|
|
||||||
@NotBlank
|
|
||||||
private String authorLogin;
|
|
||||||
|
|
||||||
public PostDto(Post post){
|
|
||||||
this.id = post.getId();
|
|
||||||
this.text = post.getText();
|
|
||||||
for(Comment comment: post.getComments()){
|
|
||||||
comments.add(new CommentDto(comment));
|
|
||||||
}
|
|
||||||
this.authorLogin = post.getAuthor().getLogin();
|
|
||||||
}
|
|
||||||
public PostDto(){}
|
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getText() {return text;}
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
public List<CommentDto> getComments() {return comments;}
|
|
||||||
public String getAuthor() {return authorLogin;}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dto;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.models.Comment;
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
import com.webproglabs.lab1.models.Topic;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class TopicDto {
|
|
||||||
private Long id;
|
|
||||||
@NotBlank
|
|
||||||
private String name;
|
|
||||||
@NotBlank
|
|
||||||
private String description;
|
|
||||||
@NotNull
|
|
||||||
private List<PostDto> posts = new ArrayList<>();
|
|
||||||
|
|
||||||
public TopicDto(Topic topic) {
|
|
||||||
this.id = topic.getId();
|
|
||||||
this.name = topic.getName();
|
|
||||||
this.description = topic.getDescription();
|
|
||||||
for(Post post: topic.getPosts()){
|
|
||||||
posts.add(new PostDto(post));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public TopicDto(){}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<PostDto> getPosts() {
|
|
||||||
return posts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dto;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.webproglabs.lab1.models.Comment;
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
import com.webproglabs.lab1.models.User;
|
|
||||||
import com.webproglabs.lab1.models.UserRole;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class UserDto {
|
|
||||||
private Long id;
|
|
||||||
@NotBlank
|
|
||||||
private String login;
|
|
||||||
@NotBlank
|
|
||||||
private String password;
|
|
||||||
@NotNull
|
|
||||||
private List<CommentDto> comments = new ArrayList<>();
|
|
||||||
@NotNull
|
|
||||||
private List<PostDto> posts = new ArrayList<>();
|
|
||||||
@NotNull
|
|
||||||
private UserRole role;
|
|
||||||
|
|
||||||
|
|
||||||
public UserDto(){}
|
|
||||||
|
|
||||||
public UserDto(User user){
|
|
||||||
this.id = user.getId();
|
|
||||||
this.login = user.getLogin();
|
|
||||||
this.password = user.getPassword();
|
|
||||||
this.role = user.getRole();
|
|
||||||
for(Comment comment: user.getComments()){
|
|
||||||
comments.add(new CommentDto(comment));
|
|
||||||
}
|
|
||||||
for (Post post: user.getPosts()) {
|
|
||||||
posts.add(new PostDto(post));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getLogin() {return login;}
|
|
||||||
public void setLogin(String login) {this.login = login;}
|
|
||||||
public String getPassword() {return password;}
|
|
||||||
public UserRole getRole() {return role;}
|
|
||||||
public void setPassword(String password) {this.password = password;}
|
|
||||||
|
|
||||||
public List<CommentDto> getComments() {return comments;}
|
|
||||||
public List<PostDto> getPosts() {return posts;}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package com.webproglabs.lab1.dto;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
public class UserSignupDto {
|
|
||||||
@NotBlank
|
|
||||||
@Size(min = 4, max = 64)
|
|
||||||
private String login;
|
|
||||||
@NotBlank
|
|
||||||
@Size(min = 4, max = 64)
|
|
||||||
private String password;
|
|
||||||
@NotBlank
|
|
||||||
@Size(min = 4, max = 64)
|
|
||||||
private String passwordConfirm;
|
|
||||||
|
|
||||||
public String getLogin() {
|
|
||||||
return login;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLogin(String login) {
|
|
||||||
this.login = login;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
package com.webproglabs.lab1.models;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Comment {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
@ManyToOne()
|
|
||||||
private User owner;
|
|
||||||
|
|
||||||
@ManyToOne()
|
|
||||||
private Post post;
|
|
||||||
|
|
||||||
public Comment(){};
|
|
||||||
public Comment(String text, User owner, Post post) {
|
|
||||||
this.text = text;
|
|
||||||
this.owner = owner;
|
|
||||||
this.post = post;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(User owner) {
|
|
||||||
this.owner.getComments().remove(this);
|
|
||||||
this.owner = owner;
|
|
||||||
if (!owner.getComments().contains(this)) {
|
|
||||||
owner.getComments().add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Post getPost() {return post; }
|
|
||||||
|
|
||||||
public void setPost(Post post) {
|
|
||||||
this.post.getComments().remove(this);
|
|
||||||
this.post = post;
|
|
||||||
if (!post.getComments().contains(this)) {
|
|
||||||
post.getComments().add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Comment comment = (Comment) o;
|
|
||||||
return Objects.equals(id, comment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String ToString() {
|
|
||||||
return "Comment{" +
|
|
||||||
"id=" + id +
|
|
||||||
", text='" + text + '\'' +
|
|
||||||
", owner='" + owner.ToString() + '\'' +
|
|
||||||
", post='" + post.ToString() + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
package com.webproglabs.lab1.models;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Post {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "post", orphanRemoval = true, fetch = FetchType.EAGER)
|
|
||||||
private List<Comment> comments = new ArrayList<Comment>();
|
|
||||||
|
|
||||||
@ManyToOne()
|
|
||||||
private User author;
|
|
||||||
|
|
||||||
@ManyToOne()
|
|
||||||
private Topic topic;
|
|
||||||
|
|
||||||
public Post(){}
|
|
||||||
public Post(String text, User author, Topic topic) {
|
|
||||||
this.text = text;
|
|
||||||
this.author = author;
|
|
||||||
this.topic = topic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getAuthor() {
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthor(User author) {
|
|
||||||
this.author.getPosts().remove(this);
|
|
||||||
this.author = author;
|
|
||||||
if (!author.getPosts().contains(this)) {
|
|
||||||
author.getPosts().add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Topic getTopic() {
|
|
||||||
return topic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTopic(Topic topic) {
|
|
||||||
this.topic.getPosts().remove(this);
|
|
||||||
this.topic = topic;
|
|
||||||
if (!topic.getPosts().contains(this)) {
|
|
||||||
topic.getPosts().add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Comment> getComments() { return comments; }
|
|
||||||
|
|
||||||
public void addComment(Comment comment) {
|
|
||||||
this.comments.add(comment);
|
|
||||||
if (comment.getPost() != this) {
|
|
||||||
comment.setPost(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Post post = (Post) o;
|
|
||||||
return Objects.equals(id, post.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String ToString() {
|
|
||||||
return "Post{" +
|
|
||||||
"id=" + id +
|
|
||||||
", text='" + text + '\'' +
|
|
||||||
", author='" + author.ToString() + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
package com.webproglabs.lab1.models;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Topic {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "topic", orphanRemoval = true, fetch = FetchType.EAGER)
|
|
||||||
private List<Post> posts;
|
|
||||||
|
|
||||||
public Topic(String name, String description) {
|
|
||||||
this.name = name;
|
|
||||||
this.description = description;
|
|
||||||
this.posts = new ArrayList<Post>();
|
|
||||||
}
|
|
||||||
public Topic(){}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Post> getPosts() {
|
|
||||||
return posts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPost(Post post) {
|
|
||||||
this.posts.add(post);
|
|
||||||
if (post.getTopic() != this) {
|
|
||||||
post.setTopic(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Topic topic = (Topic) o;
|
|
||||||
return Objects.equals(id, topic.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String ToString() {
|
|
||||||
return "Topic{" +
|
|
||||||
"id=" + id +
|
|
||||||
", name='" + name + '\'' +
|
|
||||||
", description='" + description + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
package com.webproglabs.lab1.models;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name="users")
|
|
||||||
public class User {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@Column(nullable = false, unique = true, length = 64)
|
|
||||||
@NotBlank
|
|
||||||
@Size(min = 3, max = 64)
|
|
||||||
private String login;
|
|
||||||
|
|
||||||
@Column(nullable = false, length = 64)
|
|
||||||
@NotBlank
|
|
||||||
@Size(min = 4, max = 64)
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
private UserRole role;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "owner", orphanRemoval = true, fetch = FetchType.EAGER)
|
|
||||||
private List<Comment> comments = new ArrayList<Comment>();
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "author", orphanRemoval = true, fetch = FetchType.EAGER)
|
|
||||||
private List<Post> posts = new ArrayList<Post>();
|
|
||||||
|
|
||||||
public User(){}
|
|
||||||
public User(String login, String password) {
|
|
||||||
this.login = login;
|
|
||||||
this.password=password;
|
|
||||||
this.role = UserRole.USER;
|
|
||||||
};
|
|
||||||
|
|
||||||
public User(String login, String password, UserRole role) {
|
|
||||||
this.login = login;
|
|
||||||
this.password=password;
|
|
||||||
this.role = role;
|
|
||||||
};
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLogin() {
|
|
||||||
return login;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserRole getRole() {
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLogin(String login) {
|
|
||||||
this.login = login;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Comment> getComments() { return comments; }
|
|
||||||
|
|
||||||
public List<Post> getPosts() {return posts; }
|
|
||||||
|
|
||||||
public void addComment(Comment comment) {
|
|
||||||
this.comments.add(comment);
|
|
||||||
if (comment.getOwner() != this) {
|
|
||||||
comment.setOwner(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPost(Post post) {
|
|
||||||
this.posts.add(post);
|
|
||||||
if (post.getAuthor() != this) {
|
|
||||||
post.setAuthor(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
User user = (User) o;
|
|
||||||
return Objects.equals(id, user.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String ToString() {
|
|
||||||
return "User{" +
|
|
||||||
"id=" + id +
|
|
||||||
", login='" + login + '\'' +
|
|
||||||
", password='" + password + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package com.webproglabs.lab1.models;
|
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
|
|
||||||
public enum UserRole 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";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
package com.webproglabs.lab1.mvc;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dto.CommentDto;
|
|
||||||
import com.webproglabs.lab1.dto.PostDto;
|
|
||||||
import com.webproglabs.lab1.dto.TopicDto;
|
|
||||||
import com.webproglabs.lab1.dto.UserDto;
|
|
||||||
import com.webproglabs.lab1.services.CommentService;
|
|
||||||
import com.webproglabs.lab1.services.PostService;
|
|
||||||
import com.webproglabs.lab1.services.TopicService;
|
|
||||||
import com.webproglabs.lab1.services.UserService;
|
|
||||||
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.*;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/feed")
|
|
||||||
public class FeedMvcController {
|
|
||||||
private final UserService userService;
|
|
||||||
private final PostService postService;
|
|
||||||
private final CommentService commentService;
|
|
||||||
private final TopicService topicService;
|
|
||||||
|
|
||||||
public FeedMvcController(UserService userService, PostService postService, CommentService commentService, TopicService topicService) {
|
|
||||||
this.userService = userService;
|
|
||||||
this.postService = postService;
|
|
||||||
this.commentService = commentService;
|
|
||||||
this.topicService = topicService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public String getFeedPage(Model model) {
|
|
||||||
model.addAttribute("topics", topicService.findAllTopics().stream().map(TopicDto::new).toList());
|
|
||||||
return "feed";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"/{id}"})
|
|
||||||
public String getFeedPageWithTopic(@PathVariable Long id, Model model) {
|
|
||||||
model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
|
|
||||||
model.addAttribute("posts", topicService.findTopicById(id).getPosts().stream().map(PostDto::new).toList());
|
|
||||||
model.addAttribute("topics", topicService.findAllTopics().stream().map(TopicDto::new).toList());
|
|
||||||
|
|
||||||
UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var user = userService.findUserByLogin(principal.getUsername());
|
|
||||||
model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
|
|
||||||
|
|
||||||
model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(id)));
|
|
||||||
|
|
||||||
return "feedPosts";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value= {"/filter/{id}/"})
|
|
||||||
public String getFeedPageFiltered(@PathVariable Long id, @RequestParam(value="searchField") String searchField, Model model) {
|
|
||||||
model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
|
|
||||||
model.addAttribute("topics", topicService.findAllTopics().stream().map(TopicDto::new).toList());
|
|
||||||
UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var user = userService.findUserByLogin(principal.getUsername());
|
|
||||||
model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
|
|
||||||
model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(id)));
|
|
||||||
|
|
||||||
model.addAttribute("posts", postService.findPostsInTopicByText(searchField, id).stream().map(PostDto::new).toList());
|
|
||||||
|
|
||||||
return "feedPosts";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value={"/{topicId}/post/{id}/"})
|
|
||||||
public String createPost(@PathVariable Long topicId, @PathVariable Long id, @RequestParam(value="postInputField") String postInputField) {
|
|
||||||
postService.addPost(postInputField, id, topicId);
|
|
||||||
return "redirect:/feed/" + topicId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/deletePost/{id}/{topicId}"})
|
|
||||||
public String deletePost(@PathVariable Long id, @PathVariable Long topicId) {
|
|
||||||
postService.deletePost(id);
|
|
||||||
return "redirect:/feed/" + topicId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"postModal/{id}/{topicId}"})
|
|
||||||
public String getPostEditModal(@PathVariable Long id,@PathVariable Long topicId, Model model) {
|
|
||||||
model.addAttribute("selectedPost", new PostDto(postService.findPostById(id)));
|
|
||||||
model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
|
|
||||||
model.addAttribute("posts", topicService.findTopicById(topicId).getPosts().stream().map(PostDto::new).toList());
|
|
||||||
|
|
||||||
UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var user = userService.findUserByLogin(principal.getUsername());
|
|
||||||
model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
|
|
||||||
model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(topicId)));
|
|
||||||
return "editPostModal";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"editPost/{id}/{topicId}/"})
|
|
||||||
public String editPost(@PathVariable Long id, @PathVariable Long topicId, @RequestParam(value="postEditField") String postEditField) {
|
|
||||||
postService.updatePost(id, postEditField);
|
|
||||||
return "redirect:/feed/" + topicId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"commentModal/{topicId}/{postId}"})
|
|
||||||
public String getCommentModal(@PathVariable Long topicId,@PathVariable Long postId, Model model) {
|
|
||||||
model.addAttribute("selectedPost", new PostDto(postService.findPostById(postId)));
|
|
||||||
model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
|
|
||||||
model.addAttribute("posts", topicService.findTopicById(topicId).getPosts().stream().map(PostDto::new).toList());
|
|
||||||
|
|
||||||
UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var user = userService.findUserByLogin(principal.getUsername());
|
|
||||||
model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
|
|
||||||
model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(topicId)));
|
|
||||||
return "commentModal";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"comment/{authorId}/{topicId}/{postId}/"})
|
|
||||||
public String createComment(@PathVariable Long authorId, @PathVariable Long topicId, @PathVariable Long postId, @RequestParam(value="commentInputField") String commentInputField) {
|
|
||||||
commentService.addComment(commentInputField, authorId, postId);
|
|
||||||
return "redirect:/feed/" + topicId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/deleteComment/{id}/{topicId}"})
|
|
||||||
public String deleteComment(@PathVariable Long id, @PathVariable Long topicId) {
|
|
||||||
commentService.deleteComment(id);
|
|
||||||
return "redirect:/feed/" + topicId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"commentEditModal/{id}/{topicId}"})
|
|
||||||
public String getCommentEditModal(@PathVariable Long id,@PathVariable Long topicId, Model model) {
|
|
||||||
model.addAttribute("selectedComment", new CommentDto(commentService.findCommentById(id)));
|
|
||||||
model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
|
|
||||||
model.addAttribute("posts", topicService.findTopicById(topicId).getPosts().stream().map(PostDto::new).toList());
|
|
||||||
|
|
||||||
UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var user = userService.findUserByLogin(principal.getUsername());
|
|
||||||
model.addAttribute("selectedProfile", new UserDto(userService.findUserById(user.getId())));
|
|
||||||
model.addAttribute("selectedTopic", new TopicDto(topicService.findTopicById(topicId)));
|
|
||||||
return "editCommentModal";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"editComment/{topicId}/{commentId}/"})
|
|
||||||
public String editComment(@PathVariable Long topicId,@PathVariable Long commentId, @RequestParam(value="commentEditField") String commentEditField) {
|
|
||||||
commentService.updateComment(commentId, commentEditField);
|
|
||||||
return "redirect:/feed/" + topicId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package com.webproglabs.lab1.mvc;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dto.TopicDto;
|
|
||||||
import com.webproglabs.lab1.dto.UserSignupDto;
|
|
||||||
import com.webproglabs.lab1.models.UserRole;
|
|
||||||
import com.webproglabs.lab1.services.TopicService;
|
|
||||||
import org.springframework.security.access.annotation.Secured;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/topic")
|
|
||||||
public class TopicMvcController {
|
|
||||||
private final TopicService topicService;
|
|
||||||
|
|
||||||
public TopicMvcController(TopicService topicService) {
|
|
||||||
this.topicService = topicService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String getTopics(Model model) {
|
|
||||||
model.addAttribute("topics", topicService.findAllTopics().stream().map(TopicDto::new).toList());
|
|
||||||
model.addAttribute("topicDto", new TopicDto());
|
|
||||||
return "topics";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/create"})
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String createTopic(@ModelAttribute TopicDto topicDto) {
|
|
||||||
topicService.addTopic(topicDto.getName(), topicDto.getDescription());
|
|
||||||
return "redirect:/topic";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/delete/{Id}"})
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String deleteTopic(@PathVariable Long Id) {
|
|
||||||
topicService.deleteTopic(Id);
|
|
||||||
return "redirect:/topic";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"/edit/{Id}"})
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String getTopicEdit(@PathVariable Long Id, Model model) {
|
|
||||||
model.addAttribute("topic", new TopicDto(topicService.findTopicById(Id)));
|
|
||||||
model.addAttribute("topicDto", new TopicDto(topicService.findTopicById(Id)));
|
|
||||||
return "topicEdit";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/edit/{Id}"})
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String editTopic(@PathVariable Long Id, @ModelAttribute TopicDto topicDto) {
|
|
||||||
topicService.updateTopic(Id, topicDto.getName(), topicDto.getDescription());
|
|
||||||
return "redirect:/topic";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
package com.webproglabs.lab1.mvc;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dto.UserDto;
|
|
||||||
import com.webproglabs.lab1.dto.UserSignupDto;
|
|
||||||
import com.webproglabs.lab1.models.User;
|
|
||||||
import com.webproglabs.lab1.models.UserRole;
|
|
||||||
import com.webproglabs.lab1.services.UserService;
|
|
||||||
import org.springframework.security.access.annotation.Secured;
|
|
||||||
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 javax.validation.Valid;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/users")
|
|
||||||
public class UserMvcController {
|
|
||||||
private final UserService userService;
|
|
||||||
|
|
||||||
public UserMvcController(UserService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String getUsersPage(Model model){
|
|
||||||
model.addAttribute("profiles", userService.findAllUsers().stream().map(UserDto::new).toList());
|
|
||||||
return "users";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/{id}"})
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String deleteUser(@PathVariable Long id) {
|
|
||||||
userService.deleteUser(id);
|
|
||||||
return "redirect:/users";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"/{login}"})
|
|
||||||
public String getUserPage(@PathVariable String login, Model model) {
|
|
||||||
model.addAttribute("user", new UserDto(userService.findUserByLogin(login)));
|
|
||||||
return "userPage";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"/settings"})
|
|
||||||
public String getUserEditPage(Model model) {
|
|
||||||
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var currentUser = userService.findUserByLogin(principal.getUsername());
|
|
||||||
model.addAttribute("user", new UserDto(userService.findUserById(currentUser.getId())));
|
|
||||||
model.addAttribute("userDto", new UserSignupDto());
|
|
||||||
|
|
||||||
return "userEditPage";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/edit/{id}"})
|
|
||||||
public String editUserData(@PathVariable Long id, @ModelAttribute("userDto") @Valid UserSignupDto userSignupDto,
|
|
||||||
BindingResult bindingResult,
|
|
||||||
Model model) {
|
|
||||||
UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var currentUser = userService.findUserByLogin(principal.getUsername());
|
|
||||||
model.addAttribute("user", new UserDto(userService.findUserById(currentUser.getId())));
|
|
||||||
model.addAttribute("userDto", new UserSignupDto());
|
|
||||||
|
|
||||||
if (bindingResult.hasErrors()) {
|
|
||||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
|
||||||
return "userEditPage";
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final User user = userService.updateUser(id, userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
|
|
||||||
model.addAttribute("success", "Данные успешно изменены");
|
|
||||||
return "userEditPage";
|
|
||||||
} catch (Exception e) {
|
|
||||||
model.addAttribute("errors", e.getMessage());
|
|
||||||
return "userEditPage";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package com.webproglabs.lab1.mvc;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dto.UserSignupDto;
|
|
||||||
import com.webproglabs.lab1.models.User;
|
|
||||||
import com.webproglabs.lab1.services.UserService;
|
|
||||||
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 javax.validation.Valid;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping()
|
|
||||||
public class UserSignupMvcController {
|
|
||||||
public static final String SIGNUP_URL = "/signup";
|
|
||||||
|
|
||||||
private final UserService userService;
|
|
||||||
|
|
||||||
public UserSignupMvcController(UserService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public String toFeed() {
|
|
||||||
return "redirect:/feed";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(SIGNUP_URL)
|
|
||||||
public String showSignupForm(Model model) {
|
|
||||||
model.addAttribute("userDto", new UserSignupDto());
|
|
||||||
return "signup";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(SIGNUP_URL)
|
|
||||||
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.createUser(userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
|
|
||||||
return "redirect:/login?created=" + user.getLogin();
|
|
||||||
} catch (Exception e) {
|
|
||||||
model.addAttribute("errors", e.getMessage());
|
|
||||||
return "signup";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
package com.webproglabs.lab1.services;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dao.CommentRepository;
|
|
||||||
import com.webproglabs.lab1.dao.PostRepository;
|
|
||||||
import com.webproglabs.lab1.dao.UserRepository;
|
|
||||||
import com.webproglabs.lab1.models.Comment;
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
import com.webproglabs.lab1.models.User;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class CommentService {
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
private final CommentRepository commentRepository;
|
|
||||||
private final PostRepository postRepository;
|
|
||||||
|
|
||||||
public CommentService(UserRepository profileRepository, CommentRepository commentRepository, PostRepository postRepository) {
|
|
||||||
this.userRepository = profileRepository;
|
|
||||||
this.commentRepository = commentRepository;
|
|
||||||
this.postRepository = postRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment findCommentById(Long id) {
|
|
||||||
final Optional<Comment> comment = commentRepository.findById(id);
|
|
||||||
return comment.orElseThrow(EntityNotFoundException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Comment> findAllComments() {
|
|
||||||
return commentRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment addComment(String text, Long userId, Long postId) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Comment data is null or empty");
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
User user = userRepository.findById(userId).get();
|
|
||||||
Post post = postRepository.findById(postId).get();
|
|
||||||
Comment comment = new Comment(text, user, post);
|
|
||||||
user.addComment(comment);
|
|
||||||
post.addComment(comment);
|
|
||||||
userRepository.save(user);
|
|
||||||
postRepository.save(post);
|
|
||||||
return commentRepository.save(comment);
|
|
||||||
}
|
|
||||||
catch (Exception exception) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment updateComment(Long id, String text) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Comment data is null or empty");
|
|
||||||
}
|
|
||||||
Comment currentComment = findCommentById(id);
|
|
||||||
currentComment.setText(text);
|
|
||||||
final User owner = currentComment.getOwner();
|
|
||||||
userRepository.save(owner);
|
|
||||||
final Post post = currentComment.getPost();
|
|
||||||
postRepository.save(post);
|
|
||||||
return commentRepository.save(currentComment);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment deleteComment(Long id) {
|
|
||||||
final Comment currentComment = findCommentById(id);
|
|
||||||
commentRepository.delete(currentComment);
|
|
||||||
return currentComment;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
package com.webproglabs.lab1.services;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dao.CommentRepository;
|
|
||||||
import com.webproglabs.lab1.dao.PostRepository;
|
|
||||||
import com.webproglabs.lab1.dao.TopicRepository;
|
|
||||||
import com.webproglabs.lab1.dao.UserRepository;
|
|
||||||
import com.webproglabs.lab1.models.Comment;
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
import com.webproglabs.lab1.models.Topic;
|
|
||||||
import com.webproglabs.lab1.models.User;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class PostService {
|
|
||||||
private final PostRepository postRepository;
|
|
||||||
private final CommentRepository commentRepository;
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
private final TopicRepository topicRepository;
|
|
||||||
|
|
||||||
public PostService(PostRepository postRepository, CommentRepository commentRepository, UserRepository userRepository, TopicRepository topicRepository) {
|
|
||||||
this.postRepository = postRepository;
|
|
||||||
this.commentRepository = commentRepository;
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
this.topicRepository = topicRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post findPostById(Long id) {
|
|
||||||
final Optional<Post> post = postRepository.findById(id);
|
|
||||||
return post.orElseThrow(EntityNotFoundException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Post> findAllPosts() {
|
|
||||||
return postRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Post> findPostsInTopicByText(String text, Long topicId) {
|
|
||||||
Topic topic = topicRepository.findById(topicId).get();
|
|
||||||
return postRepository.findPostsByTextInTopic(text, topic);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post addPost (String text, Long authorId, Long topicId) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Post data is null or empty");
|
|
||||||
}
|
|
||||||
User author = userRepository.findById(authorId).get();
|
|
||||||
Topic topic = topicRepository.findById(topicId).get();
|
|
||||||
Post post = new Post(text, author, topic);
|
|
||||||
author.addPost(post);
|
|
||||||
topic.addPost(post);
|
|
||||||
userRepository.save(author);
|
|
||||||
topicRepository.save(topic);
|
|
||||||
return postRepository.save(post);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post updatePost(Long id, String text) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Post data is null or empty");
|
|
||||||
}
|
|
||||||
final Post currentPost = findPostById(id);
|
|
||||||
currentPost.setText(text);
|
|
||||||
final User author = currentPost.getAuthor();
|
|
||||||
userRepository.save(author);
|
|
||||||
final Topic topic = currentPost.getTopic();
|
|
||||||
topicRepository.save(topic);
|
|
||||||
return postRepository.save(currentPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post deletePost(Long id) {
|
|
||||||
final Post currentPost = findPostById(id);
|
|
||||||
postRepository.delete(currentPost);
|
|
||||||
return currentPost;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
package com.webproglabs.lab1.services;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dao.TopicRepository;
|
|
||||||
import com.webproglabs.lab1.models.Post;
|
|
||||||
import com.webproglabs.lab1.models.Topic;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class TopicService {
|
|
||||||
private final TopicRepository topicRepository;
|
|
||||||
|
|
||||||
public TopicService(TopicRepository topicRepository) {
|
|
||||||
this.topicRepository = topicRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Topic addTopic(String name, String description) {
|
|
||||||
if (!StringUtils.hasText(name) || !StringUtils.hasText(description)) {
|
|
||||||
throw new IllegalArgumentException("Name is null or empty");
|
|
||||||
}
|
|
||||||
final Topic topic = new Topic(name, description);
|
|
||||||
return topicRepository.save(topic);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Topic findTopicById(Long id) {
|
|
||||||
final Topic topic = topicRepository.findById(id).orElse(null);
|
|
||||||
if (topic == null) {
|
|
||||||
throw new EntityNotFoundException(String.format(" topic with id [%s] is not found", id));
|
|
||||||
}
|
|
||||||
return topic;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Topic> findAllTopics() {
|
|
||||||
return topicRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Topic updateTopic(Long id, String name, String description) {
|
|
||||||
if (!StringUtils.hasText(name) || !StringUtils.hasText(description)) {
|
|
||||||
throw new IllegalArgumentException("Name is null or empty");
|
|
||||||
}
|
|
||||||
final Topic topic = findTopicById(id);
|
|
||||||
topic.setName(name);
|
|
||||||
topic.setDescription(description);
|
|
||||||
return topicRepository.save(topic);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Topic deleteTopic(Long id) {
|
|
||||||
final Topic topic = findTopicById(id);
|
|
||||||
topicRepository.delete(topic);
|
|
||||||
return topic;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
package com.webproglabs.lab1.services;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.dao.UserRepository;
|
|
||||||
import com.webproglabs.lab1.models.User;
|
|
||||||
import com.webproglabs.lab1.models.UserRole;
|
|
||||||
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.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class UserService implements UserDetailsService {
|
|
||||||
private final UserRepository userRepository;
|
|
||||||
private final PasswordEncoder passwordEncoder;
|
|
||||||
|
|
||||||
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
this.passwordEncoder = passwordEncoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public User findUserById(Long id) {
|
|
||||||
final Optional<User> user = userRepository.findById(id);
|
|
||||||
return user.orElseThrow(EntityNotFoundException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public User findUserByLogin(String login) {
|
|
||||||
final User user = userRepository.findOneByLoginIgnoreCase(login).orElse(null);
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<User> findAllUsers() {
|
|
||||||
return userRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public User createUser(String login, String password, String passwordConfirm, UserRole role) {
|
|
||||||
if (findUserByLogin(login) != null) {
|
|
||||||
throw new IllegalArgumentException("User " + login + " already exists");
|
|
||||||
}
|
|
||||||
final User user = new User(login, passwordEncoder.encode(password), role);
|
|
||||||
if (!Objects.equals(password, passwordConfirm)) {
|
|
||||||
throw new IllegalArgumentException("Passwords not equals");
|
|
||||||
}
|
|
||||||
return userRepository.save(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public User createUser(String login, String password, String passwordConfirm) {
|
|
||||||
return createUser(login, password, passwordConfirm, UserRole.USER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public User updateUser(Long id, String login, String password, String passwordConfirm) {
|
|
||||||
if (!StringUtils.hasText(login) || !StringUtils.hasText(password)) {
|
|
||||||
throw new IllegalArgumentException("User data is null or empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
final User currentUser = findUserById(id);
|
|
||||||
|
|
||||||
if (Objects.equals(password, currentUser.getPassword())) {
|
|
||||||
throw new IllegalArgumentException("New password is the same as old");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Objects.equals(password, passwordConfirm)) {
|
|
||||||
throw new IllegalArgumentException("Password mismatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
currentUser.setLogin(login);
|
|
||||||
currentUser.setPassword(passwordEncoder.encode(password));
|
|
||||||
return userRepository.save(currentUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public User deleteUser(Long id) {
|
|
||||||
final User currentUser = findUserById(id);
|
|
||||||
userRepository.delete(currentUser);
|
|
||||||
return currentUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
||||||
final User userEntity = findUserByLogin(username);
|
|
||||||
if (userEntity == null) {
|
|
||||||
throw new UsernameNotFoundException(username);
|
|
||||||
}
|
|
||||||
return new org.springframework.security.core.userdetails.User(
|
|
||||||
userEntity.getLogin(), userEntity.getPassword(), Collections.singleton(userEntity.getRole()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="modalFeed">
|
|
||||||
|
|
||||||
<div class="modal fade" id="commentCreate" tabindex="-1" role="dialog" aria-labelledby="commentCreateLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="commentCreateLabel">Создать комментарий</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/comment/{id}/{topicId}/{postId}/{text} (id=${selectedProfile.id}, topicId=${selectedTopic.id}, postId=${selectedPost.id}, text=${commentInputField}) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Текст комментария:</p>
|
|
||||||
<input th:value="${commentInputField}" id="commentInputField" name="commentInputField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Сохранить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,49 +0,0 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="ru"
|
|
||||||
xmlns:th="http://www.thymeleaf.org"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8"/>
|
|
||||||
<title>СоцСеточка</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
||||||
<link rel="icon" href="/favicon.svg">
|
|
||||||
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></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="/css/style.css"/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="bg-light w-75 rounded-pill text-center pt-4 pb-4 mt-3 mx-auto">
|
|
||||||
<p class='text-center h3'> СоцСеточка</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p class='h4 mt-2 text-center'>
|
|
||||||
<a sec:authorize="hasRole('ROLE_ADMIN')" href="/topic" class="text-decoration-none m-3 text-secondary ">Темы</a>
|
|
||||||
<a sec:authorize="hasRole('ROLE_ADMIN')" href="/users" class="text-decoration-none m-3 text-secondary ">Пользователи</a>
|
|
||||||
<a sec:authorize="isAuthenticated()" href="/feed" class="text-decoration-none m-3 text-secondary ">Лента</a>
|
|
||||||
<a sec:authorize="isAuthenticated()" href="/users/settings" class="text-decoration-none m-3 text-secondary ">Настройки</a>
|
|
||||||
<a sec:authorize="isAuthenticated()" href="/logout" class="text-decoration-none m-3 text-secondary ">
|
|
||||||
Выход
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div >
|
|
||||||
<div layout:fragment="content"></div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.onload = () => {
|
|
||||||
$('#postEdit').modal('show');
|
|
||||||
$('#commentCreate').modal('show');
|
|
||||||
$('#commentEdit').modal('show');
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</html>
|
|
@ -1,30 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="modalFeed">
|
|
||||||
|
|
||||||
<div class="modal fade" id="commentEdit" tabindex="-1" role="dialog" aria-labelledby="commentEditLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="commentEditLabel">Редактировать комментарий</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/editComment/{id}/{commentId}/{text} (id=${selectedTopic.id}, commentId=${selectedComment.id}, text=${commentEditField}) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Новый текст комментария:</p>
|
|
||||||
<input th:attr="value = ${selectedComment.text}" id="commentEditField" name="commentEditField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Изменить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div layout:fragment="modalFeed">
|
|
||||||
|
|
||||||
<div class="modal fade" id="postEdit" tabindex="-1" role="dialog" aria-labelledby="postEditLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="postEditLabel">Редактировать пост</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/editPost/{id}/{topicId}/{text} (id=${selectedPost.id}, topicId=${selectedTopic.id}, text=${postEditField} ) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Текст поста:</p>
|
|
||||||
<input th:attr="value = ${selectedPost.text}" id="postEditField" name="postEditField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Сохранить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,13 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<body>
|
|
||||||
<div class="container" layout:fragment="content">
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<span th:text="${error}"></span>
|
|
||||||
</div>
|
|
||||||
<a href="/">На главную</a>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="dropdown text-center mx-auto w-75">
|
|
||||||
<div class="text-center mt-3">
|
|
||||||
<button class="btn btn-secondary dropdown-toggle mb-3 w-100" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
Выбор темы
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu w-100" >
|
|
||||||
<li th:each="topic: ${topics}">
|
|
||||||
<a class="dropdown-item" th:href="@{/feed/{id}(id=${topic.id})}" th:text="${topic.name + '. ' + topic.description}">
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div layout:fragment="contentFeed"></div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,110 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feed}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="contentFeed">
|
|
||||||
|
|
||||||
<div class='mb-3 mx-auto w-75'>
|
|
||||||
<div class="text-center w-100 border border-2 bg-light">
|
|
||||||
<p class="text-center h3" th:text="${selectedTopic.name}"></p>
|
|
||||||
<p class="text-center fw-light" th:text="${selectedTopic.description}"></p>
|
|
||||||
</div>
|
|
||||||
<p class="text-end h3 " th:text="${selectedProfile.login}"></p>
|
|
||||||
</div>
|
|
||||||
<div class='h3 m-3 d-flex justify-content-between text-center mx-auto w-75'>
|
|
||||||
|
|
||||||
Лента
|
|
||||||
<button type='button' class="btn btn-primary ms-5 mb-3 " data-bs-toggle="modal" data-bs-target="#postCreate">
|
|
||||||
Добавить новый пост
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form th:action="@{/feed/filter/{id}/{text} (id=${selectedTopic.id}, text=${searchField}) }" method="get">
|
|
||||||
<input th:value="${searchField}" id="searchField" name="searchField" type="text" class="mb-2" style="width: 70%" placeholder="Поиск...">
|
|
||||||
<button type='submit' class="btn btn-primary mb-2" style="width: 5%">
|
|
||||||
Найти
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
<div th:each="post: ${posts}" class="text-center mx-auto w-75 mb-3 ">
|
|
||||||
<div class="border p-2">
|
|
||||||
<p th:text="${post.text}" class="h4 text-start"></p>
|
|
||||||
<div class="d-flex justify-content-between fst-italic">
|
|
||||||
<div>
|
|
||||||
Автор:
|
|
||||||
<a th:text="${post.getAuthor()}" class="text-start fst-italic" th:href="@{/users/{login}(login=${post.getAuthor()})}"></a>
|
|
||||||
</div>
|
|
||||||
<div th:if="${selectedProfile.getLogin() == post.getAuthor()}" class="d-flex justify-content-between fst-italic">
|
|
||||||
<form th:action="@{/feed/deletePost/{id}/{topicId} (id=${post.id}, topicId=${selectedTopic.id})}" method="post" >
|
|
||||||
<button type="submit" class="btn btn-danger me-1 mb-1 ms-2" >
|
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<form th:action="@{/feed/postModal/{id}/{topicId} (id=${post.id}, topicId=${selectedTopic.id})}" method="get">
|
|
||||||
<button type="submit" class="btn btn-warning mb-1" data-bs-toggle="modal" data-bs-target="#postEdit" >
|
|
||||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="border p-2" th:if="${post.comments.size() > 0}" >
|
|
||||||
<div class="text-start">
|
|
||||||
<p class="text-start h5">Комментарии:</p>
|
|
||||||
<div th:each="comment: ${post.comments}" >
|
|
||||||
<p class="fst-italic" th:text="${comment.getAuthor() + ':'}"> </p>
|
|
||||||
<div class="d-flex justify-content-between fst-italic">
|
|
||||||
<p class="ms-3" th:text="${comment.text}"></p>
|
|
||||||
|
|
||||||
<div th:if="${selectedProfile.getLogin() == comment.getAuthor()}" class="d-flex justify-content-between fst-italic">
|
|
||||||
<form th:action="@{/feed/deleteComment/{id}/{topicId} (id=${comment.id}, topicId=${selectedTopic.id})}" method="post" >
|
|
||||||
<button type="submit" class="btn btn-danger me-1 mb-1"> <i class="fa fa-trash" aria-hidden="true"> </i> </button>
|
|
||||||
</form>
|
|
||||||
<form th:action="@{/feed/commentEditModal/{id}/{topicId} (id=${comment.id}, topicId=${selectedTopic.id})}" method="get">
|
|
||||||
<button type="submit" class="btn btn-warning mb-1" data-bs-toggle="modal" data-bs-target="#postEdit" >
|
|
||||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/commentModal/{topicId}/{postId}/ ( topicId=${selectedTopic.id}, postId=${post.id} ) }" method="get" class="text-end">
|
|
||||||
<button type="submit" class="btn btn-info mb-3" data-bs-toggle="modal" data-bs-target="#commentCreate">Добавить комментарий</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" id="postCreate" tabindex="-1" role="dialog" aria-labelledby="postCreateLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="postCreateLabel">Создать пост</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/{topicId}/post/{id}/{text} (topicId=${selectedTopic.id}, id=${selectedProfile.id}, text=${postInputField}) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Текст поста:</p>
|
|
||||||
<input th:value="${postInputField}" id="postInputField" name="postInputField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Сохранить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div layout:fragment="modalFeed"></div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,31 +0,0 @@
|
|||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<body>
|
|
||||||
<div class="container" layout:fragment="content">
|
|
||||||
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
|
|
||||||
Пользователь не найден или пароль указан не верно
|
|
||||||
</div>
|
|
||||||
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
|
|
||||||
Выход успешно произведен
|
|
||||||
</div>
|
|
||||||
<div th:if="${param.created}" class="alert alert-success margin-bottom">
|
|
||||||
Пользователь '<span th:text="${param.created}"></span>' успешно создан
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/login}" method="post" class="container-padding">
|
|
||||||
<div class="mb-3">
|
|
||||||
<input type="text" name="username" id="username" class="form-control"
|
|
||||||
placeholder="Логин" required="true" autofocus="true"/>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<input type="password" name="password" id="password" class="form-control"
|
|
||||||
placeholder="Пароль" required="true"/>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-success button-fixed">Войти</button>
|
|
||||||
<a class="btn btn-primary button-fixed" href="/signup">Регистрация</a>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,28 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<body>
|
|
||||||
<div class="container container-padding" 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">
|
|
||||||
<input type="text" class="form-control" th:field="${userDto.login}"
|
|
||||||
placeholder="Логин" required="true" autofocus="true" maxlength="64"/>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<input type="password" class="form-control" th:field="${userDto.password}"
|
|
||||||
placeholder="Пароль" required="true" minlength="4" maxlength="64"/>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<input type="password" class="form-control" th:field="${userDto.passwordConfirm}"
|
|
||||||
placeholder="Пароль (подтверждение)" required="true" minlength="4" maxlength="64"/>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<button type="submit" class="btn btn-success button-fixed">Создать</button>
|
|
||||||
<a class="btn btn-primary button-fixed" href="/login">Назад</a>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,19 +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">
|
|
||||||
<body>
|
|
||||||
<div class="container container-padding" layout:fragment="content">
|
|
||||||
<div class="h4 text-center">Изменить топик</div>
|
|
||||||
<form action="#" th:action="@{/topic/edit/{id} (id=${topic.id})}" th:object="${topicDto}" method="post">
|
|
||||||
<p>Новое название:</p>
|
|
||||||
<input th:field="${topicDto.name}" type="text" class="mb-2 form-control" required="true" />
|
|
||||||
<p>Новое описание:</p>
|
|
||||||
<input th:field="${topicDto.description}" type="text" class="mb-2 form-control" required="true" />
|
|
||||||
<button type="submit" class="btn btn-success" >Сохранить изменения</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<body>
|
|
||||||
<div class="container container-padding" layout:fragment="content">
|
|
||||||
|
|
||||||
<form action="#" th:action="@{/topic/create}" th:object="${topicDto}" method="post">
|
|
||||||
<p>Название:</p>
|
|
||||||
<input th:field="${topicDto.name}" type="text" class="mb-2 form-control" required="true" />
|
|
||||||
<p>Описание:</p>
|
|
||||||
<input th:field="${topicDto.description}" type="text" class="mb-2 form-control" required="true" />
|
|
||||||
<button type="submit" class="btn btn-success">Добавить</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div th:each="topic: ${topics}" class="border p-3 m-3 shadow-lg bg-body rounded">
|
|
||||||
<div th:text="${'Топик: ' + topic.name}"></div>
|
|
||||||
<div th:text="${'Описание: ' + topic.description}"></div>
|
|
||||||
<form action="#" th:action="@{/topic/edit/{id} (id=${topic.id})}" method="get" class="text-end m-1">
|
|
||||||
<button type="submit" class="btn btn-warning">Изменить</button>
|
|
||||||
</form>
|
|
||||||
<form action="#" th:action="@{/topic/delete/{id} (id=${topic.id})}" method="post" class="text-end m-1">
|
|
||||||
<button type="submit" class="btn btn-danger" >Удалить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,31 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
|
|
||||||
<div th:if="${success}" th:text="${success}" class="margin-bottom text-success"></div>
|
|
||||||
<div class="text-start mx-auto w-50 border p-5">
|
|
||||||
<p class='h5'>Изменение данных пользователя</p>
|
|
||||||
<p th:text="${'Логин: ' + user.login}"></p>
|
|
||||||
|
|
||||||
<form action="#" th:action="@{/users/edit/{id} (id=${user.id})}" th:object="${userDto}" method="post">
|
|
||||||
<p>Новый логин:</p>
|
|
||||||
<input th:field="${userDto.login}" type="text" class="mb-2 form-control" required="true" autofocus="true" maxlength="64"/>
|
|
||||||
<p>Новый пароль:</p>
|
|
||||||
<input th:field="${userDto.password}" type="password" class="mb-2 form-control" required="true" minlength="4" maxlength="64"/>
|
|
||||||
<p>Повторите пароль:</p>
|
|
||||||
<input th:field="${userDto.passwordConfirm}" type="password" class="mb-2 form-control" required="true" minlength="4" maxlength="64"/>
|
|
||||||
<button type="submit" class="btn btn-success" >Сохранить изменения</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-start mx-auto w-50 border p-5">
|
|
||||||
<p class='h5'>Профиль</p>
|
|
||||||
<p th:text="${'Логин: ' + user.login}"></p>
|
|
||||||
<p class='h6 '>Список постов пользователя: </p>
|
|
||||||
|
|
||||||
<div th:if="${user.posts.size()>0}">
|
|
||||||
<div th:each="post: ${user.posts}">
|
|
||||||
<p th:text="${post.text}" class="mb-3 ms-2 border p-2"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p th:unless="${user.posts.size()>0}">
|
|
||||||
Нет постов
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,36 +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" class="text-center">
|
|
||||||
|
|
||||||
<div th:each="profile: ${profiles}" class="mb-2">
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-start mx-auto w-50 border shadow p-3">
|
|
||||||
<p class='h5'>Профиль</p>
|
|
||||||
<p th:text="${'Логин: ' + profile.login}"></p>
|
|
||||||
<p class='h6 '>Список постов пользователя: </p>
|
|
||||||
|
|
||||||
<div th:if="${profile.posts.size()>0}">
|
|
||||||
<div th:each="post: ${profile.posts}">
|
|
||||||
<p th:text="${post.text}" class="mb-3 ms-2 border p-2"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p th:unless="${profile.posts.size()>0}">
|
|
||||||
Нет постов
|
|
||||||
</p>
|
|
||||||
<div class="text-end" th:if="${profile.login!='admin'}">
|
|
||||||
<form action="#" th:action="@{/users/{id} (id=${profile.id})}" method="post" >
|
|
||||||
<button type="submit" class="btn btn-danger">Удалить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user