Ajout de commentaires (CRUD pas entièrement implémenté)
This commit is contained in:
parent
02ea44d57d
commit
8c7966deb2
@ -38,9 +38,10 @@ public class SpringSecurityConfig {
|
||||
"/api/authors/{id}",
|
||||
"/api/authors/{id}/posts",
|
||||
"/api/posts",
|
||||
"/api/posts/{id}").permitAll() // Autorise les GET sur ces routes
|
||||
"/api/posts/{id}",
|
||||
"/api/comments/posts/{id}",
|
||||
"/api/comments").permitAll() // Autorise les GET sur ces routes
|
||||
.requestMatchers("/api/authors/login", "/api/authors/register").permitAll() // Autorise sans authentification
|
||||
.requestMatchers("/api/authors/me").authenticated() // Requiert authentification
|
||||
.anyRequest().authenticated() // Toutes les autres routes nécessitent une authentification
|
||||
)
|
||||
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) // Ajoute le filtre JWT
|
||||
|
@ -98,7 +98,7 @@ public class AuthorController {
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<Author> authorRegister(@RequestBody Author author) {
|
||||
Assert.isNull(author.getId(), "Author id must be null");
|
||||
if (authorRepository.findByName(author.getName()) != null) {
|
||||
if (authorService.findByName(author.getName()).isPresent()) {
|
||||
throw new AlreadyExistsException("Author already exists");
|
||||
}
|
||||
author.setPassword(passwordEncoder.encode(author.getPassword()));
|
||||
@ -112,12 +112,7 @@ public class AuthorController {
|
||||
throw new ForbiddenExecption("You are not authorized to access this resource");
|
||||
}
|
||||
|
||||
String username = authentication.getName();
|
||||
Author author = authorRepository.findByName(username);
|
||||
|
||||
if (author == null) {
|
||||
throw new NotFoundException("Author not found");
|
||||
}
|
||||
Author author = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
|
||||
return author.setPassword("");
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
package com.guams.review.controller;
|
||||
|
||||
import com.guams.review.exception.ForbiddenExecption;
|
||||
import com.guams.review.exception.NotFoundException;
|
||||
import com.guams.review.model.AuthorRepository;
|
||||
import com.guams.review.model.dao.Author;
|
||||
import com.guams.review.model.dao.Comment;
|
||||
import com.guams.review.model.dao.CommentIds;
|
||||
import com.guams.review.service.AuthorService;
|
||||
import com.guams.review.service.CommentService;
|
||||
import com.guams.review.service.PostService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(path = "api/comments")
|
||||
@RequiredArgsConstructor
|
||||
public class CommentController {
|
||||
|
||||
private final CommentService commentService;
|
||||
private final AuthorRepository authorRepository;
|
||||
private final PostService postService;
|
||||
private final AuthorService authorService;
|
||||
|
||||
@GetMapping
|
||||
public List<Comment> listAllComments() {
|
||||
return commentService.list();
|
||||
}
|
||||
|
||||
@PostMapping("/posts/{id}")
|
||||
public ResponseEntity<Comment> addComment(@RequestBody Comment comment, Authentication authentication, @PathVariable("id") Long postId) {
|
||||
if (authentication == null || !authentication.isAuthenticated()) {
|
||||
throw new ForbiddenExecption("You are not authorized to access this resource");
|
||||
}
|
||||
|
||||
Author author = authorRepository.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
Comment insertedComment = commentService.insert(comment
|
||||
.setCommentDate(Timestamp.from(Instant.now()))
|
||||
.setIsUpdated(false));
|
||||
postService.findById(postId).orElseThrow(() -> new NotFoundException("Post not found"));
|
||||
|
||||
commentService.associateCommentToPostAndAuthor(author.getId(), postId, insertedComment.getId());
|
||||
return new ResponseEntity<>(insertedComment, HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@GetMapping("/posts/{id}")
|
||||
public List<Comment> listCommentsByPostId(@PathVariable("id") Long postId) {
|
||||
postService.findById(postId).orElseThrow(() -> new NotFoundException("Post not found"));
|
||||
return commentService.getCommentsByCommentId(postId);
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public void updateComment(@PathVariable Long id, @RequestBody CommentIds commentIds, Authentication authentication) {
|
||||
if (authentication == null || !authentication.isAuthenticated()) {
|
||||
throw new ForbiddenExecption("You are not authorized to access this resource");
|
||||
}
|
||||
|
||||
Author author = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
Comment commentToUpdate = commentService.findById(id).orElseThrow(() -> new NotFoundException("Comment not found"));
|
||||
CommentIds concernedCommentIds = commentService.getCommentIdsByCommentId(id).orElseThrow(() -> new NotFoundException("Comment not found"));
|
||||
if (!author.getId().equals(concernedCommentIds.getAuthorId())) {
|
||||
throw new ForbiddenExecption("You are not authorized to access this resource");
|
||||
}
|
||||
|
||||
commentService.insert(commentToUpdate
|
||||
.setIsUpdated(true)
|
||||
.setContent(commentIds.getContent()));
|
||||
}
|
||||
|
||||
// @DeleteMapping("/{id}")
|
||||
// public void deleteComment(@PathVariable Long id, Authentication authentication) {}
|
||||
}
|
@ -2,8 +2,8 @@ package com.guams.review.controller;
|
||||
|
||||
import com.guams.review.exception.ForbiddenExecption;
|
||||
import com.guams.review.exception.NotFoundException;
|
||||
import com.guams.review.model.AuthorRepository;
|
||||
import com.guams.review.model.dao.Author;
|
||||
import com.guams.review.model.dao.Comment;
|
||||
import com.guams.review.model.dao.Post;
|
||||
import com.guams.review.service.AuthorService;
|
||||
import com.guams.review.service.PostService;
|
||||
@ -19,6 +19,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@ -28,7 +29,6 @@ public class PostController {
|
||||
|
||||
private final PostService postService;
|
||||
private final AuthorService authorService;
|
||||
private final AuthorRepository authorRepository;
|
||||
|
||||
@GetMapping
|
||||
public List<Post> listPosts() {
|
||||
@ -45,14 +45,15 @@ public class PostController {
|
||||
if (authentication == null) {
|
||||
throw new ForbiddenExecption("You have to login to do that");
|
||||
}
|
||||
Author authenticatedAuthor = authorRepository.findByName(authentication.getName());
|
||||
Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
//Si l'user authent possède ce post
|
||||
if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) {
|
||||
Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found"));
|
||||
postService.insert(updatedPost
|
||||
.setId(postToUpdate.getId())
|
||||
.setIllustration(postToUpdate.getIllustration())
|
||||
.setPublicationDate(postToUpdate.getPublicationDate()));
|
||||
.setPublicationDate(postToUpdate.getPublicationDate())
|
||||
.setIsUpdated(true));
|
||||
} else {
|
||||
throw new ForbiddenExecption("You do not have permission to update this post");
|
||||
}
|
||||
@ -63,7 +64,7 @@ public class PostController {
|
||||
if (authentication == null) {
|
||||
throw new ForbiddenExecption("You have to login to do that");
|
||||
}
|
||||
Author authenticatedAuthor = authorRepository.findByName(authentication.getName());
|
||||
Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) {
|
||||
Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found"));
|
||||
postService.insert(postToUpdate.setIllustration(illustration.getBytes()));
|
||||
@ -78,7 +79,14 @@ public class PostController {
|
||||
if (authentication == null) {
|
||||
throw new ForbiddenExecption("You have to login to do that");
|
||||
}
|
||||
return new ResponseEntity<>(postService.insert(postToCreate.setPublicationDate(Timestamp.from(Instant.now()))), HttpStatus.CREATED);
|
||||
return new ResponseEntity<>(postService.insert(postToCreate
|
||||
.setPublicationDate(Timestamp.from(Instant.now()))
|
||||
.setIsUpdated(false)), HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/comments")
|
||||
public List<Comment> listCommentsByPostId(@PathVariable Long id) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@ -86,7 +94,7 @@ public class PostController {
|
||||
if (authentication == null) {
|
||||
throw new ForbiddenExecption("You have to login to do that");
|
||||
}
|
||||
Author authenticatedAuthor = authorRepository.findByName(authentication.getName());
|
||||
Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) {
|
||||
Post postToDelete = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found"));
|
||||
postService.delete(authenticatedAuthor.getId(), postToDelete.getId());
|
||||
|
@ -7,6 +7,7 @@ import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
@ -22,5 +23,5 @@ public interface AuthorRepository extends CrudRepository<Author, UUID> {
|
||||
|
||||
List<Author> findAll();
|
||||
|
||||
Author findByName(String name);
|
||||
Optional<Author> findByName(String name);
|
||||
}
|
||||
|
27
src/main/java/com/guams/review/model/CommentRepository.java
Normal file
27
src/main/java/com/guams/review/model/CommentRepository.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.guams.review.model;
|
||||
|
||||
import com.guams.review.model.dao.Comment;
|
||||
import com.guams.review.model.dao.CommentIds;
|
||||
import org.springframework.data.jdbc.repository.query.Modifying;
|
||||
import org.springframework.data.jdbc.repository.query.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface CommentRepository extends CrudRepository<Comment, Long> {
|
||||
|
||||
List<Comment> findAll();
|
||||
|
||||
@Query("select post_fk, comment_fk, author_fk from comment_association where comment_fk = :commentId")
|
||||
Optional<CommentIds> getCommentIdsByCommentId(Long commentId);
|
||||
|
||||
@Query("select distinct comment.id, comment.content, comment.comment_date, comment.is_updated from comment join comment_association on " +
|
||||
"comment_association.post_fk = :commentId")
|
||||
List<Comment> getCommentsByCommentId(Long commentId);
|
||||
|
||||
@Modifying
|
||||
@Query("insert into comment_association(comment_fk, post_fk, author_fk) values (:commentId, :postId, :authorId);")
|
||||
void associateCommentToUserAndPost(UUID authorId, Long postId, Long commentId);
|
||||
}
|
@ -7,11 +7,7 @@ import lombok.experimental.Accessors;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.mapping.Table;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
|
26
src/main/java/com/guams/review/model/dao/Comment.java
Normal file
26
src/main/java/com/guams/review/model/dao/Comment.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.guams.review.model.dao;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.mapping.Table;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
|
||||
@Table(name = "comment")
|
||||
public class Comment {
|
||||
@Id
|
||||
Long id;
|
||||
@Column("content")
|
||||
String content;
|
||||
@Column("comment_date")
|
||||
Timestamp commentDate;
|
||||
@Column("is_updated")
|
||||
Boolean isUpdated;
|
||||
}
|
25
src/main/java/com/guams/review/model/dao/CommentIds.java
Normal file
25
src/main/java/com/guams/review/model/dao/CommentIds.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.guams.review.model.dao;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.relational.core.mapping.Column;
|
||||
import org.springframework.data.relational.core.mapping.Table;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@Table("comment_association")
|
||||
public class CommentIds {
|
||||
|
||||
@Id
|
||||
Long postId;
|
||||
@Column("comment_fk")
|
||||
Long commentId;
|
||||
@Column("author_fk")
|
||||
UUID authorId;
|
||||
String content;
|
||||
}
|
@ -28,5 +28,7 @@ public class Post {
|
||||
String category;
|
||||
@Column("publication_date")
|
||||
Timestamp publicationDate;
|
||||
@Column("is_updated")
|
||||
Boolean isUpdated;
|
||||
|
||||
}
|
||||
|
@ -59,23 +59,24 @@ public class AuthorService implements UserDetailsService
|
||||
}
|
||||
Author author = findById(id).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
String username = authentication.getName();
|
||||
Author authorAuthenticated = authorRepository.findByName(username);
|
||||
Author authorAuthenticated = authorRepository.findByName(username).orElseThrow(() -> new NotFoundException("Author not found"));
|
||||
if (authorAuthenticated.getId().compareTo(author.getId()) != 0 && !authorAuthenticated.getRole().equals("ADMIN")) {
|
||||
throw new ForbiddenExecption("Specified Author is not authorized to do that");
|
||||
}
|
||||
return author;
|
||||
}
|
||||
|
||||
public Optional<Author> findByName(String name) {
|
||||
return authorRepository.findByName(name);
|
||||
}
|
||||
|
||||
public void delete(Author author) {
|
||||
authorRepository.delete(author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
Author author = authorRepository.findByName(username);
|
||||
if (author == null) {
|
||||
throw new UsernameNotFoundException(username);
|
||||
}
|
||||
Author author = authorRepository.findByName(username).orElseThrow(() -> new UsernameNotFoundException("Author not found"));
|
||||
return new User(author.getName(), author.getPassword(), Collections.singletonList(new SimpleGrantedAuthority(author.getRole())));
|
||||
}
|
||||
}
|
||||
|
42
src/main/java/com/guams/review/service/CommentService.java
Normal file
42
src/main/java/com/guams/review/service/CommentService.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.guams.review.service;
|
||||
|
||||
import com.guams.review.model.CommentRepository;
|
||||
import com.guams.review.model.dao.Comment;
|
||||
import com.guams.review.model.dao.CommentIds;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CommentService {
|
||||
|
||||
private final CommentRepository commentRepository;
|
||||
|
||||
public Optional<Comment> findById(Long id) {
|
||||
return commentRepository.findById(id);
|
||||
}
|
||||
|
||||
public List<Comment> list() {
|
||||
return commentRepository.findAll();
|
||||
}
|
||||
|
||||
public List<Comment> getCommentsByCommentId(Long commentId) {
|
||||
return commentRepository.getCommentsByCommentId(commentId);
|
||||
}
|
||||
|
||||
public void associateCommentToPostAndAuthor(UUID authorId, Long postId, Long commentId) {
|
||||
commentRepository.associateCommentToUserAndPost(authorId, postId, commentId);
|
||||
}
|
||||
public Optional<CommentIds> getCommentIdsByCommentId(Long id) {
|
||||
return commentRepository.getCommentIdsByCommentId(id);
|
||||
}
|
||||
|
||||
public Comment insert(Comment comment) {
|
||||
return commentRepository.save(comment);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
drop table if exists comment_association;
|
||||
drop table if exists comment;
|
||||
drop table if exists publication;
|
||||
drop table if exists post;
|
||||
drop table if exists author;
|
||||
drop type if exists author_role;
|
||||
|
||||
create type author_role as enum ('READER', 'WRITER', 'ADMIN');
|
||||
|
||||
create table author
|
||||
(
|
||||
@ -11,7 +10,7 @@ create table author
|
||||
name varchar(255) unique not null,
|
||||
password text not null,
|
||||
profile_picture bytea,
|
||||
role author_role default 'READER' not null
|
||||
role varchar(10) default 'READER' not null
|
||||
);
|
||||
|
||||
create table post
|
||||
@ -22,7 +21,8 @@ create table post
|
||||
title varchar(50) not null,
|
||||
body text not null,
|
||||
category varchar(50) not null,
|
||||
publication_date timestamp not null
|
||||
publication_date timestamp not null,
|
||||
is_updated boolean default false
|
||||
);
|
||||
|
||||
create table publication
|
||||
@ -32,3 +32,22 @@ create table publication
|
||||
foreign key (author_fk) references author (id),
|
||||
foreign key (post_fk) references post (id)
|
||||
);
|
||||
|
||||
create table comment
|
||||
(
|
||||
id serial primary key,
|
||||
content varchar(512) not null,
|
||||
comment_date timestamp not null,
|
||||
is_updated boolean default false
|
||||
);
|
||||
|
||||
create table comment_association
|
||||
(
|
||||
ca_pk serial primary key,
|
||||
comment_fk serial,
|
||||
post_fk serial,
|
||||
author_fk uuid,
|
||||
foreign key (comment_fk) references comment (id),
|
||||
foreign key (post_fk) references post (id),
|
||||
foreign key (author_fk) references author (id)
|
||||
);
|
Loading…
Reference in New Issue
Block a user