Spaces:
Running
Running
Forward admin identity when creating analysis sessions
Browse files- app.py +3 -2
- tests/test_admin_analysis.py +51 -0
app.py
CHANGED
|
@@ -606,7 +606,8 @@ async def analyze(request: Request, playerId: str = Form(...), clientId: UUID =
|
|
| 606 |
reference = playerId.strip()
|
| 607 |
if not reference or len(reference) > 100 or len(sessionName) > 150:
|
| 608 |
raise HTTPException(422, "Invalid player reference or session name")
|
| 609 |
-
session = backend("", user_id, "POST", {"clientId": client_id, "playerId": reference, "name": sessionName}
|
|
|
|
| 610 |
session_id, player_id = session["session_id"], session["player_id"]
|
| 611 |
owner_user_id = session.get("user_id") if "user_id" in session else user_id
|
| 612 |
actor_is_admin = bool(session.get("actor_is_admin", False))
|
|
@@ -751,7 +752,7 @@ def result_action_id(session_id, index):
|
|
| 751 |
|
| 752 |
|
| 753 |
def owned_session_row(session_id, user_id, is_admin=False):
|
| 754 |
-
row = backend(f"/{session_id}", user_id)
|
| 755 |
if row.get("user_id") != user_id and not is_admin:
|
| 756 |
raise HTTPException(404, "Session not found")
|
| 757 |
return row
|
|
|
|
| 606 |
reference = playerId.strip()
|
| 607 |
if not reference or len(reference) > 100 or len(sessionName) > 150:
|
| 608 |
raise HTTPException(422, "Invalid player reference or session name")
|
| 609 |
+
session = backend("", user_id, "POST", {"clientId": client_id, "playerId": reference, "name": sessionName},
|
| 610 |
+
is_admin=request.state.is_admin)
|
| 611 |
session_id, player_id = session["session_id"], session["player_id"]
|
| 612 |
owner_user_id = session.get("user_id") if "user_id" in session else user_id
|
| 613 |
actor_is_admin = bool(session.get("actor_is_admin", False))
|
|
|
|
| 752 |
|
| 753 |
|
| 754 |
def owned_session_row(session_id, user_id, is_admin=False):
|
| 755 |
+
row = backend(f"/{session_id}", user_id, is_admin=is_admin)
|
| 756 |
if row.get("user_id") != user_id and not is_admin:
|
| 757 |
raise HTTPException(404, "Session not found")
|
| 758 |
return row
|
tests/test_admin_analysis.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import asyncio
|
| 2 |
+
from io import BytesIO
|
| 3 |
+
import unittest
|
| 4 |
+
from unittest.mock import patch
|
| 5 |
+
from uuid import UUID
|
| 6 |
+
|
| 7 |
+
from fastapi import UploadFile
|
| 8 |
+
from starlette.requests import Request
|
| 9 |
+
|
| 10 |
+
import app as analysis_app
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
class StopBeforeUpload(Exception):
|
| 14 |
+
pass
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class AdminAnalysisTest(unittest.TestCase):
|
| 18 |
+
def test_begin_analysis_forwards_admin_identity_to_internal_backend(self):
|
| 19 |
+
user_id = "11111111-1111-4111-8111-111111111111"
|
| 20 |
+
client_id = UUID("22222222-2222-4222-8222-222222222222")
|
| 21 |
+
player_id = "33333333-3333-4333-8333-333333333333"
|
| 22 |
+
for is_admin in (False, True):
|
| 23 |
+
with self.subTest(is_admin=is_admin):
|
| 24 |
+
request = Request({"type": "http", "method": "POST", "path": "/api/analyze", "headers": []})
|
| 25 |
+
request.state.user_id = user_id
|
| 26 |
+
request.state.is_admin = is_admin
|
| 27 |
+
actions = UploadFile(BytesIO(b"{}"), filename="actions.json")
|
| 28 |
+
calibration = UploadFile(BytesIO(b"data"), filename="calibration.npz")
|
| 29 |
+
with patch.object(analysis_app, "backend", side_effect=StopBeforeUpload) as backend:
|
| 30 |
+
with self.assertRaises(StopBeforeUpload):
|
| 31 |
+
asyncio.run(analysis_app.analyze(
|
| 32 |
+
request, playerId=player_id, clientId=client_id,
|
| 33 |
+
videoOrders=[1, 2], videos=[], videoDriveLinks=["first", "second"],
|
| 34 |
+
actionsJson=actions, calibration=calibration, sessionName="Admin session",
|
| 35 |
+
))
|
| 36 |
+
backend.assert_called_once_with("", user_id, "POST", {
|
| 37 |
+
"clientId": str(client_id), "playerId": player_id, "name": "Admin session",
|
| 38 |
+
}, is_admin=is_admin)
|
| 39 |
+
|
| 40 |
+
def test_admin_session_lookup_forwards_admin_identity(self):
|
| 41 |
+
session_id = "44444444-4444-4444-8444-444444444444"
|
| 42 |
+
admin_id = "11111111-1111-4111-8111-111111111111"
|
| 43 |
+
other_owner = "22222222-2222-4222-8222-222222222222"
|
| 44 |
+
with patch.object(analysis_app, "backend", return_value={"user_id": other_owner}) as backend:
|
| 45 |
+
self.assertEqual(analysis_app.owned_session_row(session_id, admin_id, is_admin=True),
|
| 46 |
+
{"user_id": other_owner})
|
| 47 |
+
backend.assert_called_once_with(f"/{session_id}", admin_id, is_admin=True)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
if __name__ == "__main__":
|
| 51 |
+
unittest.main()
|