mirror of
https://github.com/umap-project/umap.git
synced 2025-04-29 11:52:38 +02:00
chore(sync): relax some validation logic on the websocket server
Messages are now checked for conformity with the procol we defined, but stop at the `operation` boundary. Values aren't checked.
This commit is contained in:
parent
bc1dec245b
commit
db50c6cdd6
1 changed files with 7 additions and 23 deletions
30
umap/ws.py
30
umap/ws.py
|
@ -8,7 +8,7 @@ import django
|
||||||
import websockets
|
import websockets
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.signing import TimestampSigner
|
from django.core.signing import TimestampSigner
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, ValidationError
|
||||||
from websockets import WebSocketClientProtocol
|
from websockets import WebSocketClientProtocol
|
||||||
from websockets.server import serve
|
from websockets.server import serve
|
||||||
|
|
||||||
|
@ -31,26 +31,12 @@ class JoinMessage(BaseModel):
|
||||||
token: str
|
token: str
|
||||||
|
|
||||||
|
|
||||||
class Geometry(BaseModel):
|
|
||||||
type: Literal["Point", "Polygon", "LineString"]
|
|
||||||
coordinates: list
|
|
||||||
|
|
||||||
|
|
||||||
class GeometryValue(BaseModel):
|
|
||||||
geometry: Geometry
|
|
||||||
|
|
||||||
|
|
||||||
# FIXME better define the different messages
|
|
||||||
# to ensure only relying valid ones.
|
|
||||||
# This would mean having different kind of validation types
|
|
||||||
# based on the kind and verb.
|
|
||||||
class OperationMessage(BaseModel):
|
class OperationMessage(BaseModel):
|
||||||
kind: str = "operation"
|
kind: str = "operation"
|
||||||
verb: str = Literal["upsert", "update", "delete"]
|
verb: str = Literal["upsert", "update", "delete"]
|
||||||
subject: str = Literal["map", "layer", "feature"]
|
subject: str = Literal["map", "layer", "feature"]
|
||||||
metadata: Optional[dict] = None
|
metadata: Optional[dict] = None
|
||||||
key: Optional[str] = None
|
key: Optional[str] = None
|
||||||
value: Optional[str | bool | int | GeometryValue | Geometry] = None
|
|
||||||
|
|
||||||
|
|
||||||
async def join_and_listen(
|
async def join_and_listen(
|
||||||
|
@ -61,7 +47,6 @@ async def join_and_listen(
|
||||||
New messages will be broadcasted to other connected peers.
|
New messages will be broadcasted to other connected peers.
|
||||||
"""
|
"""
|
||||||
print(f"{user} joined room #{map_id}")
|
print(f"{user} joined room #{map_id}")
|
||||||
# FIXME: Persist permissions and user info.
|
|
||||||
CONNECTIONS[map_id].add(websocket)
|
CONNECTIONS[map_id].add(websocket)
|
||||||
try:
|
try:
|
||||||
async for raw_message in websocket:
|
async for raw_message in websocket:
|
||||||
|
@ -69,13 +54,12 @@ async def join_and_listen(
|
||||||
# as doing so beforehand would miss new connections
|
# as doing so beforehand would miss new connections
|
||||||
peers = CONNECTIONS[map_id] - {websocket}
|
peers = CONNECTIONS[map_id] - {websocket}
|
||||||
# Only relay valid "operation" messages
|
# Only relay valid "operation" messages
|
||||||
# try:
|
try:
|
||||||
# OperationMessage.model_validate_json(raw_message)
|
OperationMessage.model_validate_json(raw_message)
|
||||||
# except ValidationError as e:
|
websockets.broadcast(peers, raw_message)
|
||||||
print(raw_message)
|
except ValidationError as e:
|
||||||
|
error = f"An error occurred when receiving this message: {raw_message}"
|
||||||
# For now, broadcast anyway
|
print(error, e)
|
||||||
websockets.broadcast(peers, raw_message)
|
|
||||||
finally:
|
finally:
|
||||||
CONNECTIONS[map_id].remove(websocket)
|
CONNECTIONS[map_id].remove(websocket)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue