134 lines
3.5 KiB
Python
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
|