comment delete et limite de 5 requete post toute les minutes
This commit is contained in:
parent
f41c830970
commit
40da59bd31
@ -1,4 +1,5 @@
|
||||
package com.guams.review.configuration;
|
||||
|
||||
import com.guams.review.service.AuthorService;
|
||||
import io.jsonwebtoken.JwtException;
|
||||
import jakarta.servlet.FilterChain;
|
||||
@ -11,7 +12,11 @@ import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Component
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
@ -19,6 +24,13 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
private final JwtTokenUtil jwtTokenUtil;
|
||||
private final AuthorService authorService;
|
||||
|
||||
// Map pour traquer les requêtes : UUID -> { dernière réinitialisation, compteur de requêtes }
|
||||
private final ConcurrentHashMap<String, RateLimiter> rateLimiters = new ConcurrentHashMap<>();
|
||||
|
||||
// Configuration du rate limiting
|
||||
private static final int MAX_REQUESTS = 5;
|
||||
private static final long TIME_WINDOW_MS = 60 * 1000; // 1 minute
|
||||
|
||||
public JwtAuthenticationFilter(JwtTokenUtil jwtTokenUtil, AuthorService authorService) {
|
||||
this.jwtTokenUtil = jwtTokenUtil;
|
||||
this.authorService = authorService;
|
||||
@ -35,9 +47,16 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
String authorUuid = jwtTokenUtil.extractAuthorId(token); // Récupère l'UUID du token
|
||||
|
||||
if (authorUuid != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
UserDetails userDetails = authorService.loadUserByUsername(authorUuid); // Utilise le service pour charger l'auteur par UUID
|
||||
UserDetails userDetails = authorService.loadUserByUsername(authorUuid); // Charge l'auteur
|
||||
|
||||
if (jwtTokenUtil.validateToken(token, userDetails, authorUuid)) {
|
||||
// Applique le rate limiting
|
||||
if (isRateLimited(authorUuid, request)) {
|
||||
response.setStatus(429); // TOO MANY REQUESTS
|
||||
response.getWriter().write("Rate limit exceeded. Please try again later.");
|
||||
return;
|
||||
}
|
||||
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
@ -50,7 +69,42 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
filterChain.doFilter(request, response); // Continue le traitement
|
||||
}
|
||||
|
||||
private boolean isRateLimited(String authorUuid, HttpServletRequest request) {
|
||||
// Ne limite que les requêtes POST
|
||||
if (!"POST".equalsIgnoreCase(request.getMethod())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Récupère ou crée un RateLimiter pour l'utilisateur
|
||||
RateLimiter limiter = rateLimiters.computeIfAbsent(authorUuid, k -> new RateLimiter());
|
||||
|
||||
synchronized (limiter) {
|
||||
long now = Instant.now().toEpochMilli();
|
||||
if (now - limiter.lastReset > TIME_WINDOW_MS) {
|
||||
// Réinitialise la fenêtre de temps et le compteur
|
||||
limiter.lastReset = now;
|
||||
limiter.requestCount.set(0);
|
||||
}
|
||||
|
||||
if (limiter.requestCount.incrementAndGet() > MAX_REQUESTS) {
|
||||
return true; // Limite atteinte
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Classe interne pour suivre les requêtes
|
||||
private static class RateLimiter {
|
||||
private long lastReset;
|
||||
private AtomicInteger requestCount;
|
||||
|
||||
public RateLimiter() {
|
||||
this.lastReset = Instant.now().toEpochMilli();
|
||||
this.requestCount = new AtomicInteger(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,12 @@ public class AuthorController {
|
||||
}
|
||||
}
|
||||
|
||||
// @PutMapping("/{id}/password")
|
||||
// public void changePassword(@PathVariable UUID id, @RequestBody Author updatedAuthor, Authentication authentication) {
|
||||
// Author authorToUpdate = authorService.verifyIfUserIsAuthorized(authentication, id);
|
||||
// if (passwordEncoder.matches(updatedAuthor.getPassword(), authorToUpdate.getPassword())) {}
|
||||
// }
|
||||
|
||||
@PutMapping(value = "{id}/avatar", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
|
||||
public Author updateUserAvatar(@PathVariable UUID id, @RequestPart MultipartFile avatar, Authentication authentication) throws IOException {
|
||||
Author authorToUpdate = authorService.verifyIfUserIsAuthorized(authentication, id);
|
||||
|
@ -85,7 +85,7 @@ public class CommentController {
|
||||
throw new UnauthorizedExecption("You are not authorized to access this resource");
|
||||
}
|
||||
Comment commentToDelete = commentService.findById(id).orElseThrow(() -> new NotFoundException("Comment not found"));
|
||||
commentService.delete(commentToDelete);
|
||||
commentService.deleteAssociationByCommentId(commentToDelete.getId());
|
||||
commentService.delete(commentToDelete);
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,14 @@ public class PostController {
|
||||
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"));
|
||||
commentService.getCommentsByPostId(id).stream().map(mapper::mapCommentWithAuthor).forEach(commentService::delete);
|
||||
commentService.getCommentsByPostId(id)
|
||||
.stream()
|
||||
.map(mapper::mapCommentWithAuthor)
|
||||
.forEach(comment -> commentService.deleteAssociationByCommentId(comment.getId()));
|
||||
commentService.getCommentsByPostId(id)
|
||||
.stream()
|
||||
.map(mapper::mapCommentWithAuthor)
|
||||
.forEach(commentService::delete);
|
||||
postService.delete(authenticatedAuthor.getId(), postToDelete.getId());
|
||||
} else {
|
||||
throw new UnauthorizedExecption("You do not have permission to delete this post");
|
||||
|
Loading…
Reference in New Issue
Block a user