This commit is contained in:
Kilton937342 2022-09-25 22:32:19 +02:00
parent a26b4aaa43
commit 8391c2e64a
5 changed files with 487 additions and 320 deletions

View File

@ -2,7 +2,8 @@ import uuid
from services.password import get_password_hash from services.password import get_password_hash
from database.auth.models import User, UserEdit from database.auth.models import User, UserEdit
from sqlmodel import Session, select from sqlmodel import Session, select
from jose import jwt, exceptions
from config import SECRET_KEY, ALGORITHM
def create_user_db(username:str , password: str, db: Session): def create_user_db(username:str , password: str, db: Session):
user = User(username=username, hashed_password=password, clientId=uuid.uuid4()) user = User(username=username, hashed_password=password, clientId=uuid.uuid4())
db.add(user) db.add(user)
@ -18,6 +19,17 @@ def get_user_from_clientId_db(clientId: str , db: Session):
user = db.exec(select(User).where(User.clientId == clientId)).first() user = db.exec(select(User).where(User.clientId == clientId)).first()
return user return user
def get_user_from_token(token: str, db: Session):
try:
decoded = jwt.decode(token=token, key=SECRET_KEY,
algorithms=[ALGORITHM])
except exceptions.ExpiredSignatureError:
return False
clientId = decoded.get('sub')
return get_user_from_clientId_db(clientId=clientId, db=db)
def update_user_db(clientId: str, user: UserEdit, db: Session): def update_user_db(clientId: str, user: UserEdit, db: Session):
db_user = get_user_from_clientId_db(clientId, db) db_user = get_user_from_clientId_db(clientId, db)

View File

@ -1,22 +1,30 @@
from fastapi import Depends from fastapi import Depends
from sqlmodel import Session, select from sqlmodel import Session, select, col
from database.db import get_session from database.db import get_session
from database.room.models import Anonymous, Member, Room, RoomCreate from database.room.models import Anonymous, Member, Room, RoomCreate
from database.auth.models import User from database.auth.models import User
from services.database import generate_unique_code from services.database import generate_unique_code
from database.auth.crud import get_user_from_token
def check_room(room_id: str, db: Session = Depends(get_session)):
room = db.exec(select(Room).where(Room.id_code == room_id)).first()
return room
def create_room_db(*,room: RoomCreate, user: User | None = None, username: str | None = None, db: Session): def create_room_db(*,room: RoomCreate, user: User | None = None, username: str | None = None, db: Session):
id_code = generate_unique_code(Room,s=db) id_code = generate_unique_code(Room,s=db)
member_id = generate_unique_code(Member, s=db)
room_obj = Room(**room.dict(exclude_unset=True), id_code=id_code) room_obj = Room(**room.dict(exclude_unset=True), id_code=id_code)
if user is not None: if user is not None:
member = Member(user_id=user.id, room=room_obj, is_admin=True) member = Member(user_id=user.id, room=room_obj, is_admin=True, id_code=member_id)
db.add(member) db.add(member)
db.commit() db.commit()
db.refresh(member) db.refresh(member)
if username is not None: if username is not None:
reconnect_code = generate_unique_code(Anonymous, s=db, field_name='reconnect_code') reconnect_code = generate_unique_code(Anonymous, s=db, field_name='reconnect_code')
anonymous = Anonymous(username=username, reconnect_code=reconnect_code) anonymous = Anonymous(username=username, reconnect_code=reconnect_code)
member = Member(anonymous=anonymous, room=room_obj, is_admin=True) member = Member(anonymous=anonymous, room=room_obj, is_admin=True, id_code=member_id)
db.add(member) db.add(member)
db.commit() db.commit()
db.refresh(member) db.refresh(member)
@ -25,10 +33,159 @@ def create_room_db(*,room: RoomCreate, user: User | None = None, username: str |
return {"room": room_obj, "member": member} return {"room": room_obj, "member": member}
def check_room(room_id: str, db: Session = Depends(get_session)):
room = db.exec(select(Room).where(Room.id_code==room_id)).first()
return room
def userInRoom(room: Room, user: User, db: Session): def get_member_from_user(user_id: int, room_id: int, db: Session):
member = db.exec(select(Member).where(Member.room_id == room.id, Member.user_id == user.id)).first() member = db.exec(select(Member).where(Member.room_id ==
return member room_id, Member.user_id == user_id)).first()
return member
def get_member_from_token(token: str, room_id: int, db: Session):
user = get_user_from_token(token, db)
if user is False:
return False
if user is None:
return None
member = get_member_from_user(user.id, room_id, db)
return member
def get_member_from_anonymous(anonymous_id: int, room_id: int, db: Session):
member = db.exec(select(Member).where(Member.room_id ==
room_id, Member.anonymous_id == anonymous_id)).first()
return member
def get_member_from_reconnect_code(reconnect_code: str, room_id: int, db: Session):
anonymous = get_anonymous_from_code(reconnect_code, db)
if anonymous is None:
return None
member = get_member_from_anonymous(anonymous.id, room_id, db)
return member
def get_anonymous_from_code(reconnect_code: str, db: Session):
anonymous = db.exec(select(Anonymous).where(
Anonymous.reconnect_code == reconnect_code)).first()
return anonymous
def connect_member(member: Member, db: Session):
member.online = True
db.add(member)
db.commit()
db.refresh(member)
return member
def disconnect_member(member: Member, db: Session):
if member.waiting == False:
member.online = False
db.add(member)
db.commit()
db.refresh(member)
return member
else:
db.delete(member)
db.commit()
return member
def validate_username(username: str, room: Room, db: Session = Depends(get_session)):
print('VALIDATE', username)
if len(username) > 20:
return None
members = select(Member.anonymous_id).where(
Member.room_id == room.id, Member.anonymous_id != None)
anonymous = select(Anonymous).where(
col(Anonymous.id).in_(members), Anonymous.username == username)
username_anonymous = db.exec(anonymous).first()
return None if username_anonymous is not None else username
def create_anonymous_member(username: str, room: Room, db: Session):
username = validate_username(username, room, db)
if username is None:
return None
reconnect_code = generate_unique_code(
Anonymous, s=db, field_name="reconnect_code")
anonymous = Anonymous(username=username, reconnect_code=reconnect_code)
member_id = generate_unique_code(Member, s=db)
member = Member(room=room, anonymous=anonymous, id_code=member_id)
db.add(member)
db.commit()
db.refresh(member)
return member
def create_user_member(user: User, room: Room, db: Session):
member = get_member_from_user(user.id, room.id, db)
if member is not None:
return None
member_id = generate_unique_code(Member, s=db)
member = Member(room=room, user=user, id_code=member_id)
db.add(member)
db.commit()
db.refresh(member)
return member
def create_anonymous_waiter(username: str, room: Room, db: Session):
username = validate_username(username, room, db)
if username is None:
return None
reconnect_code = generate_unique_code(
Anonymous, s=db, field_name="reconnect_code")
anonymous = Anonymous(username=username, reconnect_code=reconnect_code)
member_id = generate_unique_code(Member, s=db)
member = Member(room=room, anonymous=anonymous,
waiting=True, id_code=member_id)
db.add(member)
db.commit()
db.refresh(member)
return member
def create_user_waiter(user: User, room: Room, db: Session):
member = get_member_from_user(user.id, room.id, db)
if member is not None:
return member
member_id = generate_unique_code(Member, s=db)
member = Member(room=room, user=user, waiting=True,
id_code=member_id)
db.add(member)
db.commit()
db.refresh(member)
return member
def get_waiter(waiter_code: str, db: Session):
return db.exec(select(Member).where(Member.id_code == waiter_code)).first()
def get_member(id_code: str,room_id:str, db: Session):
return db.exec(select(Member).where(Member.id_code == id_code, Member.room_id== room_id)).first()
def delete_member(member: Member, db: Session):
db.delete(member)
db.commit()
return None
def accept_waiter(member: Member, db: Session):
member.waiting = False
member.waiter_code = None
db.add(member)
db.commit()
db.refresh(member)
return member
def refuse_waiter(member: Member, db: Session):
db.delete(member)
db.commit()
return None
def leave_room(member: Member, db: Session):
db.delete(member)
db.commit()
return None

View File

@ -54,6 +54,7 @@ class Member(SQLModel, table = True):
online: bool = False online: bool = False
waiter_code: Optional[str] = Field(default= None) waiter_code: Optional[str] = Field(default= None)
id_code: str
class RoomRead(RoomBase): class RoomRead(RoomBase):
id_code: str id_code: str
#members: List['Member'] #members: List['Member']
@ -74,7 +75,7 @@ class MemberRead(SQLModel):
reconnect_code: str = '' reconnect_code: str = ''
isUser: bool isUser: bool
isAdmin: bool isAdmin: bool
id_code: str
class MemberSerializer(MemberRead): class MemberSerializer(MemberRead):
member: MemberWithRelations member: MemberWithRelations

View File

@ -1,9 +1,6 @@
from pydantic import Field from database.room.crud import create_room_db, delete_member, get_member, get_member_from_token, get_member_from_reconnect_code, connect_member, disconnect_member, create_anonymous_member, create_anonymous_waiter, create_user_member, create_user_waiter, get_waiter, accept_waiter, leave_room, refuse_waiter, check_room
from pydantic import create_model_from_typeddict
from pydantic.error_wrappers import ValidationError from pydantic.error_wrappers import ValidationError
from pydantic import validate_arguments from pydantic import validate_arguments
from services.database import generate_unique_code
from sqlmodel import col
from sqlmodel import select from sqlmodel import select
from pydantic import BaseModel from pydantic import BaseModel
from typing import Any, Callable, Dict, List, Optional from typing import Any, Callable, Dict, List, Optional
@ -12,7 +9,7 @@ from config import ALGORITHM, SECRET_KEY
from database.auth.crud import get_user_from_clientId_db from database.auth.crud import get_user_from_clientId_db
from database.auth.models import User from database.auth.models import User
from database.db import get_session from database.db import get_session
from database.room.crud import check_room, create_room_db, userInRoom
from sqlmodel import Session from sqlmodel import Session
from database.room.models import Anonymous, MemberSerializer, MemberWithRelations, MemberRead, Room, RoomCreate, RoomRead, Member from database.room.models import Anonymous, MemberSerializer, MemberWithRelations, MemberRead, Room, RoomCreate, RoomRead, Member
from services.auth import get_current_user_optional from services.auth import get_current_user_optional
@ -35,9 +32,9 @@ class Waiter(BaseModel):
def serialize_member(member: Member) -> MemberRead | Waiter: def serialize_member(member: Member) -> MemberRead | Waiter:
member_obj = member.user or member.anonymous member_obj = member.user or member.anonymous
if member.waiting == False: if member.waiting == False:
return MemberRead(username=member_obj.username, reconnect_code=getattr(member_obj, "reconnect_code", ""), isUser=member.user_id != None, isAdmin=member.is_admin) return MemberRead(username=member_obj.username, reconnect_code=getattr(member_obj, "reconnect_code", ""), isUser=member.user_id != None, isAdmin=member.is_admin, id_code=member.id_code)
if member.waiting == True: if member.waiting == True:
return Waiter(username=member_obj.username, waiter_id=member.waiter_code) return Waiter(username=member_obj.username, waiter_id=member.id_code)
@router.post('/room', response_model=RoomAndMember) @router.post('/room', response_model=RoomAndMember)
@ -70,11 +67,16 @@ class ConnectionManager:
def make_event_decorator(eventsDict): def make_event_decorator(eventsDict):
def _(name: str, conditions: List[Callable | bool] = []): def _(name: str | List, conditions: List[Callable | bool] = []):
def add_event(func): def add_event(func):
model = validate_arguments(func).model model = validate_arguments(func).model
eventsDict[name] = {"func": func, if type(name) == str:
"conditions": conditions, "model": model} eventsDict[name] = {"func": func,
"conditions": conditions, "model": model}
if type(name) == list:
for n in name:
eventsDict[n] = {"func": func,
"conditions": conditions, "model": model}
return func return func
return add_event return add_event
return _ return _
@ -131,7 +133,7 @@ class Consumer:
async def send(self, payload): async def send(self, payload):
type = payload.get('type', None) type = payload.get('type', None)
print('TYPE', type, self.member.id) print('TYPE', type, self.member)
if type is not None: if type is not None:
event_wrapper = self.sendings.get(type, None) event_wrapper = self.sendings.get(type, None)
if event_wrapper is not None: if event_wrapper is not None:
@ -147,6 +149,7 @@ class Consumer:
try: try:
validated_payload = model(self=self, **data) validated_payload = model(self=self, **data)
except ValidationError as e: except ValidationError as e:
print("ERROR", e)
await self.ws.send_json({"type": "error", "data": {"msg": "Oops there was an error"}}) await self.ws.send_json({"type": "error", "data": {"msg": "Oops there was an error"}})
return return
@ -154,19 +157,16 @@ class Consumer:
exclude=["v__duplicate_kwargs", "args", 'kwargs', "self"]) exclude=["v__duplicate_kwargs", "args", 'kwargs', "self"])
try: try:
parsed_payload = handler( parsed_payload = handler(
self, **validated_payload) self, **validated_payload)
await self.ws.send_json({'type': type, "data": dict_all(parsed_payload)}) await self.ws.send_json({'type': type, "data": dict_all(parsed_payload)})
return return
except Exception as e: except Exception as e:
print('NOPE', self.member.id, e)
return return
return return
print('pls') #print('pls')
await self.ws.send_json(payload) await self.ws.send_json(payload)
print('sent') #print('sent')
async def receive(self, data): async def receive(self, data):
event = data.get('type', None) event = data.get('type', None)
@ -211,9 +211,9 @@ class ConsumerManager:
if group not in self.active_connections: if group not in self.active_connections:
self.active_connections[group] = [] self.active_connections[group] = []
print("adding", ws, self.active_connections[group]) #print("adding", ws, self.active_connections[group])
if ws not in self.active_connections[group]: if ws not in self.active_connections[group]:
print('ACTUALLY ADDING') #print('ACTUALLY ADDING')
self.active_connections[group].append(ws) self.active_connections[group].append(ws)
def remove(self, group: str, ws: Consumer): def remove(self, group: str, ws: Consumer):
@ -223,14 +223,13 @@ class ConsumerManager:
async def broadcast(self, message, group: str, exclude: list[Consumer] = []): async def broadcast(self, message, group: str, exclude: list[Consumer] = []):
if group in self.active_connections: if group in self.active_connections:
print(self.active_connections[group], exclude) #print(self.active_connections[group], exclude)
for connection in list(set(self.active_connections[group])): for connection in list(set(self.active_connections[group])):
if connection not in exclude: if connection not in exclude:
print('SEND TO', connection, message) #print('SEND TO', connection, message)
await connection.send(message) await connection.send(message)
manager = ConsumerManager()
class Token(BaseModel): class Token(BaseModel):
@ -248,151 +247,12 @@ def get_user_from_token(token: str, db: Session):
return get_user_from_clientId_db(clientId=clientId, db=db) return get_user_from_clientId_db(clientId=clientId, db=db)
def get_member_from_user(user_id: int, room_id: int, db: Session): def check_same_member(member: Member, memberR: MemberRead):
member = db.exec(select(Member).where(Member.room_id == return (member.user is not None and memberR.username == member.user.username) or (member.anonymous and memberR.reconnect_code == member.anonymous.reconnect_code)
room_id, Member.user_id == user_id)).first()
return member
def get_member_from_token(token: str, room_id: int, db: Session):
user = get_user_from_token(token, db)
if user is False:
return False
if user is None:
return None
member = get_member_from_user(user.id, room_id, db)
return member
def get_member_from_anonymous(anonymous_id: int, room_id: int, db: Session):
member = db.exec(select(Member).where(Member.room_id ==
room_id, Member.anonymous_id == anonymous_id)).first()
return member
def get_member_reconnect_code(reconnect_code: str, room_id: int, db: Session):
anonymous = get_anonymous_from_code(reconnect_code, db)
if anonymous is None:
return None
member = get_member_from_anonymous(anonymous.id, room_id, db)
return member
def get_anonymous_from_code(reconnect_code: str, db: Session):
anonymous = db.exec(select(Anonymous).where(
Anonymous.reconnect_code == reconnect_code)).first()
return anonymous
def connect_member(member: Member, db: Session):
member.online = True
db.add(member)
db.commit()
db.refresh(member)
return member
def disconnect_member(member: Member, db: Session):
if member.waiting == False:
member.online = False
db.add(member)
db.commit()
db.refresh(member)
return member
else:
db.delete(member)
db.commit()
return member
def validate_username(username: str, room: Room, db: Session = Depends(get_session)):
print('VALIDATE', username)
if len(username) > 20:
return None
members = select(Member.anonymous_id).where(
Member.room_id == room.id, Member.anonymous_id != None)
anonymous = select(Anonymous).where(
col(Anonymous.id).in_(members), Anonymous.username == username)
username_anonymous = db.exec(anonymous).first()
return None if username_anonymous is not None else username
def create_anonymous_member(username: str, room: Room, db: Session):
username = validate_username(username)
if username is None:
return None
reconnect_code = generate_unique_code(
Anonymous, s=db, field_name="reconnect_code")
anonymous = Anonymous(username=username, reconnect_code=reconnect_code)
member = Member(room=room, anonymous=anonymous)
db.add(member)
db.commit()
db.refresh(member)
return member
def create_user_member(user: User, room: Room, db: Session):
member = get_member_from_user(user.id, room.id, db)
if member is not None:
return None
member = Member(room=room, user=user)
db.add(member)
db.commit()
db.refresh(member)
return member
def create_anonymous_waiter(username: str, room: Room, db: Session):
username = validate_username(username, room, db)
if username is None:
return None
reconnect_code = generate_unique_code(
Anonymous, s=db, field_name="reconnect_code")
anonymous = Anonymous(username=username, reconnect_code=reconnect_code)
waiter_code = generate_unique_code(Member, s=db, field_name="waiter_code")
member = Member(room=room, anonymous=anonymous,
waiting=True, waiter_code=waiter_code)
db.add(member)
db.commit()
db.refresh(member)
return member
def create_user_waiter(user: User, room: Room, db: Session):
member = get_member_from_user(user.id, room.id, db)
if member is not None:
return None
waiter_code = generate_unique_code(Member, s=db, field_name="waiter_code")
member = Member(room=room, user=user, waiting=True,
waiter_code=waiter_code)
db.add(member)
db.commit()
db.refresh(member)
return member
def get_waiter(waiter_code: str, db: Session):
return db.exec(select(Member).where(Member.waiter_code == waiter_code)).first()
def accept_waiter(member: Member, db: Session):
member.waiting = False
member.waiter_code = None
db.add(member)
db.commit()
db.refresh(member)
return member
def refuse_waiter(member: Member, db: Session):
db.delete(member)
db.commit()
return None
class RoomConsumer(Consumer): class RoomConsumer(Consumer):
def __init__(self, ws: WebSocket, room: Room, manager: ConsumerManager, db: Session): def __init__(self, ws: WebSocket, room: Room, manager: "RoomManager", db: Session):
self.room = room self.room = room
self.ws = ws self.ws = ws
self.manager = manager self.manager = manager
@ -406,39 +266,30 @@ class RoomConsumer(Consumer):
async def direct_send(self, type: str, payload: Any): async def direct_send(self, type: str, payload: Any):
await self.ws.send_json({'type': type, "data": payload}) await self.ws.send_json({'type': type, "data": payload})
async def send_to_all_room(self, type: str, payload: Any, exclude: bool = False):
await self.manager.broadcast({'type': type, "data": payload}, f'{self.room.id}__member', [exclude == True and self.ws])
await self.manager.broadcast({'type': type, "data": payload}, f'{self.room.id}__admin', [exclude == True and self.ws])
async def send_to_admin(self, type: str, payload: Any, exclude: bool = False): async def send_to_admin(self, type: str, payload: Any, exclude: bool = False):
await self.manager.broadcast({'type': type, "data": payload}, f'{self.room.id}__admin', [exclude == True and self.ws]) await self.manager.send_to_admin(self.room.id, {'type': type, "data": payload})
async def send_to(self, type: str, payload: Any,member_id, exclude: bool = False):
await self.manager.send_to(self.room.id, member_id,{'type': type, "data": payload})
async def send_to_members(self, type: str, payload: Any, exclude: bool = False): async def broadcast(self, type, payload, exclude=False):
await self.manager.broadcast({'type': type, "data": payload}, f'{self.room.id}__member', [exclude == True and self.ws]) await self.manager.broadcast({"type": type, "data": payload}, self.room.id, exclude=[exclude == True and self])
async def broadcast(self, type, payload, exclude= False):
await self.manager.broadcast({"type": type, "data": payload}, self.room.id, exclude = [exclude == True and self])
def add_to_admin(self):
self.manager.add(f'{self.room.id}__admin', self.ws)
def add_to_members(self):
self.manager.add(f'{self.room.id}__members', self.ws)
def add_to_group(self): def add_to_group(self):
if self.member.waiting == True:
self.manager.add(f'waiter__{self.member.waiter_code}', self)
self.manager.add(self.room.id, self) self.manager.add(self.room.id, self)
async def connect_self(self): async def connect_self(self):
if isinstance(self.member, Member): if isinstance(self.member, Member):
connect_member(self.member, self.db) connect_member(self.member, self.db)
await self.broadcast(type="connect", payload={"member": serialize_member(self.member).dict()}) await self.broadcast(type="connect", payload={"member": serialize_member(self.member).dict()}, exclude=True)
async def disconnect_self(self): async def disconnect_self(self):
if isinstance(self.member, Member): if isinstance(self.member, Member):
disconnect_member(self.member, self.db) disconnect_member(self.member, self.db)
await self.broadcast(type="disconnect", payload={"member": serialize_member(self.member).dict()}) if self.member.waiting is False:
await self.broadcast(type="disconnect", payload={"member": serialize_member(self.member).dict()})
else:
await self.broadcast(type="disconnect_waiter", payload={"waiter": serialize_member(self.member).dict()})
# DB Utilities # DB Utilities
@ -455,12 +306,12 @@ class RoomConsumer(Consumer):
return return
self.member = member self.member = member
# await self.connect_self() await self.connect_self()
self.add_to_group() self.add_to_group()
await self.direct_send(type="loggedIn", payload={"member": serialize_member(self.member).dict()}) await self.direct_send(type="loggedIn", payload={"member": serialize_member(self.member).dict()})
elif reconnect_code is not None: elif reconnect_code is not None:
member = get_member_reconnect_code( member = get_member_from_reconnect_code(
reconnect_code, self.room.id, db=self.db) reconnect_code, self.room.id, db=self.db)
if member is None: if member is None:
await self.direct_send(type="error", payload={"msg": "Utilisateur introuvable dans cette salle"}) await self.direct_send(type="error", payload={"msg": "Utilisateur introuvable dans cette salle"})
@ -468,7 +319,7 @@ class RoomConsumer(Consumer):
self.member = member self.member = member
# await self.connect_self() await self.connect_self()
self.add_to_group() self.add_to_group()
await self.direct_send(type="loggedIn", payload={"member": serialize_member(self.member).dict()}) await self.direct_send(type="loggedIn", payload={"member": serialize_member(self.member).dict()})
if reconnect_code is None and token is None: if reconnect_code is None and token is None:
@ -493,13 +344,14 @@ class RoomConsumer(Consumer):
self.member = waiter self.member = waiter
# await self.connect_self() # await self.connect_self()
self.add_to_group() self.add_to_group()
await self.connect_self()
await self.direct_send(type="loggedIn", payload={"member": serialize_member(self.member).dict()}) await self.direct_send(type="loggedIn", payload={"member": serialize_member(self.member).dict()})
return return
self.member = waiter self.member = waiter
self.add_to_group() self.add_to_group()
await self.direct_send(type="waiting", payload={"waiter": serialize_member(self.member).dict()}) await self.direct_send(type="waiting", payload={"waiter": serialize_member(self.member).dict()})
await self.broadcast(type="waiter", payload={"waiter": serialize_member(self.member).dict()}) await self.send_to_admin(type="waiter", payload={"waiter": serialize_member(self.member).dict()})
elif username is not None: elif username is not None:
waiter = create_anonymous_waiter(username, self.room, self.db) waiter = create_anonymous_waiter(username, self.room, self.db)
@ -509,13 +361,15 @@ class RoomConsumer(Consumer):
self.member = waiter self.member = waiter
self.add_to_group() self.add_to_group()
await self.direct_send(type="waiting", payload={"waiter": serialize_member(self.member).dict()}) await self.direct_send(type="waiting", payload={"waiter": serialize_member(self.member).dict()})
await self.broadcast(type="waiter", payload={"waiter": serialize_member(self.member).dict()}) await self.send_to_admin(type="waiter", payload={"waiter": serialize_member(self.member).dict()})
else: else:
if token is not None: if token is not None:
user = get_user_from_token(token, self.db) user = get_user_from_token(token, self.db)
if user is None: if user is None:
await self.direct_send(type="error", payload={"msg": "Utilisateur introuvable"})
return return
if user is False: if user is False:
await self.direct_send(type="error", payload={"msg": "Token expired"})
return return
member = create_user_member(user, self.room, self.db) member = create_user_member(user, self.room, self.db)
@ -523,7 +377,8 @@ class RoomConsumer(Consumer):
return return
self.member = member self.member = member
self.add_to_group() self.add_to_group()
await self.direct_send() await self.broadcast(type="joined", payload={"member": serialize_member(self.member).dict()}, exclude=True)
await self.direct_send(type="accepted", payload={"member": serialize_member(self.member).dict()})
elif username is not None: elif username is not None:
member = create_anonymous_member(username, self.room, self.db) member = create_anonymous_member(username, self.room, self.db)
if member is None: if member is None:
@ -531,55 +386,166 @@ class RoomConsumer(Consumer):
return return
self.member = member self.member = member
self.add_to_group() self.add_to_group()
await self.direct_send()
await self.broadcast(type="joined", payload={"member": serialize_member(self.member).dict()}, exclude=True)
await self.direct_send(type="accepted", payload={"member": serialize_member(self.member).dict()})
async def isAdminReceive(self):
is_admin = self.member is not None and self.member.is_admin == True
if not is_admin:
await self.direct_send(type="error", payload={"msg": "Vous n'avez pas la permission de faire ca"})
return False
return True
def isAdmin(self): def isAdmin(self):
return self.member is not None and self.member.is_admin == True return self.member is not None and self.member.is_admin == True
@Consumer.event('accept', conditions=[isAdmin]) @Consumer.event('accept', conditions=[isAdminReceive])
async def accept(self, waiter_id: str): async def accept(self, waiter_id: str):
waiter = get_waiter(waiter_id, self.db) waiter = get_waiter(waiter_id, self.db)
if waiter is None:
await self.direct_send(type="error", payload={'msg': "Utilisateur introuvable"})
return
member = accept_waiter(waiter, self.db) member = accept_waiter(waiter, self.db)
await self.manager.broadcast({"type": "accepted", "data": {'member': serialize_member(member).dict()}}, f"waiter__{waiter_id}") await self.send_to(type="accepted", payload={"member": serialize_member(member).dict()}, member_id=waiter_id)
await self.broadcast(type="joined", payload={"member": serialize_member(member).dict()}) await self.broadcast(type="joined", payload={"member": serialize_member(member).dict()})
@Consumer.event('refuse', conditions=[isAdmin]) @Consumer.event('refuse', conditions=[isAdminReceive])
async def accept(self, waiter_id: str): async def accept(self, waiter_id: str):
waiter = get_waiter(waiter_id, self.db) waiter = get_waiter(waiter_id, self.db)
member = refuse_waiter(waiter, self.db) member = refuse_waiter(waiter, self.db)
await self.manager.broadcast({"type": "refused", "data": {'waiter_id': waiter_id}}, f"waiter__{waiter_id}") await self.send_to(type="refused", payload={'waiter_id': waiter_id}, member_id=waiter_id)
#await self.broadcast(type="joined", payload={"member": serialize_member(member).dict()}) # await self.broadcast(type="joined", payload={"member": serialize_member(member).dict()})
@Consumer.event('ping_room') @Consumer.event('ping_room')
async def proom(self): async def proom(self):
await self.broadcast(type='ping', payload={}) await self.broadcast(type='ping', payload={}, exclude=True)
async def hasRoom(self):
if self.member is None:
await self.direct_send(type="error", payload={"msg": "Vous n'êtes connecté à aucune salle"})
return self.member
@Consumer.event('leave', conditions=[hasRoom])
async def leave(self):
if self.member.is_admin is True:
await self.direct_send(type="error", payload={"msg": "Vous ne pouvez pas quitter une salle dont vous êtes l'administrateur"})
return
member_obj = serialize_member(self.member).dict()
leave_room(self.member, self.db)
await self.direct_send(type="successfully_leaved", payload = {})
await self.broadcast(type='leaved', payload ={"member": member_obj})
self.member = None
@Consumer.event('ban', conditions=[isAdminReceive])
async def ban(self, member_id: str):
member = get_member(member_id, self.room.id, self.db)
if member == None:
await self.direct_send(type="error", payload={"msg": "Utilisateur introuvable"})
return
if member.is_admin is True:
await self.direct_send(type="error", payload={"msg": "Vous ne pouvez pas bannir un administrateur"})
return
member_serialized = serialize_member(member)
leave_room(member, self.db)
await self.send_to(type="banned", payload={}, member_id=member.id_code)
await self.broadcast(type="leaved", payload = {"member": member_serialized.dict()})
def isMember(self): def isMember(self):
return self.member is not None and self.member.waiting == False return self.member is not None and self.member.waiting == False
# Sending Events # Sending Events
@Consumer.sending("joined", conditions=[isMember]) @Consumer.sending("joined", conditions=[isMember])
def joined(self, member: MemberRead): def joined(self, member: MemberRead):
print('MEMBER', self.member, member) if self.member.id_code == member.id_code:
if (self.member.user is not None and member.username == self.member.user.username) or (self.member.anonymous and member.reconnect_code == self.member.anonymous.reconnect_code): raise ValueError("")
raise ValueError("Nope")
if self.member.is_admin == False: if self.member.is_admin == False:
member.reconnect_code = "" member.reconnect_code = ""
return {"member": member} return {"member": member}
@Consumer.sending('waiter', conditions=[isAdmin]) @Consumer.sending(['waiter', "disconnect_waiter"], conditions=[isAdmin])
def waiter(self, waiter: Waiter): def waiter(self, waiter: Waiter):
return {"waiter": waiter} return {"waiter": waiter}
@Consumer.sending(['connect', "disconnect", ""])
def connect_event(self, member: MemberRead):
if not self.member.is_admin:
member.reconnect_code = ""
return {"member": member}
@Consumer.sending('disconnect')
def disconnect_event(self, member: MemberRead):
if not self.member.is_admin:
member.reconnect_code = ""
return {"member": member}
@Consumer.sending('disconnect_waiter', conditions=[isAdmin])
def disconnect_event(self, waiter: Waiter):
return {"waiter": waiter}
def isWaiter(self):
return self.member is not None and self.member.waiting == True
@Consumer.sending("refused", conditions=[isWaiter])
def refused(self, waiter_id: str):
self.member = None
self.manager.remove(self.room.id, self)
return {"waiter_id": waiter_id}
@Consumer.sending("banned", conditions=[isMember])
def banned(self):
self.member = None
self.manager.remove(self.room.id, self)
return {}
@Consumer.sending('ping', conditions=[isMember]) @Consumer.sending('ping', conditions=[isMember])
def ping(self): def ping(self):
return {} return {}
async def disconnect(self): async def disconnect(self):
print("DISCONNECT", self.member)
self.manager.remove(self.room.id, self) self.manager.remove(self.room.id, self)
#await self.disconnect_self() await self.disconnect_self()
class RoomManager:
def __init__(self):
self.active_connections: Dict[str, List[RoomConsumer]] = {}
def add(self, group: str, ws: RoomConsumer):
if group not in self.active_connections:
self.active_connections[group] = []
#print("adding", ws, self.active_connections[group])
if ws not in self.active_connections[group]:
#print('ACTUALLY ADDING')
self.active_connections[group].append(ws)
def remove(self, group: str, ws: RoomConsumer):
if group in self.active_connections:
if ws in self.active_connections[group]:
self.active_connections[group].remove(ws)
async def broadcast(self, message, group: str, exclude: list[RoomConsumer] = []):
if group in self.active_connections:
#print(self.active_connections[group], exclude)
for connection in list(set(self.active_connections[group])):
if connection not in exclude:
#print('SEND TO', connection, message)
await connection.send(message)
async def send_to(self, group, id_code, msg):
if group in self.active_connections:
members = [c for c in self.active_connections[group] if c.member.id_code == id_code]
for m in members:
await m.send(msg)
async def send_to_admin(self, group, msg):
if group in self.active_connections:
members = [c for c in self.active_connections[group] if c.member.is_admin == True]
for m in members:
await m.send(msg)
manager = RoomManager()
@router.websocket('/ws/room/{room_id}') @router.websocket('/ws/room/{room_id}')
async def room_ws(ws: WebSocket, room: Room | None = Depends(check_room), db: Session = Depends(get_session)): async def room_ws(ws: WebSocket, room: Room | None = Depends(check_room), db: Session = Depends(get_session)):
if room is None: if room is None:
@ -587,32 +553,3 @@ async def room_ws(ws: WebSocket, room: Room | None = Depends(check_room), db: Se
status_code=status.HTTP_404_NOT_FOUND, detail='Room not found') status_code=status.HTTP_404_NOT_FOUND, detail='Room not found')
consumer = RoomConsumer(ws=ws, room=room, manager=manager, db=db) consumer = RoomConsumer(ws=ws, room=room, manager=manager, db=db)
await consumer.run() await consumer.run()
class TestConsumer(Consumer):
async def connect(self):
await self.ws.accept()
def test(self):
return True
@Consumer.event("test", conditions=[True, test])
async def testering(self):
await self.ws.send_json({"type": "success"})
await self.send({"type": "test", "data": {"i": {"username": "lilian", "reconnect_code": "something", "isAdmin": False, "isUser": False}, "test": 12}})
# await self.send({"type": "test", "data": {"i": {"username": "lilian", "reconnect_code": "something", "isAdmin": False, "isUser": False}}})
return
@Consumer.sending('test', conditions=[])
def sendtest(self, i: MemberRead, test: int):
print("i", i)
print(i.reconnect_code)
print(dict(i))
i.reconnect_code = "nope"
return {"i": i, "test": test}
@router.websocket('/ws/test')
async def test(ws: WebSocket):
consumer = TestConsumer(ws)
await consumer.run()

View File

@ -5,12 +5,13 @@ from tests.test_auth import test_register
def test_create_room_no_auth(client: TestClient, public=False): def test_create_room_no_auth(client: TestClient, public=False):
r = client.post('/room', json={"name": "test_room", r = client.post('/room', json={"name": "test_room",
"public": False}, params={'username': "lilian", "public": public}) "public": public}, params={'username': "lilian"})
print(r.json()) print(r.json())
assert "id_code" in r.json()['room'] assert "id_code" in r.json()['room']
assert r.json()['member']['reconnect_code'] is not None assert r.json()['member']['reconnect_code'] is not None
assert {"room": {**r.json()['room'], 'id_code': None}, "member": {**r.json()['member'], "reconnect_code": None}} == {"room": {"id_code": None, "name": "test_room", assert "id_code" in r.json()['member']
"public": False}, 'member': {"username": "lilian", "reconnect_code": None, "isUser": False, "isAdmin": True}} assert {"room": {**r.json()['room'], 'id_code': None}, "member": {**r.json()['member'], "reconnect_code": None, "id_code": None}} == {"room": {"id_code": None, "name": "test_room",
"public": public}, 'member': {"username": "lilian", "reconnect_code": None, "isUser": False, "isAdmin": True, "id_code": None}}
return r.json() return r.json()
@ -29,8 +30,9 @@ def test_create_room_auth(client: TestClient, token=None):
"public": False}, headers={"Authorization": "Bearer " + token}) "public": False}, headers={"Authorization": "Bearer " + token})
print(r.json()) print(r.json())
assert "id_code" in r.json()['room'] assert "id_code" in r.json()['room']
assert "id_code" in r.json()['member']
assert {**r.json(), "room": {**r.json()['room'], 'id_code': None}} == {"room": {"id_code": None, "name": "test_room", assert {**r.json(), "room": {**r.json()['room'], 'id_code': None}} == {"room": {"id_code": None, "name": "test_room",
"public": False}, 'member': {"username": "lilian", "reconnect_code": "", "isUser": True, "isAdmin": True}} "public": False}, 'member': {"username": "lilian", "reconnect_code": "", "isUser": True, "isAdmin": True, "id_code": r.json()['member']['id_code']}}
return r.json() return r.json()
@ -51,9 +53,9 @@ def test_login_no_auth(client: TestClient):
ws.send_json({"type": "login", "data": { ws.send_json({"type": "login", "data": {
"reconnect_code": member['reconnect_code']}}) "reconnect_code": member['reconnect_code']}})
data = ws.receive_json() data = ws.receive_json()
print(data) assert "id_code" in data['data']['member']
assert data == {'type': "loggedIn", "data": {"member": { assert data == {'type': "loggedIn", "data": {"member": {
"username": member['username'], "reconnect_code": member['reconnect_code'], "isAdmin": True, "isUser": False}}} "username": member['username'], "reconnect_code": member['reconnect_code'], "isAdmin": True, "isUser": False, "id_code": data['data']["member"]["id_code"]}}}
def test_login_no_auth_not_in_room(client: TestClient): def test_login_no_auth_not_in_room(client: TestClient):
@ -76,8 +78,9 @@ def test_login_auth(client: TestClient):
ws.send_json({"type": "login", "data": {"token": token}}) ws.send_json({"type": "login", "data": {"token": token}})
data = ws.receive_json() data = ws.receive_json()
print(data) print(data)
assert "id_code" in data["data"]['member']
assert data == {'type': "loggedIn", "data": {"member": { assert data == {'type': "loggedIn", "data": {"member": {
"username": member['username'], "isAdmin": True, "isUser": True, 'reconnect_code': ""}}} "username": member['username'], "isAdmin": True, "isUser": True, 'reconnect_code': "", "id_code": data['data']["member"]["id_code"]}}}
def test_login_auth_not_in_room(client: TestClient): def test_login_auth_not_in_room(client: TestClient):
@ -103,10 +106,12 @@ def test_join_auth(client: TestClient):
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member:
member.send_json({"type": "join", "data": {"token": token}}) member.send_json({"type": "join", "data": {"token": token}})
mdata = member.receive_json() mdata = member.receive_json()
assert "waiter_id" in mdata['data']['waiter'] assert "waiter_id" in mdata['data']['waiter']
assert mdata == {"type": "waiting", "data": {"waiter": { assert mdata == {"type": "waiting", "data": {"waiter": {
"username": "lilian2", "waiter_id": mdata['data']['waiter']['waiter_id']}}} "username": "lilian2", "waiter_id": mdata['data']['waiter']['waiter_id']}}}
admin.send_json({"type": "ping_room"})
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {'type': "waiter", 'data': { assert adata == {'type': "waiter", 'data': {
"waiter": {"waiter_id": mdata['data']['waiter']['waiter_id'], "username": "lilian2"}}} "waiter": {"waiter_id": mdata['data']['waiter']['waiter_id'], "username": "lilian2"}}}
@ -114,14 +119,26 @@ def test_join_auth(client: TestClient):
admin.send_json({"type": "accept", "data": { admin.send_json({"type": "accept", "data": {
"waiter_id": mdata['data']['waiter']['waiter_id']}}) "waiter_id": mdata['data']['waiter']['waiter_id']}})
mdata = member.receive_json() mdata = member.receive_json()
print('MDATA', mdata)
assert mdata == {"type": "accepted", "data": {"member": { assert mdata == {"type": "accepted", "data": {"member": {
"username": "lilian2", "isUser": True, "isAdmin": False, "reconnect_code": ""}}} "username": "lilian2", "isUser": True, "isAdmin": False, "reconnect_code": "", "id_code": mdata['data']["member"]["id_code"]}}}
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {'type': "joined", 'data': { assert adata == {'type': "joined", 'data': {
"member": {"reconnect_code": "", "username": "lilian2", "isUser": True, "isAdmin": False}}} "member": {"reconnect_code": "", "username": "lilian2", "isUser": True, "isAdmin": False, "id_code": adata['data']["member"]["id_code"]}}}
admin.send_json({"type": "ping_room"}) admin.send_json({"type": "ping_room"})
mdata = member.receive_json() mdata = member.receive_json()
assert mdata == {"type": "ping", "data": {}} assert mdata == {"type": "ping", "data": {}}
def test_join_waiter_not_found(client: TestClient):
token = test_register(client, username="lilian2")['access']
room = test_create_room_no_auth(client=client)
member = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": {
"reconnect_code": member['reconnect_code']}})
admin.receive_json()
admin.send_json({"type": "accept", "data": {"waiter_id": "OOOO"}})
data = admin.receive_json()
assert data == {"type": "error", "data": {"msg": "Utilisateur introuvable"}}
def test_join_no_auth(client: TestClient): def test_join_no_auth(client: TestClient):
room = test_create_room_no_auth(client=client) room = test_create_room_no_auth(client=client)
@ -148,15 +165,15 @@ def test_join_no_auth(client: TestClient):
new_reconnect = mdata['data']['member']['reconnect_code'] new_reconnect = mdata['data']['member']['reconnect_code']
assert 'reconnect_code' in mdata['data']['member'] assert 'reconnect_code' in mdata['data']['member']
assert mdata == {"type": "accepted", "data": {"member": { assert mdata == {"type": "accepted", "data": {"member": {
"username": "member", "reconnect_code": new_reconnect, "isUser": False, "isAdmin": False}}} "username": "member", "reconnect_code": new_reconnect, "isUser": False, "isAdmin": False, "id_code": mdata['data']["member"]["id_code"]}}}
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {'type': "joined", 'data': { assert adata == {'type': "joined", 'data': {
"member": {"reconnect_code": new_reconnect, "username": "member", "isUser": False, "isAdmin": False}}} "member": {"reconnect_code": new_reconnect, "username": "member", "isUser": False, "isAdmin": False, "id_code": adata['data']["member"]["id_code"]}}}
admin.send_json({"type": "ping_room"}) admin.send_json({"type": "ping_room"})
mdata = memberws.receive_json() mdata = memberws.receive_json()
assert mdata == {"type": "ping", "data": {}} assert mdata == {"type": "ping", "data": {}}
return {"room": room, "members": [member['reconnect_code'], new_reconnect]} return {"room": room['room'], "members": [member['reconnect_code'], new_reconnect]}
def test_join_no_auth_username_error(client: TestClient): def test_join_no_auth_username_error(client: TestClient):
@ -217,7 +234,7 @@ def test_join_auth_in_room_yet(client: TestClient):
member.send_json({"type": "join", "data": {"token": token}}) member.send_json({"type": "join", "data": {"token": token}})
mdata = member.receive_json() mdata = member.receive_json()
assert mdata == {"type": "loggedIn", "data": {"member": { assert mdata == {"type": "loggedIn", "data": {"member": {
"username": "lilian2", "isAdmin": True, "isUser": True}}} "username": "lilian", "isAdmin": True, "isUser": True, 'reconnect_code': "", "id_code": mdata['data']["member"]["id_code"]}}}
def test_join_auth_public(client: TestClient): def test_join_auth_public(client: TestClient):
@ -227,19 +244,19 @@ def test_join_auth_public(client: TestClient):
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": member['reconnect_code']}}) "reconnect_code": member['reconnect_code']}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member:
member.send_json({"type": "join", "data": {"token": token}}) member.send_json({"type": "join", "data": {"token": token}})
mdata = member.receive_json() mdata = member.receive_json()
assert mdata == {"type": "accepted", "data": {"member": { assert mdata == {"type": "accepted", "data": {"member": {
"username": "member", "isUser": True, "isAdmin": False}}} "username": "lilian2", "isUser": True, "isAdmin": False, "reconnect_code": "", "id_code": mdata['data']["member"]["id_code"]}}}
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {'type': "joined", 'data': { assert adata == {'type': "joined", 'data': {
"member": {"reconnect_code": "", "username": "member", "isUser": True}}} "member": {"reconnect_code": "", "username": "lilian2", "isUser": True, "isAdmin": False, "id_code": mdata['data']["member"]["id_code"]}}}
admin.send_json({"type": "ping_room"}) admin.send_json({"type": "ping_room"})
mdata = member.receive_json() mdata = member.receive_json()
assert mdata == {"type": "ping"} assert mdata == {"type": "ping", "data": {}}
def test_join_no_auth_public(client: TestClient): def test_join_no_auth_public(client: TestClient):
@ -248,46 +265,46 @@ def test_join_no_auth_public(client: TestClient):
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": member['reconnect_code']}}) "reconnect_code": member['reconnect_code']}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member:
member.send_json({"type": "join", "data": {"username": "member"}}) member.send_json({"type": "join", "data": {"username": "member"}})
mdata = member.receive_json() mdata = member.receive_json()
assert 'reconnect_code' in mdata['data']['member'] assert 'reconnect_code' in mdata['data']['member']
assert mdata == {"type": "accepted", "data": {"member": { assert mdata == {"type": "accepted", "data": {"member": {
"username": "member", "reconnect_code": mdata['data']['reconnect_code'], "isUser": False, "isAdmin": False}}} "username": "member", "reconnect_code": mdata['data']['member']['reconnect_code'], "isUser": False, "isAdmin": False, "id_code": mdata['data']["member"]["id_code"]}}}
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {'type': "joined", 'data': { assert adata == {'type': "joined", 'data': {
"member": {"reconnect_code": mdata['data']['reconnect_code'], "username": "member", "isUser": False}}} "member": {"reconnect_code": mdata['data']['member']['reconnect_code'], "username": "member", "isUser": False, "isAdmin": False, "id_code": mdata['data']["member"]["id_code"]}}}
member.send_json({"type": "update_groups"}) member.send_json({"type": "update_groups"})
admin.send_json({"type": "ping_room"}) admin.send_json({"type": "ping_room"})
mdata = member.receive_json() mdata = member.receive_json()
assert mdata == {"type": "ping"} assert mdata == {"type": "ping", "data": {}}
def test_join_no_auth_unauthorized(client: TestClient): def test_join_auth_unauthorized(client: TestClient):
token = test_register(client, username="lilian2")['access'] token = test_register(client, username="lilian2")['access']
room = test_create_room_no_auth(client=client) room = test_create_room_no_auth(client=client)
member = room['member'] member = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": member['reconnect_code']}}) "reconnect_code": member['reconnect_code']}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member:
member.send_json({"type": "join", "data": {"token": token}}) member.send_json({"type": "join", "data": {"token": token}})
mdata = member.receive_json() mdata = member.receive_json()
assert "id_code" in mdata['data']['waiter'] assert "waiter_id" in mdata['data']['waiter']
assert mdata == {"type": "waiting", "data": {"waiter": { assert mdata == {"type": "waiting", "data": {"waiter": {
"username": "lilian2", "id_code": mdata['data']['waiter']}}} "username": "lilian2", "waiter_id": mdata['data']['waiter']['waiter_id']}}}
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {'type': "waiter", 'data': { assert adata == {'type': "waiter", 'data': {
"waiter": {"id_code": mdata['data']['waiter']['id_code'], "username": "member"}}} "waiter": {"waiter_id": mdata['data']['waiter']['waiter_id'], "username": "lilian2"}}}
member.send_json({"type": "refuse", "data": { member.send_json({"type": "refuse", "data": {
"waiter_id": mdata['data']['waiter']['id_code']}}) "waiter_id": mdata['data']['waiter']['waiter_id']}})
mdata = member.receive_json() mdata = member.receive_json()
assert mdata == {"type": "error", "data": { assert mdata == {"type": "error", "data": {
@ -300,14 +317,14 @@ def test_connect_admin(client: TestClient):
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": members[0]}}) "reconnect_code": members[0]}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as member:
member.send_json({'type': "login", "data": { member.send_json({'type': "login", "data": {
"reconnect_code": members[0]}}) "reconnect_code": members[1]}})
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {"type": "connect", "data": {"member": { assert adata == {"type": "connect", "data": {"member": {
"username": "member", "reconnect_code": members[1], "isAdmin": False, "isUser": False}}} "username": "member", "reconnect_code": members[1], "isAdmin": False, "isUser": False, "id_code": adata['data']["member"]["id_code"]}}}
def test_connect_member(client: TestClient): def test_connect_member(client: TestClient):
@ -316,15 +333,14 @@ def test_connect_member(client: TestClient):
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({"type": "login", "data": { memberws.send_json({"type": "login", "data": {
"reconnect_code": members[1]}}) "reconnect_code": members[1]}})
memberws.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({'type': "login", "data": { admin.send_json({'type': "login", "data": {
"reconnect_code": members[0]}}) "reconnect_code": members[0]}})
mdata = memberws.receive_json() mdata = memberws.receive_json()
assert mdata == {"type": "connect", "data": {"member": { assert mdata == {"type": "connect", "data": {"member": {
"username": "member", "reconnect_code": "", "isAdmin": True, "isUser": False}}} "username": "lilian", "reconnect_code": "", "isAdmin": True, "isUser": False, "id_code": mdata['data']["member"]["id_code"]}}}
def test_disconnect(client: TestClient): def test_disconnect(client: TestClient):
room = test_join_no_auth(client=client) room = test_join_no_auth(client=client)
@ -332,42 +348,61 @@ def test_disconnect(client: TestClient):
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({"type": "login", "data": { memberws.send_json({"type": "login", "data": {
"reconnect_code": members[1]}}) "reconnect_code": members[1]}})
memberws.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({'type': "login", "data": { admin.send_json({'type': "login", "data": {
"reconnect_code": members[0]}}) "reconnect_code": members[0]}})
memberws.receive_json()
admin.close() admin.close()
mdata = memberws.receive_json() mdata = memberws.receive_json()
assert mdata == {"type": "disconnect", "data": {"member": { assert mdata == {"type": "disconnect", "data": {"member": {
"username": "member", "reconnect_code": "", "isAdmin": True, "isUser": False}}} "username": "lilian", "reconnect_code": "", "isAdmin": True, "isUser": False, "id_code": mdata['data']["member"]["id_code"]}}}
def test_disconnect_waiter(client: TestClient):
room = test_create_room_no_auth(client=client)
member = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": {
"reconnect_code": member['reconnect_code']}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({'type': "join", "data": {
"username": "test"}})
mdata = memberws.receive_json()
admin.receive_json()
memberws.close()
adata = admin.receive_json()
assert adata == {"type": "disconnect_waiter", "data": {"waiter": {**mdata['data']['waiter']}}}
def test_leave(client: TestClient): def test_leave(client: TestClient):
room = test_join_no_auth(client=client) room = test_create_room_no_auth(client=client, public=True)
members = room['members'] member = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": members[1]}}) "reconnect_code": member["reconnect_code"]}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({"type": "login", "data": { memberws.send_json({"type": "join", "data": {
"reconnect_code": members[1]}}) "username":"test"}})
m = memberws.receive_json()
admin.receive_json()
memberws.send_json({"type": "leave"}) memberws.send_json({"type": "leave"})
data = memberws.receive_json() data = memberws.receive_json()
assert data == {"type": "successfully_leaved"} assert data == {"type": "successfully_leaved", "data": {}}
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {"type": "leaved", "data": {"member": { assert adata == {"type": "leaved", "data": {"member": {
"username": "member", "reconnect_code": members[1], "isAdmin": False, "isUser": False}}} "username": "test", "reconnect_code": m["data"]['member']["reconnect_code"], "isAdmin": False, "isUser": False, "id_code": adata['data']["member"]["id_code"]}}}
def test_leave_not_connected(client: TestClient): def test_leave_not_connected(client: TestClient):
room = test_create_room_no_auth(client=client) room = test_create_room_no_auth(client=client)
members = room['members'] members = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({"type": "leave"}) memberws.send_json({"type": "leave"})
data = memberws.receive_json() data = memberws.receive_json()
assert data == {"type": "error", "data": { assert data == {"type": "error", "data": {
@ -375,12 +410,13 @@ def test_leave_not_connected(client: TestClient):
def test_leave_admin(client: TestClient): def test_leave_admin(client: TestClient):
room = test_join_no_auth(client=client) room = test_create_room_no_auth(client=client)
members = room['members'] member = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": members[0]}}) "reconnect_code": member["reconnect_code"]}})
admin.receive_json()
admin.send_json({"type": "leave"}) admin.send_json({"type": "leave"})
data = admin.receive_json() data = admin.receive_json()
assert data == {"type": "error", "data": { assert data == {"type": "error", "data": {
@ -388,50 +424,74 @@ def test_leave_admin(client: TestClient):
def test_ban_anonymous(client: TestClient): def test_ban_anonymous(client: TestClient):
room = test_create_room_no_auth(client=client) room = test_create_room_no_auth(client=client, public=True)
members = room['members'] member = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": members[1]}}) "reconnect_code": member['reconnect_code']}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({"type": "login", "data": { memberws.send_json({"type": "join", "data": {
"reconnect_code": members[1]}}) "username": "test"}})
admin.send_json({"type": "ban", "data": {"member": { m = memberws.receive_json()
"username": "member", "reconnect_code": members[1], "isUser": False, "isAdmin": False}}}) reconnect_code = m['data']['member']['reconnect_code']
id_code = m['data']['member']['id_code']
admin.receive_json()
admin.send_json({"type": "ban", "data": {"member_id": m['data']['member']['id_code']}})
mdata = memberws.receive_json()
assert mdata == {"type": "banned", "data": {}}
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {"type": "leaved", "data": {"member": { assert adata == {"type": "leaved", "data": {"member": {
"username": "member", "reconnect_code": members[1], "isUser": True, "isAdmin": False}}} "username": "test", "reconnect_code": reconnect_code, "isUser": False, "isAdmin": False, "id_code": id_code}}}
def test_ban_anonymous_unauthorized(client: TestClient): def test_ban_anonymous_unauthorized(client: TestClient):
room = test_create_room_no_auth(client=client) room = test_create_room_no_auth(client=client, public=True)
members = room['members'] members = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": members[1]}}) "reconnect_code": members["reconnect_code"]}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({"type": "login", "data": { memberws.send_json({"type": "join", "data": {
"reconnect_code": members[1]}}) "username": "test"}})
memberws.send_json({"type": "ban", "data": {"member": { memberws.receive_json()
"username": "member", "reconnect_code": members[1], "isUser": False, "isAdmin": False}}}) memberws.send_json({"type": "ban", "data": {"member_id": "OOO"}})
mdata = memberws.receive_json() mdata = memberws.receive_json()
assert mdata == {"type": "error", "data": { assert mdata == {"type": "error", "data": {
"msg": "Vous n'avez pas les permissions pour faire ça"}} "msg": "Vous n'avez pas la permission de faire ca"}}
def test_ban_admin(client: TestClient):
def test_ban_user(client: TestClient):
token = test_register(client=client, username="lilian2")
room = test_create_room_no_auth(client=client) room = test_create_room_no_auth(client=client)
members = room['member'] members = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": { admin.send_json({"type": "login", "data": {
"reconnect_code": members["reconnect_code "]}}) "reconnect_code": members["reconnect_code"]}})
data = admin.receive_json()
admin.send_json({"type": "ban", "data": {"member_id": data['data']['member']['id_code']}})
a = admin.receive_json()
assert a == {'type': "error", "data": {
"msg": "Vous ne pouvez pas bannir un administrateur"}}
def test_ban_user(client: TestClient):
token = test_register(client=client, username="lilian2")['access']
room = test_create_room_no_auth(client=client, public=True)
member = room['member']
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as admin:
admin.send_json({"type": "login", "data": {
"reconnect_code": member["reconnect_code"]}})
admin.receive_json()
with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws: with client.websocket_connect(f"/ws/room/" + room['room']['id_code']) as memberws:
memberws.send_json({"type": "join", "data": {"token": token}}) memberws.send_json({"type": "join", "data": {"token": token}})
adata = admin.receive_json() m = memberws.receive_json()
admin.receive_json()
admin.send_json(
{"type": "ban", "data": {"member_id": m['data']['member']['id_code']}})
mdata = memberws.receive_json()
assert mdata == {"type": "banned", "data": {}}
admin.send_json({"type": "ban", "data": {"member": {
"username": "lilian2", "reconnect_code": "", "isUser": True, "isAdmin": False}}})
adata = admin.receive_json() adata = admin.receive_json()
assert adata == {"type": "leaved", "data": {"member": { assert adata == {"type": "leaved", "data": {"member": {
"username": "lilian2", "reconnect_code": "", "isUser": True, "isAdmin": False}}} "username": "lilian2", "reconnect_code": "", "isUser": True, "isAdmin": False, "id_code": m['data']['member']['id_code']}}}