diff --git a/packetserver/http/routers/objects.py b/packetserver/http/routers/objects.py index eb3398a..ac64eb8 100644 --- a/packetserver/http/routers/objects.py +++ b/packetserver/http/routers/objects.py @@ -548,4 +548,50 @@ async def download_object( iter([content_bytes]), # single chunk since ZODB objects are usually small-ish media_type=content_type, headers=headers + ) + +@router.get("/objects/{uuid}", response_model=ObjectSummary) +async def get_object_metadata( + uuid: UUID, + db: DbDependency, + current_user: HttpUser = Depends(get_current_http_user) +): + username = current_user.username + + try: + with db.transaction() as conn: + root = conn.root() + + obj = Object.get_object_by_uuid(uuid, root) + if not obj: + raise HTTPException(status_code=404, detail="Object not found") + + # Authorization: private objects only visible to owner + if obj.private: + user = User.get_user_by_username(username, root) + if not user or user.uuid != obj.owner: + raise HTTPException(status_code=403, detail="Not authorized to view this private object") + + # Guess content_type for summary + content_type, _ = mimetypes.guess_type(obj.name) + if content_type is None: + content_type = "application/octet-stream" if obj.binary else "text/plain" + + logging.info(f"User {username} retrieved metadata for object {uuid} ({obj.name})") + + except HTTPException: + raise + except Exception as e: + logging.error(f"Metadata retrieval failed for {username} on {uuid}: {e}\n{traceback.format_exc()}") + raise HTTPException(status_code=500, detail="Failed to retrieve object metadata") + + return ObjectSummary( + uuid=obj.uuid, + name=obj.name, + binary=obj.binary, + size=obj.size, + content_type=content_type, + private=obj.private, + created_at=obj.created_at, + modified_at=obj.modified_at ) \ No newline at end of file