fix: tighten API P0 auth and route handling
This commit is contained in:
@@ -60,6 +60,33 @@ def _resolve_institute(
|
||||
return None, db, teacher_uuid
|
||||
|
||||
|
||||
def _allowed_neo4j_dbs(user_id: str, user_email: str) -> set[str]:
|
||||
"""Return Neo4j databases this user may request via lazy graph APIs."""
|
||||
allowed = {f"cc.users.teacher.{user_id.replace('-', '')}"} if user_id else set()
|
||||
if user_id or user_email:
|
||||
_, institute_db, _ = _resolve_institute(user_id, user_email)
|
||||
if institute_db:
|
||||
allowed.add(institute_db)
|
||||
allowed.add(f"{institute_db}.curriculum")
|
||||
return allowed
|
||||
|
||||
|
||||
def _require_allowed_neo4j_db(neo4j_db_name: str, node_type: str, section_id: str, user_id: str, user_email: str) -> None:
|
||||
"""Reject arbitrary DB traversal from /graph/node/children query params."""
|
||||
if not neo4j_db_name:
|
||||
raise HTTPException(status_code=400, detail="neo4j_db_name is required")
|
||||
|
||||
if neo4j_db_name == "classroomcopilot":
|
||||
if node_type.startswith("Calendar") or section_id == "calendar":
|
||||
return
|
||||
raise HTTPException(status_code=403, detail="Requested graph database is not allowed for this node")
|
||||
|
||||
if neo4j_db_name in _allowed_neo4j_dbs(user_id, user_email):
|
||||
return
|
||||
|
||||
raise HTTPException(status_code=403, detail="Requested graph database is outside the authenticated user's scope")
|
||||
|
||||
|
||||
def _find_teacher_institute(user_email: str) -> Tuple[Optional[str], Optional[str]]:
|
||||
"""Return (institute_db_name, teacher_uuid) by matching worker_email in all institute DBs."""
|
||||
if not user_email:
|
||||
@@ -821,7 +848,11 @@ async def get_node_children(
|
||||
section_id: str = "",
|
||||
credentials: dict = Depends(SupabaseBearer()),
|
||||
) -> Dict[str, Any]:
|
||||
user_id = credentials.get("sub", "")
|
||||
user_email = credentials.get("email", "")
|
||||
if not user_id:
|
||||
raise HTTPException(status_code=403, detail="Could not extract user_id from token")
|
||||
_require_allowed_neo4j_db(neo4j_db_name, node_type, section_id, user_id, user_email)
|
||||
children = _get_children_for_node(neo4j_node_id, neo4j_db_name, node_type, section_id, user_email)
|
||||
return {"status": "success", "children": children}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user