- Add Django Channels 4 + channels-redis to requirements and INSTALLED_APPS
- Upgrade ASGI config to ProtocolTypeRouter with JWT-authenticated WebSocket routing
- Add JWTAuthMiddleware for WebSocket token auth via query param
- Add CallSession, CallParticipant, CallEvent models with migration 0004
- MeetingCallConsumer: join/leave, P2P SDP/ICE relay via per-user groups,
instructor mute/unmute/kick with DB audit and WS broadcast
- REST endpoints: GET/POST/DELETE /meetings/{id}/call/ (session lifecycle),
POST /moderate/ (mute/unmute/kick), POST /screen-share/, GET /events/ (audit log)
- IsMeetingModerator permission (accepts training:signoff or meeting:moderate)
- Services: get_or_create_call_session, end_call_session, apply_moderation_action,
toggle_screen_share with full CallEvent audit trail
- Integration tests covering REST lifecycle, moderation, and WebSocket signaling
Co-Authored-By: Paperclip <noreply@paperclip.ing>
21 lines
818 B
Python
21 lines
818 B
Python
from rest_framework.permissions import BasePermission
|
|
|
|
|
|
class IsTrainer(BasePermission):
|
|
def has_permission(self, request, view):
|
|
if not request.user or not request.user.is_authenticated:
|
|
return False
|
|
from accounts.services import get_effective_capabilities
|
|
return "training:signoff" in get_effective_capabilities(request.user)
|
|
|
|
|
|
class IsMeetingModerator(BasePermission):
|
|
"""Grants access to users who can moderate meeting calls (trainers)."""
|
|
|
|
def has_permission(self, request, view):
|
|
if not request.user or not request.user.is_authenticated:
|
|
return False
|
|
from accounts.services import get_effective_capabilities
|
|
caps = get_effective_capabilities(request.user)
|
|
return "training:signoff" in caps or "meeting:moderate" in caps
|