WebHostLib: Properly Format IDs in API Responses (#4944)

* update the id formatter to use staticmethods to not fake the unused self arg, and then use the formatter for the user session endpoints

* missed an id (ty treble)

* clean up duplicate code

* Update WebHostLib/__init__.py

Co-authored-by: Aaron Wagener <mmmcheese158@gmail.com>

* keep the BaseConverter format

* lol, change all the instances

* revert this

---------

Co-authored-by: Aaron Wagener <mmmcheese158@gmail.com>
This commit is contained in:
qwint
2025-07-16 10:34:28 -05:00
committed by GitHub
parent 477028a025
commit e9e0861eb7
4 changed files with 24 additions and 12 deletions

View File

@@ -61,18 +61,26 @@ cache = Cache()
Compress(app) Compress(app)
def to_python(value):
return uuid.UUID(bytes=base64.urlsafe_b64decode(value + '=='))
def to_url(value):
return base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii')
class B64UUIDConverter(BaseConverter): class B64UUIDConverter(BaseConverter):
def to_python(self, value): def to_python(self, value):
return uuid.UUID(bytes=base64.urlsafe_b64decode(value + '==')) return to_python(value)
def to_url(self, value): def to_url(self, value):
return base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii') return to_url(value)
# short UUID # short UUID
app.url_map.converters["suuid"] = B64UUIDConverter app.url_map.converters["suuid"] = B64UUIDConverter
app.jinja_env.filters['suuid'] = lambda value: base64.urlsafe_b64encode(value.bytes).rstrip(b'=').decode('ascii') app.jinja_env.filters["suuid"] = to_url
app.jinja_env.filters["title_sorted"] = title_sorted app.jinja_env.filters["title_sorted"] = title_sorted

View File

@@ -3,6 +3,7 @@ from uuid import UUID
from flask import abort, url_for from flask import abort, url_for
from WebHostLib import to_url
import worlds.Files import worlds.Files
from . import api_endpoints, get_players from . import api_endpoints, get_players
from ..models import Room from ..models import Room
@@ -33,7 +34,7 @@ def room_info(room_id: UUID) -> Dict[str, Any]:
downloads.append(slot_download) downloads.append(slot_download)
return { return {
"tracker": room.tracker, "tracker": to_url(room.tracker),
"players": get_players(room.seed), "players": get_players(room.seed),
"last_port": room.last_port, "last_port": room.last_port,
"last_activity": room.last_activity, "last_activity": room.last_activity,

View File

@@ -1,6 +1,7 @@
from flask import session, jsonify from flask import session, jsonify
from pony.orm import select from pony.orm import select
from WebHostLib import to_url
from WebHostLib.models import Room, Seed from WebHostLib.models import Room, Seed
from . import api_endpoints, get_players from . import api_endpoints, get_players
@@ -10,13 +11,13 @@ def get_rooms():
response = [] response = []
for room in select(room for room in Room if room.owner == session["_id"]): for room in select(room for room in Room if room.owner == session["_id"]):
response.append({ response.append({
"room_id": room.id, "room_id": to_url(room.id),
"seed_id": room.seed.id, "seed_id": to_url(room.seed.id),
"creation_time": room.creation_time, "creation_time": room.creation_time,
"last_activity": room.last_activity, "last_activity": room.last_activity,
"last_port": room.last_port, "last_port": room.last_port,
"timeout": room.timeout, "timeout": room.timeout,
"tracker": room.tracker, "tracker": to_url(room.tracker),
}) })
return jsonify(response) return jsonify(response)
@@ -26,7 +27,7 @@ def get_seeds():
response = [] response = []
for seed in select(seed for seed in Seed if seed.owner == session["_id"]): for seed in select(seed for seed in Seed if seed.owner == session["_id"]):
response.append({ response.append({
"seed_id": seed.id, "seed_id": to_url(seed.id),
"creation_time": seed.creation_time, "creation_time": seed.creation_time,
"players": get_players(seed), "players": get_players(seed),
}) })

View File

@@ -2,6 +2,8 @@ import re
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Optional, cast from typing import TYPE_CHECKING, Optional, cast
from WebHostLib import to_python
if TYPE_CHECKING: if TYPE_CHECKING:
from flask import Flask from flask import Flask
from werkzeug.test import Client as FlaskClient from werkzeug.test import Client as FlaskClient
@@ -103,7 +105,7 @@ def stop_room(app_client: "FlaskClient",
poll_interval = 2 poll_interval = 2
print(f"Stopping room {room_id}") print(f"Stopping room {room_id}")
room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] room_uuid = to_python(room_id)
if timeout is not None: if timeout is not None:
sleep(.1) # should not be required, but other things might use threading sleep(.1) # should not be required, but other things might use threading
@@ -156,7 +158,7 @@ def set_room_timeout(room_id: str, timeout: float) -> None:
from WebHostLib.models import Room from WebHostLib.models import Room
from WebHostLib import app from WebHostLib import app
room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] room_uuid = to_python(room_id)
with db_session: with db_session:
room: Room = Room.get(id=room_uuid) room: Room = Room.get(id=room_uuid)
room.timeout = timeout room.timeout = timeout
@@ -168,7 +170,7 @@ def get_multidata_for_room(webhost_client: "FlaskClient", room_id: str) -> bytes
from WebHostLib.models import Room from WebHostLib.models import Room
from WebHostLib import app from WebHostLib import app
room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] room_uuid = to_python(room_id)
with db_session: with db_session:
room: Room = Room.get(id=room_uuid) room: Room = Room.get(id=room_uuid)
return cast(bytes, room.seed.multidata) return cast(bytes, room.seed.multidata)
@@ -180,7 +182,7 @@ def set_multidata_for_room(webhost_client: "FlaskClient", room_id: str, data: by
from WebHostLib.models import Room from WebHostLib.models import Room
from WebHostLib import app from WebHostLib import app
room_uuid = app.url_map.converters["suuid"].to_python(None, room_id) # type: ignore[arg-type] room_uuid = to_python(room_id)
with db_session: with db_session:
room: Room = Room.get(id=room_uuid) room: Room = Room.get(id=room_uuid)
room.seed.multidata = data room.seed.multidata = data