From 455b8b1071b50d17cd7c48f97bc78d85656d6e5d Mon Sep 17 00:00:00 2001 From: Alix JEUDI--LEMOINE Date: Mon, 2 Jun 2025 23:21:33 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20POI=20gestion=20for=20pins?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/dto/pin.py | 1 + app/models/pin.py | 15 +++++++-- app/routes/pins.py | 56 ++++++++++++++++++++----------- app/serializers/pin_serializer.py | 3 +- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/app/dto/pin.py b/app/dto/pin.py index c1b2161..0d718b0 100644 --- a/app/dto/pin.py +++ b/app/dto/pin.py @@ -12,6 +12,7 @@ class PinDTO(BaseModel): files: List[str] = Field(default_factory=list) user_id: str = None date: Optional[datetime] = None + is_poi: bool = False @field_validator('files') @classmethod diff --git a/app/models/pin.py b/app/models/pin.py index ce81c71..e288ff5 100644 --- a/app/models/pin.py +++ b/app/models/pin.py @@ -1,5 +1,5 @@ from typing import Optional, List -from pydantic import BaseModel, Field, validator +from pydantic import BaseModel, Field, field_validator from datetime import datetime class Pin(BaseModel): @@ -9,11 +9,20 @@ class Pin(BaseModel): location: list = Field(..., min_items=2) complete_address: str = Field(..., min_length=3) files: Optional[List[str]] = [] # Liste des IDs d'images - user_id: str + is_poi: bool = False + user_id: Optional[str] = None date: Optional[datetime] = None - @validator('location') + @field_validator('location') + @classmethod def validate_location(cls, v): if not v or len(v) == 0: raise ValueError('La location ne peut pas être vide') + return v + + @field_validator('user_id') + @classmethod + def validate_user_id(cls, v, info): + if not info.data.get('is_poi') and not v: + raise ValueError('user_id est requis lorsque is_poi est False') return v \ No newline at end of file diff --git a/app/routes/pins.py b/app/routes/pins.py index 31dec05..e81d197 100644 --- a/app/routes/pins.py +++ b/app/routes/pins.py @@ -64,18 +64,23 @@ async def update_pin(id: str, pin: PinDTO, current_user: User = Depends(get_curr existing_pin = pins_collection.find_one({"_id": ObjectId(id)}) check_pin_is_null(existing_pin) - # Vérifier si l'utilisateur a la permission de modifier le pin - if existing_pin["user_id"] != current_user.uid: - permission = pin_permissions_collection.find_one({ - "pin_id": ObjectId(id), - "user_id": current_user.uid, - "can_edit": True - }) - if not permission: + # Vérifier si le pin est un POI, si oui, il ne être modifié que si l'utilisateur est administrateur + if existing_pin["is_poi"]: + if not current_user.is_admin: raise HTTPException(status_code=403, detail="You don't have permission to edit this pin") - - # Ajouter l'ID de l'utilisateur au PinDTO - pin.user_id = current_user.uid + else: + # Vérifier si l'utilisateur a la permission de modifier le pin + if existing_pin["user_id"] != current_user.uid: + permission = pin_permissions_collection.find_one({ + "pin_id": ObjectId(id), + "user_id": current_user.uid, + "can_edit": True + }) + if not permission: + raise HTTPException(status_code=403, detail="You don't have permission to edit this pin") + + # Ajouter l'ID de l'utilisateur au PinDTO + pin.user_id = current_user.uid # Mettre à jour le pin pins_collection.update_one({"_id": ObjectId(id)}, {"$set": pin.model_dump()}) @@ -97,7 +102,9 @@ async def update_pin(id: str, pin: PinDTO, current_user: User = Depends(get_curr responses={401: {"model": HTTPError}} ) async def add_pin(pin: PinDTO, current_user: User = Depends(get_current_user)): - pin.user_id = current_user.uid + if not pin.is_poi: + pin.user_id = current_user.uid + pin_id = pins_collection.insert_one(pin.model_dump()).inserted_id # Mettre à jour les images avec le pin_id @@ -113,18 +120,21 @@ async def add_pin(pin: PinDTO, current_user: User = Depends(get_current_user)): path="s", responses={401: {"model": HTTPError}} ) -async def list_pins(current_user: User = Depends(get_current_user)): +async def list_pins(current_user: User = Depends(get_current_user), poi: bool = False): # Récupérer les IDs des pins partagés avec l'utilisateur shared_pins = pin_permissions_collection.find({"user_id": current_user.uid}) shared_pin_ids = [permission["pin_id"] for permission in shared_pins] # Récupérer tous les pins de l'utilisateur et les pins partagés avec lui - pins = pins_collection.find({ - "$or": [ - {"user_id": current_user.uid}, # Pins de l'utilisateur - {"_id": {"$in": shared_pin_ids}} # Pins partagés avec l'utilisateur - ] - }) + if poi: + pins = pins_collection.find({"is_poi": True}) + else: + pins = pins_collection.find({ + "$or": [ + {"user_id": current_user.uid}, # Pins de l'utilisateur + {"_id": {"$in": shared_pin_ids}} # Pins partagés avec l'utilisateur + ] + }) return serializers.pins_serialize(pins.to_list()) @@ -189,6 +199,14 @@ async def delete_pin(id: str, current_user: User = Depends(get_current_user)): try: pin = pins_collection.find_one({"_id": ObjectId(id)}) check_pin_is_null(pin) + + # Vérifier si le pin est un POI, si oui, il ne peut être supprimé que si l'utilisateur est administrateur + if pin["is_poi"]: + if not current_user.is_admin: + raise HTTPException(status_code=403, detail="You don't have permission to delete this pin") + else: + pins_collection.delete_one({"_id": ObjectId(id)}) + return {"message": "POI deleted successfully"} # Si l'utilisateur est le propriétaire, supprimer le pin et toutes ses permissions if pin["user_id"] == current_user.uid: diff --git a/app/serializers/pin_serializer.py b/app/serializers/pin_serializer.py index 34e4aed..b6d6066 100644 --- a/app/serializers/pin_serializer.py +++ b/app/serializers/pin_serializer.py @@ -10,7 +10,8 @@ def pin_serialize(pin: list) -> Pin: "complete_address": pin["complete_address"], "files": pin["files"], "user_id": pin["user_id"], - "date": pin.get("date") + "date": pin.get("date"), + "is_poi": pin.get("is_poi", False) }) def pins_serialize(pins: list) -> list: