test: backend
This commit is contained in:
@@ -25,14 +25,19 @@ def extract_notebook_path(
|
||||
) -> Optional[str]:
|
||||
"""Pull the relative notebook path out of the original request URI.
|
||||
|
||||
Only ``/jupyter/{workspace_id}/notebooks/*.ipynb`` requests are
|
||||
subject to file-level lock checks; everything else (tree views,
|
||||
``/api/contents`` and WebSocket upgrades) bypasses the lock.
|
||||
Match ``/jupyter/{workspace_id}/notebooks/*.ipynb`` (the legacy
|
||||
iframe flow) and ``/jupyter/{workspace_id}/api/contents/*.ipynb``
|
||||
(the Monaco-based Contents API PUT path). The caller decides
|
||||
whether to actually enforce the lock — typically only on writes.
|
||||
"""
|
||||
pattern = rf"^/jupyter/{re.escape(workspace_id)}/notebooks/(.+\.ipynb)"
|
||||
match = re.match(pattern, uri)
|
||||
if match:
|
||||
return match.group(1)
|
||||
nb_pattern = rf"^/jupyter/{re.escape(workspace_id)}/notebooks/(.+\.ipynb)"
|
||||
contents_pattern = (
|
||||
rf"^/jupyter/{re.escape(workspace_id)}/api/contents/(.+\.ipynb)"
|
||||
)
|
||||
for pattern in (nb_pattern, contents_pattern):
|
||||
match = re.match(pattern, uri)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
|
||||
@@ -126,13 +131,16 @@ async def verify_jupyter_access(
|
||||
await load_active_membership_or_403(session, user_id, workspace_id)
|
||||
|
||||
notebook_path = extract_notebook_path(original_uri, workspace_id)
|
||||
if notebook_path and await check_notebook_is_locked(
|
||||
session, workspace_id, notebook_path, user_id,
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail=f"Notebook '{notebook_path}' is currently locked",
|
||||
)
|
||||
# Lock only on writes — reads (GET) stay open so anyone can still
|
||||
# preview a locked notebook the way they could via the iframe before.
|
||||
if notebook_path and request.method in {"PUT", "POST", "PATCH", "DELETE"}:
|
||||
if await check_notebook_is_locked(
|
||||
session, workspace_id, notebook_path, user_id,
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail=f"Notebook '{notebook_path}' is currently locked",
|
||||
)
|
||||
|
||||
runtime_client = request.app.state.runtime_client
|
||||
ws_info = await runtime_client.get_workspace(workspace_id)
|
||||
|
||||
Reference in New Issue
Block a user