fix: enforce run ownership on all mutation endpoints
Add require_run_owner helper in auth.py that enforces ownership on mutation endpoints. Unowned (legacy) runs are now read-only. Applied ownership checks to: - All 4 encounter mutation endpoints - Both boss result mutation endpoints - Run update/delete endpoints - All 5 genlocke mutation endpoints (via first leg's run owner) Also sets owner_id on run creation in genlockes.py (create_genlocke, advance_leg) and adds 22 comprehensive ownership enforcement tests. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.database import get_session
|
||||
from app.models.nuzlocke_run import NuzlockeRun
|
||||
from app.models.user import User
|
||||
|
||||
|
||||
@@ -105,3 +106,20 @@ async def require_admin(
|
||||
detail="Admin access required",
|
||||
)
|
||||
return user
|
||||
|
||||
|
||||
def require_run_owner(run: NuzlockeRun, user: AuthUser) -> None:
|
||||
"""
|
||||
Verify user owns the run. Raises 403 if not owner.
|
||||
Unowned (legacy) runs are read-only and reject all mutations.
|
||||
"""
|
||||
if run.owner_id is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="This run has no owner and cannot be modified",
|
||||
)
|
||||
if UUID(user.id) != run.owner_id:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Only the run owner can perform this action",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user