feat(anhaenge): Endpunkte zum Hochladen, Abrufen und Loeschen
Neuer Router unter /api/local mit Upload, Liste, Download, Thumbnail und Loeschen, dazu permissions.readable_local_event als fehlendes Gegenstueck zu _writable_event. Der Lese-Helfer prueft nicht nur den Kalender, sondern auch die Privatsphaere: ein fremder privater Termin wird im Lesepfad maskiert, also duerfen auch seine Anhaenge nicht ueber die UID erreichbar sein. Fremde bekommen durchgaengig 404 statt 403, damit die Existenz nicht durchsickert. Die Mengenbegrenzung zaehlt nach dem Insert innerhalb derselben Transaktion -- zaehlen-dann-einfuegen waere ein Wettlauf, bei dem zwei gleichzeitige Uploads beide 9 sehen. Ausgeliefert wird immer als Download mit nosniff, nie inline. Dazu die Capability-URL unter /api/attach/<token> fuer externe CalDAV-Clients, abschaltbar ueber ATTACHMENT_PUBLIC_LINKS=0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
22a469d449
commit
0e8a1a6a3d
@@ -82,6 +82,28 @@ def accessible_local_calendar(
|
||||
return cal
|
||||
|
||||
|
||||
def readable_local_event(db: Session, user: models.User, uid: str) -> models.LocalEvent:
|
||||
"""Return the event if the user may READ it, else raise 404.
|
||||
|
||||
The read-side mirror of local_router._writable_event. Beyond the calendar
|
||||
check it enforces the private-event rule: the merge read hides or busy-masks
|
||||
another user's private events, so anything hanging off such an event must
|
||||
not be reachable by uid either — otherwise a share recipient could read the
|
||||
attachments of events whose very title is deliberately withheld from them.
|
||||
|
||||
Always 404, never 403: a user who may not see the event may not learn that
|
||||
it exists.
|
||||
"""
|
||||
ev = db.query(models.LocalEvent).filter(models.LocalEvent.uid == uid).first()
|
||||
if not ev:
|
||||
raise HTTPException(404, "Event not found")
|
||||
cal = accessible_local_calendar(db, user, ev.calendar_id)
|
||||
owner_id = ev.creator_id or cal.user_id
|
||||
if ev.is_private and owner_id != user.id:
|
||||
raise HTTPException(404, "Event not found")
|
||||
return ev
|
||||
|
||||
|
||||
def is_calendar_owner(db: Session, user: models.User, calendar_id: int) -> models.LocalCalendar:
|
||||
"""Return the calendar only if the user owns it, else raise 404."""
|
||||
cal = (
|
||||
|
||||
Reference in New Issue
Block a user