fix(security): remediate telecom compliance findings

This commit is contained in:
2026-07-28 11:33:05 +08:00
parent c38a9e74ad
commit 29e4e4a804
17 changed files with 293 additions and 72 deletions
+14
View File
@@ -12,11 +12,21 @@ from app.models.user import User
from app.schemas.visit import VisitCreate, VisitUpdate, VisitOut, VisitListOut
from app.utils.timezone import today_cst, parse_date
from app.services.minio_client import delete_objects
from app.api.upload import is_owned_upload_key
from app.utils.edit_log import compute_diff, append_entry, init_entry
router = APIRouter(prefix="/visits", tags=["Visits"])
def _validate_photo_keys(photo_keys: list[str], user_id: str, existing_keys: list[str] | None = None) -> None:
if len(photo_keys) > 9:
raise HTTPException(status_code=400, detail="A visit may contain at most 9 photos")
existing = set(existing_keys or [])
for key in photo_keys:
if key not in existing and not is_owned_upload_key(key, user_id):
raise HTTPException(status_code=400, detail="Invalid or unauthorized photo reference")
async def _enrich_visit(visit: Visit, db: AsyncSession) -> dict:
"""Enrich a visit record with customer/manager names."""
customer_name = None
@@ -137,6 +147,7 @@ async def create_visit(
db: AsyncSession = Depends(get_db),
):
"""Create a visit record. If companions are selected, creates draft copies for them."""
_validate_photo_keys(data.photos, current_user["user_id"])
visit = Visit(
customer_id=data.customer_id,
visit_date=parse_date(data.visit_date),
@@ -209,6 +220,9 @@ async def update_visit(
if current_user["role"] == "manager" and str(visit.manager_id) != current_user["user_id"]:
raise HTTPException(status_code=403, detail="Access denied")
if data.photos is not None:
_validate_photo_keys(data.photos, current_user["user_id"], visit.photos or [])
# Snapshot old values for diff
old_snapshot = {
"customer_id": str(visit.customer_id), "visit_date": str(visit.visit_date),