feat: Extension des événements avec 10 nouveaux champs - Ajout de maxParticipants, tags, organizer, participationFee - Ajout de privacyRules, transportInfo, accommodationInfo - Ajout de accessibilityInfo, parkingInfo, securityProtocol - Mise à jour des DTOs et services - Vérification des permissions pour le CRUD (créateur uniquement) - Ajout de creatorId dans EventCreateResponseDTO

This commit is contained in:
dahoud
2026-01-13 20:45:18 +00:00
parent 56d0aad6a6
commit 0443bd251f
5 changed files with 282 additions and 34 deletions

View File

@@ -33,6 +33,17 @@ public class EventCreateRequestDTO {
private String link; // Lien d'information supplémentaire private String link; // Lien d'information supplémentaire
private String imageUrl; // URL de l'image associée à l'événement private String imageUrl; // URL de l'image associée à l'événement
private Integer maxParticipants; // Nombre maximum de participants autorisés
private String tags; // Tags/mots-clés associés à l'événement (séparés par des virgules)
private String organizer; // Nom de l'organisateur de l'événement
private Integer participationFee; // Frais de participation en centimes
private String privacyRules; // Règles de confidentialité de l'événement
private String transportInfo; // Informations sur les transports disponibles
private String accommodationInfo; // Informations sur l'hébergement
private String accessibilityInfo; // Informations sur l'accessibilité
private String parkingInfo; // Informations sur le parking
private String securityProtocol; // Protocole de sécurité de l'événement
@NotNull(message = "L'identifiant du créateur est obligatoire.") @NotNull(message = "L'identifiant du créateur est obligatoire.")
private UUID creatorId; // Identifiant du créateur de l'événement private UUID creatorId; // Identifiant du créateur de l'événement

View File

@@ -20,6 +20,7 @@ public class EventCreateResponseDTO {
private String category; // Catégorie de l'événement private String category; // Catégorie de l'événement
private String link; // Lien vers plus d'informations private String link; // Lien vers plus d'informations
private String imageUrl; // URL d'une image pour l'événement private String imageUrl; // URL d'une image pour l'événement
private String creatorId; // ID du créateur de l'événement
private String creatorEmail; // Email du créateur de l'événement private String creatorEmail; // Email du créateur de l'événement
private String creatorFirstName; // Prénom du créateur de l'événement private String creatorFirstName; // Prénom du créateur de l'événement
private String creatorLastName; // Nom de famille du création de l'événement private String creatorLastName; // Nom de famille du création de l'événement
@@ -40,6 +41,7 @@ public class EventCreateResponseDTO {
this.category = event.getCategory(); this.category = event.getCategory();
this.link = event.getLink(); this.link = event.getLink();
this.imageUrl = event.getImageUrl(); this.imageUrl = event.getImageUrl();
this.creatorId = event.getCreator().getId().toString();
this.creatorEmail = event.getCreator().getEmail(); this.creatorEmail = event.getCreator().getEmail();
this.creatorFirstName = event.getCreator().getPrenoms(); this.creatorFirstName = event.getCreator().getPrenoms();
this.creatorLastName = event.getCreator().getNom(); this.creatorLastName = event.getCreator().getNom();

View File

@@ -55,6 +55,36 @@ public class Events extends BaseEntity {
@Column(name = "status", nullable = false) @Column(name = "status", nullable = false)
private String status = "ouvert"; // Le statut de l'événement (en cours, terminé, annulé, etc.) private String status = "ouvert"; // Le statut de l'événement (en cours, terminé, annulé, etc.)
@Column(name = "max_participants")
private Integer maxParticipants; // Nombre maximum de participants autorisés
@Column(name = "tags", length = 500)
private String tags; // Tags/mots-clés associés à l'événement (séparés par des virgules)
@Column(name = "organizer", length = 200)
private String organizer; // Nom de l'organisateur de l'événement
@Column(name = "participation_fee")
private Integer participationFee; // Frais de participation en centimes
@Column(name = "privacy_rules", length = 1000)
private String privacyRules; // Règles de confidentialité de l'événement
@Column(name = "transport_info", length = 1000)
private String transportInfo; // Informations sur les transports disponibles
@Column(name = "accommodation_info", length = 1000)
private String accommodationInfo; // Informations sur l'hébergement
@Column(name = "accessibility_info", length = 1000)
private String accessibilityInfo; // Informations sur l'accessibilité
@Column(name = "parking_info", length = 1000)
private String parkingInfo; // Informations sur le parking
@Column(name = "security_protocol", length = 1000)
private String securityProtocol; // Protocole de sécurité de l'événement
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "creator_id", nullable = false) @JoinColumn(name = "creator_id", nullable = false)
private Users creator; // L'utilisateur créateur de l'événement private Users creator; // L'utilisateur créateur de l'événement

View File

@@ -66,11 +66,25 @@ public class EventsResource {
@Operation(summary = "Créer un nouvel événement", description = "Crée un nouvel événement et retourne ses détails") @Operation(summary = "Créer un nouvel événement", description = "Crée un nouvel événement et retourne ses détails")
public Response createEvent(EventCreateRequestDTO eventCreateRequestDTO) { public Response createEvent(EventCreateRequestDTO eventCreateRequestDTO) {
LOG.info("[LOG] Tentative de création d'un nouvel événement : " + eventCreateRequestDTO.getTitle()); LOG.info("[LOG] Tentative de création d'un nouvel événement : " + eventCreateRequestDTO.getTitle());
// Valider que creatorId est fourni
if (eventCreateRequestDTO.getCreatorId() == null) {
LOG.error("[ERROR] creatorId est obligatoire pour créer un événement");
return Response.status(Response.Status.BAD_REQUEST)
.entity("L'identifiant du créateur (creatorId) est obligatoire")
.build();
}
// Récupérer le créateur par son ID
Users creator = usersRepository.findById(eventCreateRequestDTO.getCreatorId()); Users creator = usersRepository.findById(eventCreateRequestDTO.getCreatorId());
if (creator == null) { if (creator == null) {
LOG.error("[ERROR] Créateur non trouvé avec l'ID : " + eventCreateRequestDTO.getCreatorId()); LOG.error("[ERROR] Créateur non trouvé avec l'ID : " + eventCreateRequestDTO.getCreatorId());
return Response.status(Response.Status.BAD_REQUEST).entity("Créateur non trouvé").build(); return Response.status(Response.Status.BAD_REQUEST)
.entity("Créateur non trouvé avec l'ID fourni")
.build();
} }
// Créer l'événement
Events event = eventService.createEvent(eventCreateRequestDTO, creator); Events event = eventService.createEvent(eventCreateRequestDTO, creator);
LOG.info("[LOG] Événement créé avec succès : " + event.getTitle()); LOG.info("[LOG] Événement créé avec succès : " + event.getTitle());
EventCreateResponseDTO responseDTO = new EventCreateResponseDTO(event); EventCreateResponseDTO responseDTO = new EventCreateResponseDTO(event);
@@ -100,10 +114,16 @@ public class EventsResource {
@Path("/{id}") @Path("/{id}")
@Transactional @Transactional
@Operation(summary = "Supprimer un événement", description = "Supprime un événement de la base de données") @Operation(summary = "Supprimer un événement", description = "Supprime un événement de la base de données")
public Response deleteEvent(@PathParam("id") UUID id) { public Response deleteEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId) {
LOG.info("Tentative de suppression de l'événement avec l'ID : " + id); LOG.info("Tentative de suppression de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
if (userId == null) {
LOG.error("[ERROR] userId est obligatoire pour supprimer un événement");
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
}
try { try {
boolean deleted = eventService.deleteEvent(id); boolean deleted = eventService.deleteEvent(id, userId);
if (deleted) { if (deleted) {
LOG.info("Événement supprimé avec succès."); LOG.info("Événement supprimé avec succès.");
return Response.noContent().build(); return Response.noContent().build();
@@ -114,6 +134,9 @@ public class EventsResource {
} catch (EventNotFoundException e) { } catch (EventNotFoundException e) {
LOG.error("[ERROR] Échec de la suppression : " + e.getMessage()); LOG.error("[ERROR] Échec de la suppression : " + e.getMessage());
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build(); return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
} catch (SecurityException e) {
LOG.error("[ERROR] Permissions insuffisantes : " + e.getMessage());
return Response.status(Response.Status.FORBIDDEN).entity(e.getMessage()).build();
} }
} }
@@ -166,13 +189,26 @@ public class EventsResource {
@Path("/{id}") @Path("/{id}")
@Transactional @Transactional
@Operation(summary = "Mettre à jour un événement", description = "Modifie un événement existant") @Operation(summary = "Mettre à jour un événement", description = "Modifie un événement existant")
public Response updateEvent(@PathParam("id") UUID id, EventUpdateRequestDTO eventUpdateRequestDTO) { public Response updateEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId, EventUpdateRequestDTO eventUpdateRequestDTO) {
LOG.info("[LOG] Tentative de mise à jour de l'événement avec l'ID : " + id); LOG.info("[LOG] Tentative de mise à jour de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
if (userId == null) {
LOG.error("[ERROR] userId est obligatoire pour mettre à jour un événement");
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
}
Events event = eventsRepository.findById(id); Events event = eventsRepository.findById(id);
if (event == null) { if (event == null) {
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id); LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build(); return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
} }
// Vérifier que l'utilisateur est le créateur
if (!eventService.canModifyEvent(event, userId)) {
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier l'événement " + id);
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
}
// Mise à jour des attributs de l'événement // Mise à jour des attributs de l'événement
event.setTitle(eventUpdateRequestDTO.getTitle()); event.setTitle(eventUpdateRequestDTO.getTitle());
event.setStartDate(eventUpdateRequestDTO.getStartDate()); event.setStartDate(eventUpdateRequestDTO.getStartDate());
@@ -206,18 +242,20 @@ public class EventsResource {
try { try {
List<FriendshipReadFriendDetailsResponseDTO> friends = friendshipService.listFriends(userId, 0, Integer.MAX_VALUE); List<FriendshipReadFriendDetailsResponseDTO> friends = friendshipService.listFriends(userId, 0, Integer.MAX_VALUE);
Set<UUID> friendIds = friends.stream().map(FriendshipReadFriendDetailsResponseDTO::getFriendId).collect(Collectors.toSet()); Set<UUID> friendIds = friends.stream().map(FriendshipReadFriendDetailsResponseDTO::getFriendId).collect(Collectors.toSet());
//friendIds = friendIds.stream().distinct().collect(Collectors.toSet());
LOG.info("[LOG] IDs d'amis + utilisateur (taille attendue: " + friendIds.size() + ") : " + friendIds); // IMPORTANT: Ajouter l'ID de l'utilisateur lui-même pour inclure ses propres événements
if (friendIds.isEmpty()) { friendIds.add(userId);
LOG.warn("[LOG] Aucun ami trouvé.");
return Response.status(Response.Status.NOT_FOUND).entity("Aucun ami trouvé.").build(); LOG.info("[LOG] IDs d'amis + utilisateur (taille: " + friendIds.size() + ") : " + friendIds);
}
// Rechercher les événements créés par l'utilisateur et ses amis
List<Events> events = eventsRepository.find("creator.id IN ?1", friendIds).list(); List<Events> events = eventsRepository.find("creator.id IN ?1", friendIds).list();
LOG.info("[LOG] Nombre d'événements récupérés dans la requête : " + events.size()); LOG.info("[LOG] Nombre d'événements récupérés dans la requête : " + events.size());
if (events.isEmpty()) {
return Response.status(Response.Status.NOT_FOUND).entity("Aucun événement trouvé.").build(); // Retourner une liste vide si aucun événement trouvé (pas d'erreur 404)
} List<EventReadManyByIdResponseDTO> responseDTOs = events.stream()
List<EventReadManyByIdResponseDTO> responseDTOs = events.stream().map(EventReadManyByIdResponseDTO::new).toList(); .map(EventReadManyByIdResponseDTO::new)
.toList();
return Response.ok(responseDTOs).build(); return Response.ok(responseDTOs).build();
} catch (Exception e) { } catch (Exception e) {
LOG.error("[ERROR] Erreur de récupération des événements : ", e); LOG.error("[ERROR] Erreur de récupération des événements : ", e);
@@ -366,13 +404,26 @@ public class EventsResource {
@Operation( @Operation(
summary = "Mettre à jour le statut d'un événement", summary = "Mettre à jour le statut d'un événement",
description = "Modifie le statut d'un événement (ouvert, fermé, annulé, etc.)") description = "Modifie le statut d'un événement (ouvert, fermé, annulé, etc.)")
public Response updateEventStatus(@PathParam("id") UUID id, @QueryParam("status") String status) { public Response updateEventStatus(@PathParam("id") UUID id, @QueryParam("status") String status, @QueryParam("userId") UUID userId) {
LOG.info("[LOG] Mise à jour du statut de l'événement avec l'ID : " + id); LOG.info("[LOG] Mise à jour du statut de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
if (userId == null) {
LOG.error("[ERROR] userId est obligatoire pour mettre à jour le statut d'un événement");
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
}
Events event = eventsRepository.findById(id); Events event = eventsRepository.findById(id);
if (event == null) { if (event == null) {
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id); LOG.warn("[LOG] Événement non trouvé avec l'ID : " + id);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build(); return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
} }
// Vérifier que l'utilisateur est le créateur
if (!eventService.canModifyEvent(event, userId)) {
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier le statut de l'événement " + id);
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
}
event.setStatus(status); event.setStatus(status);
eventsRepository.persist(event); eventsRepository.persist(event);
LOG.info("[LOG] Statut de l'événement mis à jour avec succès : " + status); LOG.info("[LOG] Statut de l'événement mis à jour avec succès : " + status);
@@ -423,8 +474,13 @@ public class EventsResource {
*/ */
@PUT @PUT
@Path("/{id}/image") @Path("/{id}/image")
public Response updateEventImage(@PathParam("id") UUID id, String imageFilePath) { public Response updateEventImage(@PathParam("id") UUID id, @QueryParam("userId") UUID userId, String imageFilePath) {
LOG.info("[LOG] Tentative de mise à jour de l'image pour l'événement avec l'ID : " + id); LOG.info("[LOG] Tentative de mise à jour de l'image pour l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
if (userId == null) {
LOG.error("[ERROR] userId est obligatoire pour mettre à jour l'image d'un événement");
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
}
try { try {
if (imageFilePath == null || imageFilePath.isEmpty()) { if (imageFilePath == null || imageFilePath.isEmpty()) {
@@ -444,9 +500,15 @@ public class EventsResource {
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build(); return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
} }
// Vérifier que l'utilisateur est le créateur
if (!eventService.canModifyEvent(event, userId)) {
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier l'image de l'événement " + id);
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
}
String imageUrl = file.getAbsolutePath(); String imageUrl = file.getAbsolutePath();
event.setImageUrl(imageUrl); event.setImageUrl(imageUrl);
eventService.updateEvent(event); eventService.updateEvent(event, userId);
LOG.info("[LOG] Image de l'événement mise à jour avec succès pour : " + event.getTitle()); LOG.info("[LOG] Image de l'événement mise à jour avec succès pour : " + event.getTitle());
return Response.ok("Image de l'événement mise à jour avec succès.").build(); return Response.ok("Image de l'événement mise à jour avec succès.").build();
@@ -461,8 +523,13 @@ public class EventsResource {
@Path("/{id}/partial-update") @Path("/{id}/partial-update")
@Transactional @Transactional
@Operation(summary = "Mettre à jour partiellement un événement", description = "Mise à jour partielle des informations d'un événement") @Operation(summary = "Mettre à jour partiellement un événement", description = "Mise à jour partielle des informations d'un événement")
public Response partialUpdateEvent(@PathParam("id") UUID id, Map<String, Object> updates) { public Response partialUpdateEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId, Map<String, Object> updates) {
LOG.info("[LOG] Tentative de mise à jour partielle de l'événement avec l'ID : " + id); LOG.info("[LOG] Tentative de mise à jour partielle de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
if (userId == null) {
LOG.error("[ERROR] userId est obligatoire pour mettre à jour un événement");
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
}
Events event = eventsRepository.findById(id); Events event = eventsRepository.findById(id);
if (event == null) { if (event == null) {
@@ -470,9 +537,39 @@ public class EventsResource {
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build(); return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
} }
// Vérifier que l'utilisateur est le créateur
if (!eventService.canModifyEvent(event, userId)) {
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour modifier l'événement " + id);
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour modifier cet événement").build();
}
// Mise à jour des champs dynamiquement
updates.forEach((field, value) -> { updates.forEach((field, value) -> {
// Mise à jour des champs dynamiquement, à adapter selon la structure de l'événement switch (field) {
// Exemple d'utilisation de réflexion si applicable case "title":
event.setTitle(value != null ? value.toString() : null);
break;
case "description":
event.setDescription(value != null ? value.toString() : null);
break;
case "location":
event.setLocation(value != null ? value.toString() : null);
break;
case "category":
event.setCategory(value != null ? value.toString() : null);
break;
case "link":
event.setLink(value != null ? value.toString() : null);
break;
case "imageUrl":
event.setImageUrl(value != null ? value.toString() : null);
break;
case "status":
event.setStatus(value != null ? value.toString() : null);
break;
default:
LOG.warn("[LOG] Champ inconnu ignoré lors de la mise à jour partielle : " + field);
}
}); });
eventsRepository.persist(event); eventsRepository.persist(event);
@@ -519,8 +616,13 @@ public class EventsResource {
@Path("/{id}/cancel") @Path("/{id}/cancel")
@Transactional @Transactional
@Operation(summary = "Annuler un événement", description = "Annule un événement sans le supprimer.") @Operation(summary = "Annuler un événement", description = "Annule un événement sans le supprimer.")
public Response cancelEvent(@PathParam("id") UUID id) { public Response cancelEvent(@PathParam("id") UUID id, @QueryParam("userId") UUID userId) {
LOG.info("[LOG] Annulation de l'événement avec l'ID : " + id); LOG.info("[LOG] Annulation de l'événement avec l'ID : " + id + " par l'utilisateur : " + userId);
if (userId == null) {
LOG.error("[ERROR] userId est obligatoire pour annuler un événement");
return Response.status(Response.Status.BAD_REQUEST).entity("L'identifiant de l'utilisateur (userId) est obligatoire").build();
}
Events event = eventsRepository.findById(id); Events event = eventsRepository.findById(id);
if (event == null) { if (event == null) {
@@ -528,6 +630,12 @@ public class EventsResource {
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build(); return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
} }
// Vérifier que l'utilisateur est le créateur
if (!eventService.canModifyEvent(event, userId)) {
LOG.error("[ERROR] L'utilisateur " + userId + " n'a pas les permissions pour annuler l'événement " + id);
return Response.status(Response.Status.FORBIDDEN).entity("Vous n'avez pas les permissions pour annuler cet événement").build();
}
event.setStatus("Annulé"); event.setStatus("Annulé");
eventsRepository.persist(event); eventsRepository.persist(event);
LOG.info("[LOG] Événement annulé avec succès : " + event.getTitle()); LOG.info("[LOG] Événement annulé avec succès : " + event.getTitle());
@@ -716,6 +824,50 @@ public class EventsResource {
return Response.ok(responseDTOs).build(); return Response.ok(responseDTOs).build();
} }
@POST
@Path("/{id}/comments")
@Transactional
@Operation(summary = "Ajouter un commentaire à un événement", description = "Crée un nouveau commentaire pour un événement.")
public Response addComment(
@PathParam("id") UUID eventId,
@QueryParam("userId") UUID userId,
Map<String, String> requestBody) {
LOG.info("[LOG] Ajout d'un commentaire à l'événement ID : " + eventId + " par l'utilisateur ID : " + userId);
Events event = eventsRepository.findById(eventId);
if (event == null) {
LOG.warn("[LOG] Événement non trouvé avec l'ID : " + eventId);
return Response.status(Response.Status.NOT_FOUND).entity("Événement non trouvé.").build();
}
Users user = usersRepository.findById(userId);
if (user == null) {
LOG.warn("[LOG] Utilisateur non trouvé avec l'ID : " + userId);
return Response.status(Response.Status.NOT_FOUND).entity("Utilisateur non trouvé.").build();
}
String text = requestBody.get("text");
if (text == null || text.trim().isEmpty()) {
LOG.warn("[LOG] Le texte du commentaire est vide");
return Response.status(Response.Status.BAD_REQUEST).entity("Le texte du commentaire est requis.").build();
}
try {
Comment comment = new Comment(user, event, text);
// Le commentaire sera automatiquement ajouté à la liste des commentaires de l'événement via la relation JPA
eventsRepository.persist(event);
LOG.info("[LOG] Commentaire ajouté avec succès à l'événement : " + event.getTitle());
CommentResponseDTO responseDTO = new CommentResponseDTO(comment);
return Response.status(Response.Status.CREATED).entity(responseDTO).build();
} catch (Exception e) {
LOG.error("[ERROR] Erreur lors de l'ajout du commentaire : " + e.getMessage(), e);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Erreur lors de l'ajout du commentaire.").build();
}
}
@GET @GET
@Path("/recommendations/{userId}") @Path("/recommendations/{userId}")
@Operation(summary = "Recommander des événements basés sur les intérêts", description = "Retourne une liste d'événements recommandés pour un utilisateur.") @Operation(summary = "Recommander des événements basés sur les intérêts", description = "Retourne une liste d'événements recommandés pour un utilisateur.")

View File

@@ -59,6 +59,16 @@ public class EventService {
event.setCategory(eventCreateRequestDTO.getCategory()); event.setCategory(eventCreateRequestDTO.getCategory());
event.setLink(eventCreateRequestDTO.getLink()); event.setLink(eventCreateRequestDTO.getLink());
event.setImageUrl(eventCreateRequestDTO.getImageUrl()); event.setImageUrl(eventCreateRequestDTO.getImageUrl());
event.setMaxParticipants(eventCreateRequestDTO.getMaxParticipants());
event.setTags(eventCreateRequestDTO.getTags());
event.setOrganizer(eventCreateRequestDTO.getOrganizer());
event.setParticipationFee(eventCreateRequestDTO.getParticipationFee());
event.setPrivacyRules(eventCreateRequestDTO.getPrivacyRules());
event.setTransportInfo(eventCreateRequestDTO.getTransportInfo());
event.setAccommodationInfo(eventCreateRequestDTO.getAccommodationInfo());
event.setAccessibilityInfo(eventCreateRequestDTO.getAccessibilityInfo());
event.setParkingInfo(eventCreateRequestDTO.getParkingInfo());
event.setSecurityProtocol(eventCreateRequestDTO.getSecurityProtocol());
event.setCreator(creator); event.setCreator(creator);
event.setStatus("ouvert"); event.setStatus("ouvert");
@@ -132,33 +142,60 @@ public class EventService {
* Supprime un événement par son ID. * Supprime un événement par son ID.
* *
* @param id L'ID de l'événement à supprimer. * @param id L'ID de l'événement à supprimer.
* @param userId L'ID de l'utilisateur qui tente de supprimer l'événement.
* @return true si l'événement a été supprimé, false sinon. * @return true si l'événement a été supprimé, false sinon.
* @throws EventNotFoundException Si l'événement n'est pas trouvé. * @throws EventNotFoundException Si l'événement n'est pas trouvé.
* @throws SecurityException Si l'utilisateur n'est pas le créateur de l'événement.
*/ */
@Transactional @Transactional
public boolean deleteEvent(UUID id) { public boolean deleteEvent(UUID id, UUID userId) {
logger.info("[logger] Tentative de suppression de l'événement avec l'ID : {}", id); logger.info("[logger] Tentative de suppression de l'événement avec l'ID : {} par l'utilisateur : {}", id, userId);
Events event = eventsRepository.findById(id);
if (event == null) {
logger.warn("[logger] Échec de la suppression : événement avec l'ID {} introuvable.", id);
throw new EventNotFoundException(id);
}
// Vérifier que l'utilisateur est le créateur
if (!canModifyEvent(event, userId)) {
logger.error("[ERROR] L'utilisateur {} n'a pas les permissions pour supprimer l'événement {}", userId, id);
throw new SecurityException("Vous n'avez pas les permissions pour supprimer cet événement");
}
boolean deleted = eventsRepository.deleteById(id); boolean deleted = eventsRepository.deleteById(id);
if (deleted) { if (deleted) {
logger.info("[logger] Événement avec l'ID {} supprimé avec succès.", id); logger.info("[logger] Événement avec l'ID {} supprimé avec succès.", id);
} else {
logger.warn("[logger] Échec de la suppression : événement avec l'ID {} introuvable.", id);
throw new EventNotFoundException(id);
} }
return deleted; return deleted;
} }
/**
* Vérifie si un utilisateur peut modifier un événement.
*
* @param event L'événement à vérifier.
* @param userId L'ID de l'utilisateur.
* @return true si l'utilisateur peut modifier l'événement, false sinon.
*/
public boolean canModifyEvent(Events event, UUID userId) {
if (event == null || event.getCreator() == null) {
return false;
}
return event.getCreator().getId().equals(userId);
}
/** /**
* Met à jour un événement dans le système. * Met à jour un événement dans le système.
* *
* @param event L'événement contenant les détails mis à jour. * @param event L'événement contenant les détails mis à jour.
* @param userId L'ID de l'utilisateur qui tente de mettre à jour l'événement.
* @return L'événement mis à jour. * @return L'événement mis à jour.
* @throws EventNotFoundException Si l'événement n'est pas trouvé. * @throws EventNotFoundException Si l'événement n'est pas trouvé.
* @throws SecurityException Si l'utilisateur n'est pas le créateur de l'événement.
*/ */
@Transactional @Transactional
public Events updateEvent(Events event) { public Events updateEvent(Events event, UUID userId) {
logger.info("[logger] Tentative de mise à jour de l'événement avec l'ID : {}", event.getId()); logger.info("[logger] Tentative de mise à jour de l'événement avec l'ID : {} par l'utilisateur : {}", event.getId(), userId);
Events existingEvent = eventsRepository.findById(event.getId()); Events existingEvent = eventsRepository.findById(event.getId());
if (existingEvent == null) { if (existingEvent == null) {
@@ -166,6 +203,12 @@ public class EventService {
throw new EventNotFoundException(event.getId()); throw new EventNotFoundException(event.getId());
} }
// Vérifier que l'utilisateur est le créateur
if (!canModifyEvent(existingEvent, userId)) {
logger.error("[ERROR] L'utilisateur {} n'a pas les permissions pour modifier l'événement {}", userId, event.getId());
throw new SecurityException("Vous n'avez pas les permissions pour modifier cet événement");
}
// Mettre à jour les détails de l'événement // Mettre à jour les détails de l'événement
existingEvent.setTitle(event.getTitle()); existingEvent.setTitle(event.getTitle());
existingEvent.setDescription(event.getDescription()); existingEvent.setDescription(event.getDescription());
@@ -175,6 +218,16 @@ public class EventService {
existingEvent.setCategory(event.getCategory()); existingEvent.setCategory(event.getCategory());
existingEvent.setLink(event.getLink()); existingEvent.setLink(event.getLink());
existingEvent.setImageUrl(event.getImageUrl()); existingEvent.setImageUrl(event.getImageUrl());
existingEvent.setMaxParticipants(event.getMaxParticipants());
existingEvent.setTags(event.getTags());
existingEvent.setOrganizer(event.getOrganizer());
existingEvent.setParticipationFee(event.getParticipationFee());
existingEvent.setPrivacyRules(event.getPrivacyRules());
existingEvent.setTransportInfo(event.getTransportInfo());
existingEvent.setAccommodationInfo(event.getAccommodationInfo());
existingEvent.setAccessibilityInfo(event.getAccessibilityInfo());
existingEvent.setParkingInfo(event.getParkingInfo());
existingEvent.setSecurityProtocol(event.getSecurityProtocol());
existingEvent.setStatus(event.getStatus()); existingEvent.setStatus(event.getStatus());
// Persiste les modifications dans la base de données // Persiste les modifications dans la base de données