Fix 403 for invited members streaming audio and 500 on invite listing
Invited members have no Nextcloud credentials of their own — stream and waveform endpoints now use the file uploader's NC credentials instead of the current member's. Falls back to the current member if uploaded_by is null. The invite listing/info endpoints were comparing timezone-aware expires_at values against naive datetime.now(), causing a TypeError (500). Fixed by using datetime.now(timezone.utc) throughout bands.py and invites.py. Also removes leftover debug logging from versions.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
@@ -37,7 +37,7 @@ async def list_invites(
|
||||
invites = await repo.get_invites_for_band(band_id)
|
||||
|
||||
# Filter for non-expired invites (optional - could also show expired)
|
||||
now = datetime.now()
|
||||
now = datetime.now(timezone.utc)
|
||||
pending_invites = [
|
||||
invite for invite in invites
|
||||
if invite.expires_at > now and invite.used_at is None
|
||||
@@ -93,7 +93,7 @@ async def revoke_invite(
|
||||
)
|
||||
|
||||
# Check if invite is still pending (not used and not expired)
|
||||
now = datetime.now()
|
||||
now = datetime.now(timezone.utc)
|
||||
if invite.used_at is not None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Invite management endpoints.
|
||||
"""
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
@@ -32,7 +32,7 @@ async def get_invite_info(
|
||||
)
|
||||
|
||||
# Check if invite is already used or expired
|
||||
now = datetime.now()
|
||||
now = datetime.now(timezone.utc)
|
||||
if invite.used_at is not None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
|
||||
@@ -186,8 +186,12 @@ async def get_waveform(
|
||||
version, _ = await _get_version_and_assert_band_membership(version_id, session, current_member)
|
||||
if not version.waveform_url:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Waveform not ready")
|
||||
|
||||
storage = NextcloudClient.for_member(current_member)
|
||||
|
||||
# Use the uploader's NC credentials — invited members may not have NC configured
|
||||
uploader: Member | None = None
|
||||
if version.uploaded_by:
|
||||
uploader = await MemberRepository(session).get_by_id(version.uploaded_by)
|
||||
storage = NextcloudClient.for_member(uploader) if uploader else NextcloudClient.for_member(current_member)
|
||||
if storage is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -228,17 +232,6 @@ async def stream_version(
|
||||
current_member: Member = Depends(_member_from_request),
|
||||
):
|
||||
version, song = await _get_version_and_assert_band_membership(version_id, session, current_member)
|
||||
|
||||
# Import at function level to avoid circular imports
|
||||
from rehearsalhub.repositories.band import BandRepository
|
||||
role = await BandRepository(session).get_member_role(song.band_id, current_member.id)
|
||||
|
||||
# Debug logging for permission issues
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
log.info(f"User {current_member.id} accessing version {version_id}")
|
||||
log.info(f"Song band: {song.band_id}")
|
||||
log.info(f"User role in band: {role if role else 'NOT A MEMBER'}")
|
||||
|
||||
# Prefer HLS playlist if transcoding finished, otherwise serve the raw file
|
||||
if version.cdn_hls_base:
|
||||
@@ -248,7 +241,11 @@ async def stream_version(
|
||||
else:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="No audio file")
|
||||
|
||||
storage = NextcloudClient.for_member(current_member)
|
||||
# Use the uploader's NC credentials — invited members may not have NC configured
|
||||
uploader: Member | None = None
|
||||
if version.uploaded_by:
|
||||
uploader = await MemberRepository(session).get_by_id(version.uploaded_by)
|
||||
storage = NextcloudClient.for_member(uploader) if uploader else NextcloudClient.for_member(current_member)
|
||||
if storage is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
||||
Reference in New Issue
Block a user