111 lines
3.1 KiB
Markdown
111 lines
3.1 KiB
Markdown
# Shot Access 403 Error Fix
|
|
|
|
## Problem
|
|
Admin users were getting 403 Forbidden errors when trying to access shot details, even though they should have access to all shots.
|
|
|
|
## Root Cause
|
|
The `check_episode_access()` function in `backend/routers/shots.py` was using implicit logic:
|
|
- It only checked if the user was an **artist**
|
|
- If not an artist, it assumed access was granted
|
|
- However, this logic failed because it didn't explicitly handle the case where a user has `is_admin=True`
|
|
|
|
The original code:
|
|
```python
|
|
# Check project access for artists
|
|
if current_user.role == UserRole.ARTIST:
|
|
member = db.query(ProjectMember).filter(
|
|
ProjectMember.project_id == episode.project_id,
|
|
ProjectMember.user_id == current_user.id
|
|
).first()
|
|
if not member:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Access denied to this project"
|
|
)
|
|
|
|
return episode
|
|
```
|
|
|
|
## Solution
|
|
Added explicit checks for admins and coordinators at the beginning of the function:
|
|
|
|
```python
|
|
# Admins and coordinators have access to all episodes
|
|
if current_user.is_admin or current_user.role == UserRole.COORDINATOR:
|
|
return episode
|
|
|
|
# Check project access for artists and other roles
|
|
if current_user.role == UserRole.ARTIST:
|
|
member = db.query(ProjectMember).filter(
|
|
ProjectMember.project_id == episode.project_id,
|
|
ProjectMember.user_id == current_user.id
|
|
).first()
|
|
if not member:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Access denied to this project"
|
|
)
|
|
|
|
return episode
|
|
```
|
|
|
|
## Changes Made
|
|
|
|
**File**: `backend/routers/shots.py`
|
|
**Function**: `check_episode_access()` (lines 44-72)
|
|
|
|
### Before
|
|
- Implicit access for non-artists
|
|
- No explicit admin check
|
|
|
|
### After
|
|
- Explicit early return for admins (`is_admin=True`)
|
|
- Explicit early return for coordinators (`role=COORDINATOR`)
|
|
- Clear access control logic
|
|
|
|
## Testing
|
|
|
|
### Test Script
|
|
Created `backend/test_admin_shot_access.py` to verify:
|
|
- ✓ Admins can access any episode
|
|
- ✓ Coordinators can access any episode
|
|
- ✓ Artists can only access episodes in their projects
|
|
|
|
### Manual Testing
|
|
1. Login as admin
|
|
2. Navigate to any project
|
|
3. Click on any shot
|
|
4. Shot detail panel should open without 403 error
|
|
|
|
## Impact
|
|
|
|
### Fixed
|
|
- Admins can now access all shot details
|
|
- Coordinators can access all shot details
|
|
- No more 403 errors for privileged users
|
|
|
|
### Unchanged
|
|
- Artists still require project membership
|
|
- Security model remains intact
|
|
- No breaking changes to API
|
|
|
|
## Related Files
|
|
- `backend/routers/shots.py` - Main fix
|
|
- `backend/test_admin_shot_access.py` - Test script
|
|
- `frontend/src/components/shot/ShotDetailPanel.vue` - Frontend component (no changes needed)
|
|
|
|
## Deployment Notes
|
|
- No database migration required
|
|
- No frontend changes required
|
|
- Backend restart required to apply fix
|
|
- Backward compatible
|
|
|
|
## Prevention
|
|
This issue occurred because the access control logic relied on implicit behavior. Future improvements:
|
|
1. Always use explicit checks for privileged roles
|
|
2. Add comprehensive access control tests
|
|
3. Document access control logic clearly
|
|
|
|
## Date
|
|
November 17, 2025
|