diff --git a/changelog.d/20240802_135738_jsick_DM_45563.md b/changelog.d/20240802_135738_jsick_DM_45563.md new file mode 100644 index 0000000..d77eb55 --- /dev/null +++ b/changelog.d/20240802_135738_jsick_DM_45563.md @@ -0,0 +1,17 @@ + + +### Backwards-incompatible changes + +- + +### New features + +- + +### Bug fixes + +- When logging into JupyterHub, a Noteburst now looks for XRSF tokens from each redirect. + +### Other changes + +- diff --git a/src/noteburst/jupyterclient/jupyterlab.py b/src/noteburst/jupyterclient/jupyterlab.py index 85d7575..6483a1f 100644 --- a/src/noteburst/jupyterclient/jupyterlab.py +++ b/src/noteburst/jupyterclient/jupyterlab.py @@ -483,16 +483,30 @@ def _extract_xsrf(self, response: Response) -> str | None: async def log_into_hub(self) -> None: """Log into JupyterHub or raise a JupyterError.""" self.logger.debug("Logging into JupyterHub") - r = await self.http_client.get(self.url_for("hub/home")) - # JupyterHub returns a 302 redirect to the login page on success, - # but we don't want to follow that redirect. This request is just - # to set cookies. - if r.status_code >= 400: - raise JupyterError.from_response(self.user.username, r) + url = self.url_for("hub/home") + r = await self.http_client.get(url, follow_redirects=False) + while r.is_redirect: + xsrf = self._extract_xsrf(r) + if xsrf and xsrf != self._lab_xsrf: + self._hub_xsrf = xsrf + next_url = urljoin(url, r.headers["Location"]) + r = await self.http_client.get(next_url, follow_redirects=False) + r.raise_for_status() xsrf = self._extract_xsrf(r) - if xsrf: + if xsrf and xsrf != self._lab_xsrf: self._hub_xsrf = xsrf + if not self._hub_xsrf: + raise JupyterError( + reason="No XSRF token found for JupyterHub", + url=url, + username=self.user.username, + status=r.status_code, + method="GET", + body=r.text, + ) + self.logger.debug("Logged into JupyterHub with XSRF token") + async def log_into_lab(self) -> None: """Log into JupyterLab or raise a JupyterError.""" self.logger.debug("Logging into JupyterLab") diff --git a/src/noteburst/worker/main.py b/src/noteburst/worker/main.py index f650e7d..7fb2fb4 100644 --- a/src/noteburst/worker/main.py +++ b/src/noteburst/worker/main.py @@ -140,7 +140,7 @@ def create_message(message: str) -> SlackMessage: ) -async def shutdown(ctx: dict[Any, Any]) -> None: # noqa: PLR0912 +async def shutdown(ctx: dict[Any, Any]) -> None: """Clean up the worker context on shutdown.""" if "logger" in ctx: logger = ctx["logger"]