Code plus propre avec enum et meilleure retour d'erreur

This commit is contained in:
Guams 2025-02-07 18:20:27 +01:00
parent 916a8ba2e4
commit 2d01f65c95
7 changed files with 72 additions and 43 deletions

View File

@ -9,26 +9,32 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.Map;
@ControllerAdvice @ControllerAdvice
public class Advice { public class Advice {
@ExceptionHandler(value = NotFoundException.class) @ExceptionHandler(value = NotFoundException.class)
public ResponseEntity<Object> handleNotFound(NotFoundException exception) { public ResponseEntity<Map<String, String>> handleNotFound(NotFoundException exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(Map.of("message", exception.getMessage()));
} }
@ExceptionHandler(value = AlreadyExistsException.class) @ExceptionHandler(value = AlreadyExistsException.class)
public ResponseEntity<Object> handleAlreadyExists(AlreadyExistsException exception) { public ResponseEntity<Map<String, String>> handleAlreadyExists(AlreadyExistsException exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST); return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("message", exception.getMessage()));
} }
@ExceptionHandler(value = InvalidNameOrPasswordException.class) @ExceptionHandler(value = InvalidNameOrPasswordException.class)
public ResponseEntity<Object> handleInvalidNameOrPassword(InvalidNameOrPasswordException exception) { public ResponseEntity<Map<String, String>> handleInvalidNameOrPassword(InvalidNameOrPasswordException exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.UNAUTHORIZED); return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(Map.of("message", exception.getMessage()));
} }
@ExceptionHandler(value = UnauthorizedExecption.class) @ExceptionHandler(value = UnauthorizedExecption.class)
public ResponseEntity<Object> handleUnauthorizedExecption(UnauthorizedExecption exception) { public ResponseEntity<Map<String, String>> handleUnauthorizedExecption(UnauthorizedExecption exception) {
return new ResponseEntity<>(exception.getMessage(), HttpStatus.UNAUTHORIZED); return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(Map.of("message", exception.getMessage()));
} }
} }

View File

@ -53,7 +53,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
// Applique le rate limiting // Applique le rate limiting
if (isRateLimited(authorUuid, request)) { if (isRateLimited(authorUuid, request)) {
response.setStatus(429); // TOO MANY REQUESTS response.setStatus(429); // TOO MANY REQUESTS
response.getWriter().write("Rate limit exceeded. Please try again later."); response.setCharacterEncoding("UTF-8");
response.getWriter().write("{\"message\":\"Vous avez envoyé trop de requête d'un coups, patientez un peu...\"}");
return; return;
} }

View File

@ -6,6 +6,7 @@ import com.guams.review.exception.UnauthorizedExecption;
import com.guams.review.exception.InvalidNameOrPasswordException; import com.guams.review.exception.InvalidNameOrPasswordException;
import com.guams.review.exception.NotFoundException; import com.guams.review.exception.NotFoundException;
import com.guams.review.model.AuthorRepository; import com.guams.review.model.AuthorRepository;
import com.guams.review.model.Role;
import com.guams.review.model.dao.Author; import com.guams.review.model.dao.Author;
import com.guams.review.model.dao.AuthorToken; import com.guams.review.model.dao.AuthorToken;
import com.guams.review.model.dao.Post; import com.guams.review.model.dao.Post;
@ -112,13 +113,13 @@ public class AuthorController {
@PostMapping("/register/admin") @PostMapping("/register/admin")
public ResponseEntity<Author> authorRegisterAdmin(@RequestBody Author authorToCreate, Authentication authentication) { public ResponseEntity<Author> authorRegisterAdmin(@RequestBody Author authorToCreate, Authentication authentication) {
Author sender = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found")); Author sender = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Cet auteur n'existe pas"));
Assert.isNull(authorToCreate.getId(), "Author id must be null"); Assert.isNull(authorToCreate.getId(), "Author id must be null");
if (authorService.findByName(authorToCreate.getName()).isPresent()) { if (authorService.findByName(authorToCreate.getName()).isPresent()) {
throw new AlreadyExistsException("Author already exists"); throw new AlreadyExistsException("Ce nom est déjà prit par un autre auteur");
} }
if (!sender.getRole().equals("ADMIN")) { if (!sender.getRole().equals(Role.ADMIN.toString())) {
throw new UnauthorizedExecption("Specified Author is not authorized to do that"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ceci");
} }
authorToCreate.setPassword(passwordEncoder.encode(authorToCreate.getPassword())); authorToCreate.setPassword(passwordEncoder.encode(authorToCreate.getPassword()));
return new ResponseEntity<>(authorRepository.save(authorToCreate).setPassword(""), HttpStatus.CREATED); return new ResponseEntity<>(authorRepository.save(authorToCreate).setPassword(""), HttpStatus.CREATED);
@ -128,19 +129,19 @@ public class AuthorController {
public ResponseEntity<Author> authorRegister(@RequestBody Author author) { public ResponseEntity<Author> authorRegister(@RequestBody Author author) {
Assert.isNull(author.getId(), "Author id must be null"); Assert.isNull(author.getId(), "Author id must be null");
if (authorService.findByName(author.getName()).isPresent()) { if (authorService.findByName(author.getName()).isPresent()) {
throw new AlreadyExistsException("Author already exists"); throw new AlreadyExistsException("Ce nom est déjà prit par un autre auteur");
} }
author.setPassword(passwordEncoder.encode(author.getPassword())); author.setPassword(passwordEncoder.encode(author.getPassword()));
return new ResponseEntity<>(authorRepository.save(author.setRole("READER")).setPassword(""), HttpStatus.CREATED); return new ResponseEntity<>(authorRepository.save(author.setRole(Role.READER.toString())).setPassword(""), HttpStatus.CREATED);
} }
@GetMapping(value = "/me", produces = "application/json") @GetMapping(value = "/me", produces = "application/json")
public Author getAuthenticatedUser(Authentication authentication) { public Author getAuthenticatedUser(Authentication authentication) {
if (authentication == null || !authentication.isAuthenticated()) { if (authentication == null || !authentication.isAuthenticated()) {
throw new UnauthorizedExecption("You are not authorized to access this resource"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ceci");
} }
Author author = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found")); Author author = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Cet auteur n'existe pas"));
return author.setPassword("").setProfilePicture(null); return author.setPassword("").setProfilePicture(null);
} }

View File

@ -42,14 +42,14 @@ public class CommentController {
@PostMapping("/posts/{post-id}") @PostMapping("/posts/{post-id}")
public ResponseEntity<Comment> addComment(@RequestBody Comment comment, Authentication authentication, @PathVariable("post-id") Long postId) { public ResponseEntity<Comment> addComment(@RequestBody Comment comment, Authentication authentication, @PathVariable("post-id") Long postId) {
if (authentication == null || !authentication.isAuthenticated()) { if (authentication == null || !authentication.isAuthenticated()) {
throw new UnauthorizedExecption("You are not authorized to access this resource"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ça");
} }
Author author = authorRepository.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found")); Author author = authorRepository.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Cet auteur n'existe pas"));
Comment insertedComment = commentService.insert(comment Comment insertedComment = commentService.insert(comment
.setCommentDate(Timestamp.from(Instant.now())) .setCommentDate(Timestamp.from(Instant.now()))
.setIsUpdated(false)); .setIsUpdated(false));
postService.findById(postId).orElseThrow(() -> new NotFoundException("Post not found")); postService.findById(postId).orElseThrow(() -> new NotFoundException("Ce post n'existe pas"));
commentService.associateCommentToPostAndAuthor(author.getId(), postId, insertedComment.getId()); commentService.associateCommentToPostAndAuthor(author.getId(), postId, insertedComment.getId());
return new ResponseEntity<>(insertedComment, HttpStatus.CREATED); return new ResponseEntity<>(insertedComment, HttpStatus.CREATED);
@ -57,21 +57,21 @@ public class CommentController {
@GetMapping("/posts/{post-id}") @GetMapping("/posts/{post-id}")
public List<CommentWithAuthor> listCommentsByPostId(@PathVariable("post-id") Long postId) { public List<CommentWithAuthor> listCommentsByPostId(@PathVariable("post-id") Long postId) {
postService.findById(postId).orElseThrow(() -> new NotFoundException("Post not found")); postService.findById(postId).orElseThrow(() -> new NotFoundException("Ce post n'existe pas"));
return commentService.getCommentsByPostId(postId); return commentService.getCommentsByPostId(postId);
} }
@PutMapping("/{id}") @PutMapping("/{id}")
public void updateComment(@PathVariable Long id, @RequestBody CommentIds commentIds, Authentication authentication) { public void updateComment(@PathVariable Long id, @RequestBody CommentIds commentIds, Authentication authentication) {
if (authentication == null || !authentication.isAuthenticated()) { if (authentication == null || !authentication.isAuthenticated()) {
throw new UnauthorizedExecption("You are not authorized to access this resource"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ceci");
} }
Author author = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found")); Author author = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Cet auteur n'existe pas"));
Comment commentToUpdate = commentService.findById(id).orElseThrow(() -> new NotFoundException("Comment not found")); Comment commentToUpdate = commentService.findById(id).orElseThrow(() -> new NotFoundException("Ce commentaire n'existe pas"));
CommentIds concernedCommentIds = commentService.getCommentIdsByCommentId(id).orElseThrow(() -> new NotFoundException("Comment not found")); CommentIds concernedCommentIds = commentService.getCommentIdsByCommentId(id).orElseThrow(() -> new NotFoundException("Ce commentaire n'existe pas"));
if (!author.getId().equals(concernedCommentIds.getAuthorId())) { if (!author.getId().equals(concernedCommentIds.getAuthorId())) {
throw new UnauthorizedExecption("You are not authorized to access this resource"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ceci");
} }
commentService.insert(commentToUpdate commentService.insert(commentToUpdate
@ -82,9 +82,9 @@ public class CommentController {
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public void deleteComment(@PathVariable Long id, Authentication authentication) { public void deleteComment(@PathVariable Long id, Authentication authentication) {
if (authentication == null || !authentication.isAuthenticated()) { if (authentication == null || !authentication.isAuthenticated()) {
throw new UnauthorizedExecption("You are not authorized to access this resource"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ceci");
} }
Comment commentToDelete = commentService.findById(id).orElseThrow(() -> new NotFoundException("Comment not found")); Comment commentToDelete = commentService.findById(id).orElseThrow(() -> new NotFoundException("Ce commentaire n'existe pas"));
commentService.deleteAssociationByCommentId(commentToDelete.getId()); commentService.deleteAssociationByCommentId(commentToDelete.getId());
commentService.delete(commentToDelete); commentService.delete(commentToDelete);
} }

View File

@ -53,33 +53,33 @@ public class PostController {
@PutMapping("/{id}") @PutMapping("/{id}")
public void updatePost(@PathVariable Long id, @RequestBody Post updatedPost, Authentication authentication) { public void updatePost(@PathVariable Long id, @RequestBody Post updatedPost, Authentication authentication) {
if (authentication == null) { if (authentication == null) {
throw new UnauthorizedExecption("You have to login to do that"); throw new UnauthorizedExecption("Vous devez vous authentifier avant de faire ça");
} }
Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found")); Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Cet auteur n'existe pas"));
//Si l'user authent possède ce post //Si l'user authent possède ce post
if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) { if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) {
Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Ce post n'existe pas"));
postService.insert(updatedPost postService.insert(updatedPost
.setId(postToUpdate.getId()) .setId(postToUpdate.getId())
.setIllustration(postToUpdate.getIllustration()) .setIllustration(postToUpdate.getIllustration())
.setPublicationDate(postToUpdate.getPublicationDate()) .setPublicationDate(postToUpdate.getPublicationDate())
.setIsUpdated(true)); .setIsUpdated(true));
} else { } else {
throw new UnauthorizedExecption("You do not have permission to update this post"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ceci");
} }
} }
@PutMapping(value = "{id}/illustration", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) @PutMapping(value = "{id}/illustration", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public void updateIllustration(@PathVariable Long id, @RequestPart("illustration") MultipartFile illustration, Authentication authentication) throws IOException { public void updateIllustration(@PathVariable Long id, @RequestPart("illustration") MultipartFile illustration, Authentication authentication) throws IOException {
if (authentication == null) { if (authentication == null) {
throw new UnauthorizedExecption("You have to login to do that"); throw new UnauthorizedExecption("Vous devez vous authentifier avant de faire ça");
} }
Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found")); Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Cet auteur n'existe pas"));
if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) { if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) {
Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Ce post n'existe pas"));
postService.insert(postToUpdate.setIllustration(illustration.getBytes())); postService.insert(postToUpdate.setIllustration(illustration.getBytes()));
} else { } else {
throw new UnauthorizedExecption("You do not have permission to update this post"); throw new UnauthorizedExecption("Vous n'êtes pas autorisé à faire ceci");
} }
} }
@ -87,7 +87,7 @@ public class PostController {
public ResponseEntity<Post> addPost(@RequestBody Post postToCreate, Authentication authentication) { public ResponseEntity<Post> addPost(@RequestBody Post postToCreate, Authentication authentication) {
Assert.isNull(postToCreate.getId(), "Post id must be null"); Assert.isNull(postToCreate.getId(), "Post id must be null");
if (authentication == null) { if (authentication == null) {
throw new UnauthorizedExecption("You have to login to do that"); throw new UnauthorizedExecption("Vous devez vous authentifier avant de faire ça");
} }
return new ResponseEntity<>(postService.insert(postToCreate return new ResponseEntity<>(postService.insert(postToCreate
.setPublicationDate(Timestamp.from(Instant.now())) .setPublicationDate(Timestamp.from(Instant.now()))
@ -102,11 +102,11 @@ public class PostController {
@DeleteMapping("{id}") @DeleteMapping("{id}")
public void deletePost(@PathVariable Long id, Authentication authentication) { public void deletePost(@PathVariable Long id, Authentication authentication) {
if (authentication == null) { if (authentication == null) {
throw new UnauthorizedExecption("You have to login to do that"); throw new UnauthorizedExecption("Vous devez vous authentifier avant de faire ça");
} }
Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Author not found")); Author authenticatedAuthor = authorService.findByName(authentication.getName()).orElseThrow(() -> new NotFoundException("Cet auteur n'existe pas"));
if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) { if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) {
Post postToDelete = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); Post postToDelete = postService.findById(id).orElseThrow(() -> new NotFoundException("Ce post n'existe pas"));
commentService.getCommentsByPostId(id) commentService.getCommentsByPostId(id)
.stream() .stream()
.map(mapper::mapCommentWithAuthor) .map(mapper::mapCommentWithAuthor)
@ -117,7 +117,7 @@ public class PostController {
.forEach(commentService::delete); .forEach(commentService::delete);
postService.delete(authenticatedAuthor.getId(), postToDelete.getId()); postService.delete(authenticatedAuthor.getId(), postToDelete.getId());
} else { } else {
throw new UnauthorizedExecption("You do not have permission to delete this post"); throw new UnauthorizedExecption("Vous n'avez pas la permission de faire ceci");
} }
} }
} }

View File

@ -0,0 +1,20 @@
package com.guams.review.model;
public enum Role {
READER {
public String toString() {
return "READER";
}
},
WRITER {
public String toString() {
return "WRITER";
}
},
ADMIN {
public String toString() {
return "ADMIN";
}
},
}

View File

@ -4,6 +4,7 @@ import com.guams.review.exception.NotFoundException;
import com.guams.review.exception.UnauthorizedExecption; import com.guams.review.exception.UnauthorizedExecption;
import com.guams.review.model.AuthorRepository; import com.guams.review.model.AuthorRepository;
import com.guams.review.model.PostRepository; import com.guams.review.model.PostRepository;
import com.guams.review.model.Role;
import com.guams.review.model.dao.Author; import com.guams.review.model.dao.Author;
import com.guams.review.model.dao.Post; import com.guams.review.model.dao.Post;
import com.guams.review.service.mapper.Mapper; import com.guams.review.service.mapper.Mapper;
@ -60,7 +61,7 @@ public class AuthorService implements UserDetailsService
Author author = findById(id).orElseThrow(() -> new NotFoundException("Author not found")); Author author = findById(id).orElseThrow(() -> new NotFoundException("Author not found"));
String username = authentication.getName(); String username = authentication.getName();
Author authorAuthenticated = authorRepository.findByName(username).orElseThrow(() -> new NotFoundException("Author not found")); Author authorAuthenticated = authorRepository.findByName(username).orElseThrow(() -> new NotFoundException("Author not found"));
if (authorAuthenticated.getId().compareTo(author.getId()) != 0 && !authorAuthenticated.getRole().equals("ADMIN")) { if (authorAuthenticated.getId().compareTo(author.getId()) != 0 && !authorAuthenticated.getRole().equals(Role.ADMIN.toString())) {
throw new UnauthorizedExecption("Specified Author is not authorized to do that"); throw new UnauthorizedExecption("Specified Author is not authorized to do that");
} }
return author; return author;