itcloud/backend/src/app/api/v1/shares.py

134 lines
3.5 KiB
Python

"""Share API routes."""
from typing import Optional
from fastapi import APIRouter, Query, status
from app.api.dependencies import CurrentUser, DatabaseSession, S3ClientDep
from app.api.schemas import (
CreateShareRequest,
DownloadUrlResponse,
ShareAccessRequest,
ShareResponse,
ShareWithAssetResponse,
)
from app.infra.config import get_settings
from app.services.share_service import ShareService
router = APIRouter(prefix="/shares", tags=["shares"])
settings = get_settings()
@router.post("", response_model=ShareResponse, status_code=status.HTTP_201_CREATED)
async def create_share(
data: CreateShareRequest,
current_user: CurrentUser,
session: DatabaseSession,
s3_client: S3ClientDep,
):
"""
Create a share link.
Args:
data: Share creation data
current_user: Current authenticated user
session: Database session
s3_client: S3 client
Returns:
Created share information
"""
share_service = ShareService(session, s3_client)
share = await share_service.create_share(
user_id=current_user.id,
asset_id=data.asset_id,
album_id=data.album_id,
expires_in_seconds=data.expires_in_seconds,
password=data.password,
)
return share
@router.get("/{token}", response_model=ShareWithAssetResponse)
async def get_share(
token: str,
session: DatabaseSession,
s3_client: S3ClientDep,
password: Optional[str] = Query(None),
):
"""
Get share information by token with asset details.
Args:
token: Share token
session: Database session
s3_client: S3 client
password: Optional password for protected shares
Returns:
Share information with asset details
"""
share_service = ShareService(session, s3_client)
share, asset = await share_service.get_share_with_asset(token=token, password=password)
return ShareWithAssetResponse(share=share, asset=asset)
@router.get("/{token}/download-url", response_model=DownloadUrlResponse)
async def get_share_download_url(
token: str,
session: DatabaseSession,
s3_client: S3ClientDep,
asset_id: str = Query(...),
kind: str = Query("original", pattern="^(original|thumb)$"),
password: Optional[str] = Query(None),
):
"""
Get download URL for a shared asset.
Args:
token: Share token
session: Database session
s3_client: S3 client
asset_id: Asset ID
kind: 'original' or 'thumb'
password: Optional password
Returns:
Pre-signed download URL
"""
share_service = ShareService(session, s3_client)
url = await share_service.get_share_download_url(
token=token,
asset_id=asset_id,
kind=kind,
password=password,
)
return DownloadUrlResponse(url=url, expires_in=settings.signed_url_ttl_seconds)
@router.post("/{token}/revoke", response_model=ShareResponse)
async def revoke_share(
token: str,
current_user: CurrentUser,
session: DatabaseSession,
s3_client: S3ClientDep,
):
"""
Revoke a share link.
Args:
token: Share token
current_user: Current authenticated user
session: Database session
s3_client: S3 client
Returns:
Updated share
"""
share_service = ShareService(session, s3_client)
# First get the share to find its ID
share = await share_service.get_share(token=token)
# Then revoke it
share = await share_service.revoke_share(user_id=current_user.id, share_id=share.id)
return share