[verified] add upload size and MIME guards
This commit is contained in:
@@ -12,6 +12,7 @@ from modules.auth.supabase_bearer import SupabaseBearer, verify_supabase_jwt_str
|
||||
from modules.logger_tool import initialise_logger
|
||||
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
|
||||
from modules.database.supabase.utils.storage import StorageAdmin
|
||||
from modules.upload_validation import read_upload_bytes
|
||||
from modules.document_processor import DocumentProcessor
|
||||
from modules.queue_system import (
|
||||
enqueue_tika_task, enqueue_docling_task, enqueue_split_map_task,
|
||||
@@ -70,13 +71,13 @@ async def upload_file(
|
||||
# Stage DB row to get file_id
|
||||
staged_path = f"{cabinet_id}/staging/{uuid.uuid4()}"
|
||||
name = _safe_filename(path or file.filename)
|
||||
file_bytes = await file.read()
|
||||
file_bytes, mime_type = await read_upload_bytes(file)
|
||||
insert_res = client.supabase.table('files').insert({
|
||||
'cabinet_id': cabinet_id,
|
||||
'name': name,
|
||||
'path': staged_path,
|
||||
'bucket': bucket,
|
||||
'mime_type': file.content_type,
|
||||
'mime_type': mime_type,
|
||||
'uploaded_by': user_id,
|
||||
'size_bytes': len(file_bytes),
|
||||
'source': 'classroomcopilot-web'
|
||||
@@ -89,7 +90,7 @@ async def upload_file(
|
||||
# Final storage path: bucket/cabinet_id/file_id/file
|
||||
final_storage_path = f"{cabinet_id}/{file_id}/{name}"
|
||||
try:
|
||||
storage.upload_file(bucket, final_storage_path, file_bytes, file.content_type or 'application/octet-stream', upsert=True)
|
||||
storage.upload_file(bucket, final_storage_path, file_bytes, mime_type, upsert=True)
|
||||
except Exception as e:
|
||||
# cleanup staged row
|
||||
client.supabase.table('files').delete().eq('id', file_id).execute()
|
||||
|
||||
@@ -19,6 +19,7 @@ from fastapi.responses import JSONResponse
|
||||
from modules.auth.supabase_bearer import SupabaseBearer
|
||||
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
|
||||
from modules.database.supabase.utils.storage import StorageAdmin
|
||||
from modules.upload_validation import read_upload_bytes
|
||||
from modules.logger_tool import initialise_logger
|
||||
|
||||
router = APIRouter()
|
||||
@@ -54,10 +55,9 @@ async def upload_file(
|
||||
if not user_id:
|
||||
raise HTTPException(status_code=401, detail="User ID required")
|
||||
|
||||
# Read file content
|
||||
file_bytes = await file.read()
|
||||
# Validate MIME/type and read file content with a hard size limit.
|
||||
file_bytes, mime_type = await read_upload_bytes(file)
|
||||
file_size = len(file_bytes)
|
||||
mime_type = file.content_type or 'application/octet-stream'
|
||||
filename = file.filename or path
|
||||
|
||||
logger.info(f"📤 Simplified upload: {filename} ({file_size} bytes) for user {user_id}")
|
||||
|
||||
@@ -28,6 +28,7 @@ from api.services.docling.regions import detect_response_regions_from_pdf
|
||||
from modules.database.services.exam_projection import project_template, project_template_safe
|
||||
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
|
||||
from modules.database.supabase.utils.storage import StorageAdmin
|
||||
from modules.upload_validation import read_pdf_upload_bytes
|
||||
from modules.logger_tool import initialise_logger
|
||||
from routers.exam.dependencies import ExamContext, get_exam_context, lookup_exam_code
|
||||
from routers.exam.schemas import (
|
||||
@@ -164,11 +165,7 @@ async def _upload_template_source_file(
|
||||
institute_id: str,
|
||||
upload: UploadFile,
|
||||
) -> str:
|
||||
file_bytes = await upload.read()
|
||||
if not file_bytes:
|
||||
raise HTTPException(status_code=400, detail="Uploaded PDF is empty")
|
||||
if upload.content_type and upload.content_type != "application/pdf":
|
||||
raise HTTPException(status_code=400, detail="Uploaded file must be a PDF")
|
||||
file_bytes = await read_pdf_upload_bytes(upload)
|
||||
|
||||
service = SupabaseServiceRoleClient()
|
||||
storage = StorageAdmin()
|
||||
|
||||
@@ -26,6 +26,7 @@ from fastapi.responses import JSONResponse
|
||||
from modules.auth.supabase_bearer import SupabaseBearer
|
||||
from modules.database.supabase.utils.client import SupabaseServiceRoleClient
|
||||
from modules.database.supabase.utils.storage import StorageAdmin
|
||||
from modules.upload_validation import read_upload_bytes
|
||||
from modules.logger_tool import initialise_logger
|
||||
|
||||
router = APIRouter()
|
||||
@@ -59,10 +60,9 @@ async def upload_single_file(
|
||||
if not user_id:
|
||||
raise HTTPException(status_code=401, detail="User ID required")
|
||||
|
||||
# Read file content
|
||||
file_bytes = await file.read()
|
||||
# Validate MIME/type and read file content with a hard size limit.
|
||||
file_bytes, mime_type = await read_upload_bytes(file)
|
||||
file_size = len(file_bytes)
|
||||
mime_type = file.content_type or 'application/octet-stream'
|
||||
filename = file.filename or path
|
||||
|
||||
logger.info(f"📤 Simple upload: {filename} ({file_size} bytes) for user {user_id}")
|
||||
@@ -234,10 +234,9 @@ async def upload_directory(
|
||||
# Process each file
|
||||
for i, (file, relative_path) in enumerate(zip(files, relative_paths)):
|
||||
try:
|
||||
# Read file content
|
||||
file_bytes = await file.read()
|
||||
# Validate MIME/type and read file content with a hard size limit.
|
||||
file_bytes, mime_type = await read_upload_bytes(file)
|
||||
file_size = len(file_bytes)
|
||||
mime_type = file.content_type or 'application/octet-stream'
|
||||
filename = file.filename or f"file_{i}"
|
||||
|
||||
total_size += file_size
|
||||
@@ -291,6 +290,8 @@ async def upload_directory(
|
||||
|
||||
logger.info(f"📄 Uploaded file {i+1}/{len(files)}: {relative_path}")
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to upload file {relative_path}: {e}")
|
||||
# Continue with other files, don't fail entire upload
|
||||
|
||||
Reference in New Issue
Block a user