Files
triviathang/backend/sockets/events.py
2025-12-22 14:47:25 -05:00

115 lines
3.3 KiB
Python

from flask_socketio import emit, join_room, leave_room
from backend.app import socketio
from backend.auth.middleware import validate_jwt
from backend.models import User
@socketio.on('connect')
def handle_connect(auth):
"""Handle client connection with JWT authentication"""
# Extract token from auth parameter
token = auth.get('token') if auth else None
if not token:
print('Connection rejected: No token provided')
return False # Reject connection
# Validate JWT
claims = validate_jwt(token)
if not claims:
print('Connection rejected: Invalid token')
return False # Reject connection
# Get user
user = User.query.filter_by(authelia_sub=claims['sub']).first()
if not user or not user.is_active:
print('Connection rejected: User not found or inactive')
return False
print(f'Client connected: {user.email}')
emit('connected', {
'message': 'Connected to trivia game server',
'user': user.to_dict()
})
@socketio.on('disconnect')
def handle_disconnect():
"""Handle client disconnection"""
print('Client disconnected')
@socketio.on('join_game')
def handle_join_game(data):
"""Handle client joining a game room with role validation
Expected data: { 'game_id': int, 'role': 'contestant' | 'admin', 'token': str }
"""
game_id = data.get('game_id')
role = data.get('role', 'contestant')
token = data.get('token')
if not game_id or not token:
emit('error', {'message': 'game_id and token are required'})
return
# Validate JWT
claims = validate_jwt(token)
if not claims:
emit('error', {'message': 'Invalid or expired token'})
return
# Get user
user = User.query.filter_by(authelia_sub=claims['sub']).first()
if not user or not user.is_active:
emit('error', {'message': 'User not found or inactive'})
return
# Join appropriate room based on role
if role == 'admin':
room = f'game_{game_id}_admin'
join_room(room)
print(f'User {user.email} joined admin room: {room}')
emit('joined', {
'game_id': game_id,
'room': 'admin',
'user': user.to_dict(),
'message': f'Joined admin room for game {game_id}'
})
else:
room = f'game_{game_id}_contestant'
join_room(room)
print(f'User {user.email} joined contestant room: {room}')
emit('joined', {
'game_id': game_id,
'room': 'contestant',
'user': user.to_dict(),
'message': f'Joined contestant room for game {game_id}'
})
@socketio.on('leave_game')
def handle_leave_game(data):
"""Handle client leaving a game room
Expected data: { 'game_id': int, 'role': 'contestant' | 'admin' }
"""
game_id = data.get('game_id')
role = data.get('role', 'contestant')
if not game_id:
emit('error', {'message': 'game_id is required'})
return
# Leave appropriate room based on role
if role == 'admin':
room = f'game_{game_id}_admin'
leave_room(room)
print(f'Client left admin room: {room}')
else:
room = f'game_{game_id}_contestant'
leave_room(room)
print(f'Client left contestant room: {room}')
emit('left', {'game_id': game_id, 'message': f'Left game {game_id}'})