From 63c2bc3b709778f0c43906400d7ffb0b593a226f Mon Sep 17 00:00:00 2001 From: Peter Vacho Date: Sun, 29 Dec 2024 14:57:45 +0100 Subject: [PATCH] Allow getting events you're attending/invited to --- src/api/events.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/api/events.py b/src/api/events.py index 9f917f9..056258e 100644 --- a/src/api/events.py +++ b/src/api/events.py @@ -1,5 +1,5 @@ from datetime import date, datetime, time -from typing import Annotated, final +from typing import Annotated, cast, final from beanie import DeleteRules, Link, PydanticObjectId from fastapi import APIRouter, Body, HTTPException, Query, status @@ -10,6 +10,7 @@ from pydantic_extra_types.color import Color from src.api.auth.dependencies import LoggedInDep from src.db.models.category import Category from src.db.models.event import Event +from src.db.models.invitation import Invitation from src.db.models.user import User from src.utils.db import MissingIdError, UnfetchedLinkError, expr, from_id_list, get_id_list, update_document from src.utils.logging import get_logger @@ -239,15 +240,25 @@ async def get_user_invited_events( @events_router.get("{event_id}") async def get_event(event_id: PydanticObjectId, user: CurrentUserDep) -> EventData: - """Get an event by ID.""" - event = await Event.get(event_id) + """Get an event by ID. + + You can only access your own events, or the events you're attending, or the events + that you have a pending invite for. + """ + event = await Event.get(event_id, fetch_links=True) if event is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Event with given id doesn't exist") - if event.owner != user: - raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You can only access your own events", + + if cast(User, event.user).id != user.id and user.id not in get_id_list(event.attendees): + # Also check for a pending invite, only do this now, to avoid unnecessary db queries + invite = await Invitation.find_one( + expr(Invitation.invitee).id == user.id, expr(Invitation.event).id == event.id ) + if invite is None or invite.status != "pending": + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="You can only access your own events, or events you're attending", + ) return EventData.from_event(event)