Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-jupyter-server for openSUSE:Factory checked in at 2023-08-30 10:20:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-jupyter-server (Old) and /work/SRC/openSUSE:Factory/.python-jupyter-server.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jupyter-server" Wed Aug 30 10:20:45 2023 rev:33 rq:1107864 version:2.7.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-jupyter-server/python-jupyter-server.changes 2023-06-13 16:09:09.598761506 +0200 +++ /work/SRC/openSUSE:Factory/.python-jupyter-server.new.1766/python-jupyter-server.changes 2023-08-30 10:23:32.150685362 +0200 @@ -1,0 +2,21 @@ +Tue Aug 29 07:28:29 UTC 2023 - Ben Greiner <c...@bnavigator.de> + +- Update fixes: + * CVE-2023-39968 boo#1214730 + * CVE-2023-40170 boo#1214731 + +------------------------------------------------------------------- +Sat Aug 26 13:06:44 UTC 2023 - Ben Greiner <c...@bnavigator.de> + +- Update to 2.7.2 + * accessing API version should not count as activity #1315 + (@minrk) + * Make kernel_id as a conditional optional field #1300 + (@allstrive) + * Reference current_user to detect auth #1294 (@bhperry) + * send2trash now supports deleting from different filesystem + type(#1290) #1291 (@wqj97) +- Release 2.7.0 + * Add missing events to gateway client #1288 (@allstrive) + +------------------------------------------------------------------- Old: ---- jupyter_server-2.6.0.tar.gz New: ---- jupyter_server-2.7.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-jupyter-server.spec ++++++ --- /var/tmp/diff_new_pack.DJRTaX/_old 2023-08-30 10:23:33.166721628 +0200 +++ /var/tmp/diff_new_pack.DJRTaX/_new 2023-08-30 10:23:33.170721770 +0200 @@ -32,7 +32,7 @@ %endif Name: python-jupyter-server%{psuffix} -Version: 2.6.0 +Version: 2.7.2 Release: 0 Summary: The backend to Jupyter web applications License: BSD-3-Clause @@ -50,7 +50,7 @@ BuildRequires: python-rpm-macros >= 20210929 Requires: python >= 3.8 Requires: python-Jinja2 -Requires: python-Send2Trash +Requires: python-Send2Trash >= 1.8.2 Requires: python-anyio >= 3.1.0 Requires: python-argon2-cffi Requires: python-jupyter-client >= 7.4.4 ++++++ jupyter_server-2.6.0.tar.gz -> jupyter_server-2.7.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/.github/workflows/python-tests.yml new/jupyter_server-2.7.2/.github/workflows/python-tests.yml --- old/jupyter_server-2.6.0/.github/workflows/python-tests.yml 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/.github/workflows/python-tests.yml 2020-02-02 01:00:00.000000000 +0100 @@ -26,6 +26,8 @@ python-version: "pypy-3.8" - os: macos-latest python-version: "3.10" + - os: ubuntu-latest + python-version: "3.12" steps: - name: Checkout uses: actions/checkout@v3 @@ -36,7 +38,9 @@ run: | sudo apt-get update sudo apt-get install texlive-plain-generic inkscape texlive-xetex - sudo apt-get install xvfb x11-utils libxkbcommon-x11-0 pandoc + sudo apt-get install xvfb x11-utils libxkbcommon-x11-0 + # pandoc is not up to date in the ubuntu repos, so we install directly + wget https://github.com/jgm/pandoc/releases/download/3.1.2/pandoc-3.1.2-1-amd64.deb && sudo dpkg -i pandoc-3.1.2-1-amd64.deb - name: Run the tests on posix if: ${{ !startsWith(matrix.python-version, 'pypy') && !startsWith(matrix.os, 'windows') }} run: hatch run cov:test --cov-fail-under 75 || hatch run test:test --lf diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/.pre-commit-config.yaml new/jupyter_server-2.7.2/.pre-commit-config.yaml --- old/jupyter_server-2.6.0/.pre-commit-config.yaml 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/.pre-commit-config.yaml 2020-02-02 01:00:00.000000000 +0100 @@ -20,7 +20,7 @@ - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.22.0 + rev: 0.23.2 hooks: - id: check-github-workflows @@ -34,8 +34,8 @@ hooks: - id: black - - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.263 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.276 hooks: - id: ruff args: ["--fix"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/CHANGELOG.md new/jupyter_server-2.7.2/CHANGELOG.md --- old/jupyter_server-2.6.0/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100 @@ -4,6 +4,59 @@ <!-- <START NEW CHANGELOG ENTRY> --> +## 2.7.1 + +([Full Changelog](https://github.com/jupyter-server/jupyter_server/compare/v2.7.0...d8f4856c32b895106eac58c9c5768afd0e2f6465)) + +### Bugs fixed + +- accessing API version should not count as activity [#1315](https://github.com/jupyter-server/jupyter_server/pull/1315) ([@minrk](https://github.com/minrk)) +- Make kernel_id as a conditional optional field [#1300](https://github.com/jupyter-server/jupyter_server/pull/1300) ([@allstrive](https://github.com/allstrive)) +- Reference current_user to detect auth [#1294](https://github.com/jupyter-server/jupyter_server/pull/1294) ([@bhperry](https://github.com/bhperry)) + +### Maintenance and upkeep improvements + +- send2trash now supports deleting from different filesystem type(#1290) [#1291](https://github.com/jupyter-server/jupyter_server/pull/1291) ([@wqj97](https://github.com/wqj97)) + +### Documentation improvements + +- Add root `/api/` endpoint to REST spec [#1312](https://github.com/jupyter-server/jupyter_server/pull/1312) ([@minrk](https://github.com/minrk)) +- Fix broken link in doc [#1307](https://github.com/jupyter-server/jupyter_server/pull/1307) ([@Hind-M](https://github.com/Hind-M)) +- Rename notebook.auth.security.passwd->jupyter_server.auth.passwd in docs [#1306](https://github.com/jupyter-server/jupyter_server/pull/1306) ([@mathbunnyru](https://github.com/mathbunnyru)) +- Update notes link [#1298](https://github.com/jupyter-server/jupyter_server/pull/1298) ([@krassowski](https://github.com/krassowski)) +- docs: fix broken hyperlink to Tornado [#1297](https://github.com/jupyter-server/jupyter_server/pull/1297) ([@emmanuel-ferdman](https://github.com/emmanuel-ferdman)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter-server/jupyter_server/graphs/contributors?from=2023-06-27&to=2023-08-15&type=c)) + +[@allstrive](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aallstrive+updated%3A2023-06-27..2023-08-15&type=Issues) | [@bhperry](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Abhperry+updated%3A2023-06-27..2023-08-15&type=Issues) | [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Ablink1073+updated%3A2023-06-27..2023-08-15&type=Issues) | [@emmanuel-ferdman](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aemmanuel-ferdman+updated%3A2023-06-27..2023-08-15&type=Issues) | [@Hind-M](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3AHind-M+updated%3A2023-06-27..2023-08-15&type=Issues) | [@kevin-bates](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Akevin-bates+updated%3A2023-06-27..2023-08-15&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Akra ssowski+updated%3A2023-06-27..2023-08-15&type=Issues) | [@mathbunnyru](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Amathbunnyru+updated%3A2023-06-27..2023-08-15&type=Issues) | [@matthewwiese](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Amatthewwiese+updated%3A2023-06-27..2023-08-15&type=Issues) | [@minrk](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aminrk+updated%3A2023-06-27..2023-08-15&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Apre-commit-ci+updated%3A2023-06-27..2023-08-15&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Awelcome+updated%3A2023-06-27..2023-08-15&type=Issues) | [@wqj97](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Awqj97+updated%3A2023-06-27..2023-08-15&type=Issues) | [@Zsailer](https://github.com/search?q=repo%3Ajup yter-server%2Fjupyter_server+involves%3AZsailer+updated%3A2023-06-27..2023-08-15&type=Issues) + +<!-- <END NEW CHANGELOG ENTRY> --> + +## 2.7.0 + +([Full Changelog](https://github.com/jupyter-server/jupyter_server/compare/v2.6.0...b652f8d08530bd60ecf4cfffe6c32939fd94eb41)) + +### Bugs fixed + +- Add missing events to gateway client [#1288](https://github.com/jupyter-server/jupyter_server/pull/1288) ([@allstrive](https://github.com/allstrive)) + +### Maintenance and upkeep improvements + +- Handle test failures [#1289](https://github.com/jupyter-server/jupyter_server/pull/1289) ([@blink1073](https://github.com/blink1073)) +- Try testing against python 3.12 [#1282](https://github.com/jupyter-server/jupyter_server/pull/1282) ([@blink1073](https://github.com/blink1073)) + +### Documentation improvements + +- Remove frontend doc [#1292](https://github.com/jupyter-server/jupyter_server/pull/1292) ([@fcollonval](https://github.com/fcollonval)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter-server/jupyter_server/graphs/contributors?from=2023-05-25&to=2023-06-27&type=c)) + +[@allstrive](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aallstrive+updated%3A2023-05-25..2023-06-27&type=Issues) | [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Ablink1073+updated%3A2023-05-25..2023-06-27&type=Issues) | [@fcollonval](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Afcollonval+updated%3A2023-05-25..2023-06-27&type=Issues) | [@kevin-bates](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Akevin-bates+updated%3A2023-05-25..2023-06-27&type=Issues) | [@minrk](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aminrk+updated%3A2023-05-25..2023-06-27&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Apre-commit-ci+updated%3A2023-05-25..2023-06-27&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Awelcome+ updated%3A2023-05-25..2023-06-27&type=Issues) + ## 2.6.0 ([Full Changelog](https://github.com/jupyter-server/jupyter_server/compare/v2.5.0...35b8e9cb68eec48fe9a017ac128cb776c2ead195)) @@ -53,8 +106,6 @@ [@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Ablink1073+updated%3A2023-03-16..2023-05-25&type=Issues) | [@brichet](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Abrichet+updated%3A2023-03-16..2023-05-25&type=Issues) | [@codecov](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Acodecov+updated%3A2023-03-16..2023-05-25&type=Issues) | [@davidbrochart](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Adavidbrochart+updated%3A2023-03-16..2023-05-25&type=Issues) | [@dependabot](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Adependabot+updated%3A2023-03-16..2023-05-25&type=Issues) | [@echarles](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aecharles+updated%3A2023-03-16..2023-05-25&type=Issues) | [@frenzymadness](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Afrenzyma dness+updated%3A2023-03-16..2023-05-25&type=Issues) | [@hbcarlos](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Ahbcarlos+updated%3A2023-03-16..2023-05-25&type=Issues) | [@kevin-bates](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Akevin-bates+updated%3A2023-03-16..2023-05-25&type=Issues) | [@lresende](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Alresende+updated%3A2023-03-16..2023-05-25&type=Issues) | [@minrk](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aminrk+updated%3A2023-03-16..2023-05-25&type=Issues) | [@ojarjur](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Aojarjur+updated%3A2023-03-16..2023-05-25&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Apre-commit-ci+updated%3A2023-03-16..2023-05-25&type=Issues) | [@rajmusuku](https://github.com/search?q=repo%3Ajupyt er-server%2Fjupyter_server+involves%3Arajmusuku+updated%3A2023-03-16..2023-05-25&type=Issues) | [@SauravMaheshkar](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3ASauravMaheshkar+updated%3A2023-03-16..2023-05-25&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Awelcome+updated%3A2023-03-16..2023-05-25&type=Issues) | [@yuvipanda](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3Ayuvipanda+updated%3A2023-03-16..2023-05-25&type=Issues) | [@Zsailer](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server+involves%3AZsailer+updated%3A2023-03-16..2023-05-25&type=Issues) -<!-- <END NEW CHANGELOG ENTRY> --> - ## 2.5.0 ([Full Changelog](https://github.com/jupyter-server/jupyter_server/compare/v2.4.0...dc1eee8715dfe674560789caa5123dc895717ca1)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/PKG-INFO new/jupyter_server-2.7.2/PKG-INFO --- old/jupyter_server-2.6.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/PKG-INFO 2020-02-02 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: jupyter_server -Version: 2.6.0 +Version: 2.7.2 Summary: The backendâi.e. core services, APIs, and REST endpointsâto Jupyter web applications. Project-URL: Homepage, https://jupyter-server.readthedocs.io Project-URL: Documentation, https://jupyter-server.readthedocs.io @@ -69,7 +69,7 @@ Requires-Dist: prometheus-client Requires-Dist: pywinpty; os_name == 'nt' Requires-Dist: pyzmq>=24 -Requires-Dist: send2trash +Requires-Dist: send2trash>=1.8.2 Requires-Dist: terminado>=0.8.3 Requires-Dist: tornado>=6.2.0 Requires-Dist: traitlets>=5.6.0 @@ -92,6 +92,7 @@ Requires-Dist: tornado; extra == 'docs' Requires-Dist: typing-extensions; extra == 'docs' Provides-Extra: test +Requires-Dist: flaky; extra == 'test' Requires-Dist: ipykernel; extra == 'test' Requires-Dist: pre-commit; extra == 'test' Requires-Dist: pytest-console-scripts; extra == 'test' @@ -151,7 +152,7 @@ - When: Thursdays [8:00am, Pacific time](https://www.thetimezoneconverter.com/?t=8%3A00%20am&tz=San%20Francisco&) - Where: [Jovyan Zoom](https://zoom.us/my/jovyan?pwd=c0JZTHlNdS9Sek9vdzR3aTJ4SzFTQT09) -- What: [Meeting notes](https://github.com/jupyter-server/team-compass/issues/4) +- What: [Meeting notes](https://github.com/jupyter-server/team-compass/issues/45) See our tentative [roadmap here](https://github.com/jupyter/jupyter_server/issues/127). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/README.md new/jupyter_server-2.7.2/README.md --- old/jupyter_server-2.6.0/README.md 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/README.md 2020-02-02 01:00:00.000000000 +0100 @@ -48,7 +48,7 @@ - When: Thursdays [8:00am, Pacific time](https://www.thetimezoneconverter.com/?t=8%3A00%20am&tz=San%20Francisco&) - Where: [Jovyan Zoom](https://zoom.us/my/jovyan?pwd=c0JZTHlNdS9Sek9vdzR3aTJ4SzFTQT09) -- What: [Meeting notes](https://github.com/jupyter-server/team-compass/issues/4) +- What: [Meeting notes](https://github.com/jupyter-server/team-compass/issues/45) See our tentative [roadmap here](https://github.com/jupyter/jupyter_server/issues/127). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/docs/source/developers/extensions.rst new/jupyter_server-2.7.2/docs/source/developers/extensions.rst --- old/jupyter_server-2.6.0/docs/source/developers/extensions.rst 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/docs/source/developers/extensions.rst 2020-02-02 01:00:00.000000000 +0100 @@ -580,4 +580,4 @@ ) -.. _`classic Notebook Server`: https://jupyter-notebook.readthedocs.io/en/stable/extending/handlers.html +.. _`classic Notebook Server`: https://jupyter-notebook.readthedocs.io/en/v6.5.4/extending/handlers.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/docs/source/operators/public-server.rst new/jupyter_server-2.7.2/docs/source/operators/public-server.rst --- old/jupyter_server-2.6.0/docs/source/operators/public-server.rst 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/docs/source/operators/public-server.rst 2020-02-02 01:00:00.000000000 +0100 @@ -37,7 +37,7 @@ .. _ZeroMQ: https://zeromq.org/ -.. _Tornado: with Found to http://www.tornadoweb.org/en/stable/ +.. _Tornado: http://www.tornadoweb.org/en/stable/ .. _JupyterHub: https://jupyterhub.readthedocs.io/en/latest/ @@ -111,7 +111,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can prepare a hashed password manually, using the function -:func:`notebook.auth.security.passwd`: +:func:`jupyter_server.auth.passwd`: .. code-block:: python @@ -123,7 +123,7 @@ .. caution:: - :func:`~notebook.auth.security.passwd` when called with no arguments + :func:`~jupyter_server.auth.passwd` when called with no arguments will prompt you to enter and verify your password such as in the above code snippet. Although the function can also be passed a string as an argument such as ``passwd('mypassword')``, please @@ -328,19 +328,6 @@ } } -When embedding the notebook in a website using an iframe, -consider putting the notebook in single-tab mode. -Since the notebook opens some links in new tabs by default, -single-tab mode keeps the notebook from opening additional tabs. -Adding the following to :file:`~/.jupyter/custom/custom.js` will enable -single-tab mode: - -.. code-block:: javascript - - define(['base/js/namespace'], function(Jupyter){ - Jupyter._target = '_self'; - }); - Using a gateway server for kernel management -------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/_version.py new/jupyter_server-2.7.2/jupyter_server/_version.py --- old/jupyter_server-2.6.0/jupyter_server/_version.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/_version.py 2020-02-02 01:00:00.000000000 +0100 @@ -6,7 +6,7 @@ from typing import List # Version string must appear intact for automatic versioning -__version__ = "2.6.0" +__version__ = "2.7.2" # Build up version_info tuple for backwards compatibility pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/auth/login.py new/jupyter_server-2.7.2/jupyter_server/auth/login.py --- old/jupyter_server-2.6.0/jupyter_server/auth/login.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/auth/login.py 2020-02-02 01:00:00.000000000 +0100 @@ -41,12 +41,25 @@ # \ is not valid in urls, but some browsers treat it as / # instead of %5C, causing `\\` to behave as `//` url = url.replace("\\", "%5C") + # urllib and browsers interpret extra '/' in the scheme separator (`scheme:///host/path`) + # differently. + # urllib gives scheme=scheme, netloc='', path='/host/path', while + # browsers get scheme=scheme, netloc='host', path='/path' + # so make sure ':///*' collapses to '://' by splitting and stripping any additional leading slash + # don't allow any kind of `:/` shenanigans by splitting on ':' only + # and replacing `:/*` with exactly `://` + if ":" in url: + scheme, _, rest = url.partition(":") + url = f"{scheme}://{rest.lstrip('/')}" parsed = urlparse(url) - if parsed.netloc or not (parsed.path + "/").startswith(self.base_url): + # full url may be `//host/path` (empty scheme == same scheme as request) + # or `https://host/path` + # or even `https:///host/path` (invalid, but accepted and ambiguously interpreted) + if (parsed.scheme or parsed.netloc) or not (parsed.path + "/").startswith(self.base_url): # require that next_url be absolute path within our path allow = False # OR pass our cross-origin check - if parsed.netloc: + if parsed.scheme or parsed.netloc: # if full URL, run our cross-origin check: origin = f"{parsed.scheme}://{parsed.netloc}" origin = origin.lower() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/base/handlers.py new/jupyter_server-2.7.2/jupyter_server/base/handlers.py --- old/jupyter_server-2.6.0/jupyter_server/base/handlers.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/base/handlers.py 2020-02-02 01:00:00.000000000 +0100 @@ -771,7 +771,7 @@ # record activity of authenticated requests if ( self._track_activity - and getattr(self, "_user_cache", None) + and getattr(self, "_jupyter_current_user", None) and self.get_argument("no_track_activity", None) is None ): self.settings["api_last_activity"] = utcnow() @@ -855,6 +855,7 @@ @authorized def get(self, path, **kwargs): """Get a file by path.""" + self.check_xsrf_cookie() if os.path.splitext(path)[1] == ".ipynb" or self.get_argument("download", None): name = path.rsplit("/", 1)[-1] self.set_attachment_header(name) @@ -1016,6 +1017,8 @@ class APIVersionHandler(APIHandler): """An API handler for the server version.""" + _track_activity = False + def get(self): """Get the server version info.""" # not authenticated, so give as few info as possible diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/event_schemas/kernel_actions/v1.yaml new/jupyter_server-2.7.2/jupyter_server/event_schemas/kernel_actions/v1.yaml --- old/jupyter_server-2.6.0/jupyter_server/event_schemas/kernel_actions/v1.yaml 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/event_schemas/kernel_actions/v1.yaml 2020-02-02 01:00:00.000000000 +0100 @@ -7,7 +7,6 @@ type: object required: - action - - kernel_id - msg properties: action: @@ -39,7 +38,7 @@ description: | Kernel id. - This is a required field. + This is a required field for all actions and statuses except action start with status error. kernel_name: type: string description: | @@ -69,3 +68,13 @@ type: string description: | Description of the event specified in action. +if: + not: + properties: + status: + const: error + action: + const: start +then: + required: + - kernel_id diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/gateway/gateway_client.py new/jupyter_server-2.7.2/jupyter_server/gateway/gateway_client.py --- old/jupyter_server-2.6.0/jupyter_server/gateway/gateway_client.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/gateway/gateway_client.py 2020-02-02 01:00:00.000000000 +0100 @@ -734,7 +734,7 @@ raise e logging.getLogger("ServerApp").info( f"Attempting retry ({self.retry_count}) against " - f"endpoint '{endpoint}'. Retried error: '{repr(e)}'" + f"endpoint '{endpoint}'. Retried error: '{e!r}'" ) response = await self._fetch(endpoint, **kwargs) return response @@ -767,6 +767,9 @@ rhc = RetryableHTTPClient() try: response = await rhc.fetch(endpoint, **kwargs) + GatewayClient.instance().emit( + data={STATUS_KEY: SUCCESS_STATUS, STATUS_CODE_KEY: 200, MESSAGE_KEY: "success"} + ) # Trap a set of common exceptions so that we can inform the user that their Gateway url is incorrect # or the server is not running. # NOTE: We do this here since this handler is called during the server's startup and subsequent refreshes @@ -808,6 +811,15 @@ f"The Gateway server specified in the gateway_url '{GatewayClient.instance().url}' doesn't " f"appear to be valid. Ensure gateway url is valid and the Gateway instance is running.", ) from e + except Exception as e: + GatewayClient.instance().emit( + data={STATUS_KEY: ERROR_STATUS, STATUS_CODE_KEY: 505, MESSAGE_KEY: str(e)} + ) + logging.getLogger("ServerApp").error( + f"Exception while trying to launch kernel via Gateway URL {GatewayClient.instance().url} , {e}", + e, + ) + raise e if GatewayClient.instance().accept_cookies: # Update cookies on GatewayClient from server if configured. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/serverapp.py new/jupyter_server-2.7.2/jupyter_server/serverapp.py --- old/jupyter_server-2.6.0/jupyter_server/serverapp.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/serverapp.py 2020-02-02 01:00:00.000000000 +0100 @@ -1229,7 +1229,7 @@ # if blank, self.ip was configured to "*" meaning bind to all interfaces, # see _valdate_ip - if self.ip == "": # noqa + if self.ip == "": return True try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/services/api/api.yaml new/jupyter_server-2.7.2/jupyter_server/services/api/api.yaml --- old/jupyter_server-2.6.0/jupyter_server/services/api/api.yaml 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/services/api/api.yaml 2020-02-02 01:00:00.000000000 +0100 @@ -63,6 +63,22 @@ type: string paths: + /api/: + get: + summary: Get the Jupyter Server version + description: | + This endpoint returns only the Jupyter Server version. + It does not require any authentication. + responses: + 200: + description: Jupyter Server version information + schema: + type: object + properties: + version: + type: string + description: The Jupyter Server version number as a string. + /api/contents/{path}: parameters: - $ref: "#/parameters/path" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/services/contents/filemanager.py new/jupyter_server-2.7.2/jupyter_server/services/contents/filemanager.py --- old/jupyter_server-2.6.0/jupyter_server/services/contents/filemanager.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/services/contents/filemanager.py 2020-02-02 01:00:00.000000000 +0100 @@ -513,17 +513,6 @@ if not self.exists(path): raise web.HTTPError(404, four_o_four) - def _check_trash(os_path): - if sys.platform in {"win32", "darwin"}: - return True - - # It's a bit more nuanced than this, but until we can better - # distinguish errors from send2trash, assume that we can only trash - # files on the same partition as the home directory. - file_dev = os.stat(os_path).st_dev - home_dev = os.stat(os.path.expanduser("~")).st_dev - return file_dev == home_dev - def is_non_empty_dir(os_path): if os.path.isdir(os_path): # A directory containing only leftover checkpoints is @@ -539,20 +528,15 @@ # send2trash can really delete files on Windows, so disallow # deleting non-empty files. See Github issue 3631. raise web.HTTPError(400, "Directory %s not empty" % os_path) - if _check_trash(os_path): - # Looking at the code in send2trash, I don't think the errors it - # raises let us distinguish permission errors from other errors in - # code. So for now, the "look before you leap" approach is used. - if not self.is_writable(path): - raise web.HTTPError(403, "Permission denied: %s" % path) - self.log.debug("Sending %s to trash", os_path) + # send2trash now supports deleting directories. see #1290 + if not self.is_writable(path): + raise web.HTTPError(403, "Permission denied: %s" % path) from None + self.log.debug("Sending %s to trash", os_path) + try: send2trash(os_path) - return - else: - self.log.warning( - "Skipping trash for %s, on different device to home directory", - os_path, - ) + except OSError as e: + raise web.HTTPError(400, "send2trash failed: %s" % e) from e + return if os.path.isdir(os_path): # Don't permanently delete non-empty directories. @@ -967,17 +951,6 @@ if not os.path.exists(os_path): raise web.HTTPError(404, "File or directory does not exist: %s" % os_path) - async def _check_trash(os_path): - if sys.platform in {"win32", "darwin"}: - return True - - # It's a bit more nuanced than this, but until we can better - # distinguish errors from send2trash, assume that we can only trash - # files on the same partition as the home directory. - file_dev = (await run_sync(os.stat, os_path)).st_dev - home_dev = (await run_sync(os.stat, os.path.expanduser("~"))).st_dev - return file_dev == home_dev - async def is_non_empty_dir(os_path): if os.path.isdir(os_path): # A directory containing only leftover checkpoints is @@ -998,20 +971,15 @@ # send2trash can really delete files on Windows, so disallow # deleting non-empty files. See Github issue 3631. raise web.HTTPError(400, "Directory %s not empty" % os_path) - if await _check_trash(os_path): - # Looking at the code in send2trash, I don't think the errors it - # raises let us distinguish permission errors from other errors in - # code. So for now, the "look before you leap" approach is used. - if not self.is_writable(path): - raise web.HTTPError(403, "Permission denied: %s" % path) - self.log.debug("Sending %s to trash", os_path) + # send2trash now supports deleting directories. see #1290 + if not self.is_writable(path): + raise web.HTTPError(403, "Permission denied: %s" % path) from None + self.log.debug("Sending %s to trash", os_path) + try: send2trash(os_path) - return - else: - self.log.warning( - "Skipping trash for %s, on different device to home directory", - os_path, - ) + except OSError as e: + raise web.HTTPError(400, "send2trash f`1ailed: %s" % e) from e + return if os.path.isdir(os_path): # Don't permanently delete non-empty directories. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/services/events/handlers.py new/jupyter_server-2.7.2/jupyter_server/services/events/handlers.py --- old/jupyter_server-2.6.0/jupyter_server/services/events/handlers.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/services/events/handlers.py 2020-02-02 01:00:00.000000000 +0100 @@ -110,6 +110,8 @@ ) self.set_status(204) self.finish() + except web.HTTPError: + raise except Exception as e: raise web.HTTPError(500, str(e)) from e diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/services/kernels/connection/base.py new/jupyter_server-2.7.2/jupyter_server/services/kernels/connection/base.py --- old/jupyter_server-2.6.0/jupyter_server/services/kernels/connection/base.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/services/kernels/connection/base.py 2020-02-02 01:00:00.000000000 +0100 @@ -94,7 +94,7 @@ offsets.append(len(msg) + offsets[-1]) offset_number = len(offsets).to_bytes(8, byteorder="little") offsets = [offset.to_bytes(8, byteorder="little") for offset in offsets] - bin_msg = b"".join([offset_number, *offsets] + [channel] + msg_list) + bin_msg = b"".join([offset_number, *offsets, channel, *msg_list]) return bin_msg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/services/kernels/connection/channels.py new/jupyter_server-2.7.2/jupyter_server/services/kernels/connection/channels.py --- old/jupyter_server-2.6.0/jupyter_server/services/kernels/connection/channels.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/services/kernels/connection/channels.py 2020-02-02 01:00:00.000000000 +0100 @@ -644,7 +644,7 @@ err_msg["channel"] = "iopub" self.write_message(json.dumps(err_msg, default=json_default)) - def _limit_rate(self, channel, msg, msg_list): # noqa + def _limit_rate(self, channel, msg, msg_list): """Limit the message rate on a channel.""" if not (self.limit_rate and channel == "iopub"): return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/services/kernels/kernelmanager.py new/jupyter_server-2.7.2/jupyter_server/services/kernels/kernelmanager.py --- old/jupyter_server-2.6.0/jupyter_server/services/kernels/kernelmanager.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/services/kernels/kernelmanager.py 2020-02-02 01:00:00.000000000 +0100 @@ -738,28 +738,31 @@ # If the method succeeds, emit a success event. try: out = await method(self, *args, **kwargs) + data = { + "kernel_name": self.kernel_name, + "action": action, + "status": "success", + "msg": success_msg.format( + kernel_id=self.kernel_id, kernel_name=self.kernel_name, action=action + ), + } + if self.kernel_id: + data["kernel_id"] = self.kernel_id self.emit( schema_id="https://events.jupyter.org/jupyter_server/kernel_actions/v1", - data={ - "kernel_id": self.kernel_id, - "kernel_name": self.kernel_name, - "action": action, - "status": "success", - "msg": success_msg.format( - kernel_id=self.kernel_id, kernel_name=self.kernel_name, action=action - ), - }, + data=data, ) return out # If the method fails, emit a failed event. except Exception as err: data = { - "kernel_id": self.kernel_id, "kernel_name": self.kernel_name, "action": action, "status": "error", "msg": str(err), } + if self.kernel_id: + data["kernel_id"] = self.kernel_id # If the exception is an HTTPError (usually via a gateway request) # log the status_code and HTTPError log_message. if isinstance(err, web.HTTPError): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/services/kernels/websocket.py new/jupyter_server-2.7.2/jupyter_server/services/kernels/websocket.py --- old/jupyter_server-2.6.0/jupyter_server/services/kernels/websocket.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/services/kernels/websocket.py 2020-02-02 01:00:00.000000000 +0100 @@ -87,7 +87,7 @@ preferred_protocol = self.connection.kernel_ws_protocol if preferred_protocol is None: preferred_protocol = "v1.kernel.websocket.jupyter.org" - elif preferred_protocol == "": # noqa + elif preferred_protocol == "": preferred_protocol = None selected_subprotocol = preferred_protocol if preferred_protocol in subprotocols else None # None is the default, "legacy" protocol diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/jupyter_server/utils.py new/jupyter_server-2.7.2/jupyter_server/utils.py --- old/jupyter_server-2.6.0/jupyter_server/utils.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/jupyter_server/utils.py 2020-02-02 01:00:00.000000000 +0100 @@ -57,7 +57,7 @@ """Convert a local file path to a URL""" pieces = [quote(p) for p in path.split(os.sep)] # preserve trailing / - if pieces[-1] == "": # noqa + if pieces[-1] == "": pieces[-1] = "/" url = url_path_join(*pieces) return url @@ -121,7 +121,7 @@ root must be a filesystem path already. """ parts = str(path).strip("/").split("/") - parts = [p for p in parts if p != ""] # noqa # remove duplicate splits + parts = [p for p in parts if p != ""] # remove duplicate splits path_ = os.path.join(root, *parts) return os.path.normpath(path_) @@ -135,7 +135,7 @@ if os_path.startswith(root): os_path = os_path[len(root) :] parts = os_path.strip(os.path.sep).split(os.path.sep) - parts = [p for p in parts if p != ""] # noqa # remove duplicate splits + parts = [p for p in parts if p != ""] # remove duplicate splits path = "/".join(parts) return ApiPath(path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/pyproject.toml new/jupyter_server-2.7.2/pyproject.toml --- old/jupyter_server-2.6.0/pyproject.toml 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/pyproject.toml 2020-02-02 01:00:00.000000000 +0100 @@ -39,7 +39,7 @@ "prometheus_client", "pywinpty;os_name=='nt'", "pyzmq>=24", - "Send2Trash", + "Send2Trash>=1.8.2", "terminado>=0.8.3", "tornado>=6.2.0", "traitlets>=5.6.0", @@ -63,7 +63,8 @@ "pytest-jupyter[server]>=0.4", "pytest>=7.0", "requests", - "pre-commit" + "pre-commit", + 'flaky' ] docs = [ "ipykernel", @@ -120,7 +121,7 @@ dependencies = [ "black[jupyter]==23.3.0", "mdformat>0.7", - "ruff==0.0.263", + "ruff==0.0.276", ] [tool.hatch.envs.lint.scripts] style = [ @@ -221,6 +222,8 @@ "PLR0913", # PLR0912 Too many branches "PLR0912", + # RUF012 Mutable class attributes should be annotated with `typing.ClassVar` + "RUF012", ] unfixable = [ # Don't touch print statements @@ -263,7 +266,7 @@ "tests/" ] timeout = 100 -# Restore this setting to debug failures +# Restore this setting to debug failures. timeout_method = "thread" filterwarnings = [ "error", @@ -272,6 +275,14 @@ "always:unclosed <socket.socket:ResourceWarning", "module:Jupyter is migrating its paths to use standard platformdirs:DeprecationWarning", "ignore:jupyter_server.base.zmqhandlers module is deprecated in Jupyter Server 2.0:DeprecationWarning", + "ignore:datetime.utcfromtimestamp:DeprecationWarning", + "ignore:datetime.utcnow:DeprecationWarning", + # from nbformat + "ignore:Importing ErrorTree directly from the jsonschema package:DeprecationWarning", + # From jupyter_events + "module:jsonschema.RefResolver is deprecated as of:DeprecationWarning", + # ignore pytest warnings. + "ignore:::_pytest", ] [tool.coverage.report] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/tests/auth/test_login.py new/jupyter_server-2.7.2/tests/auth/test_login.py --- old/jupyter_server-2.6.0/tests/auth/test_login.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/tests/auth/test_login.py 2020-02-02 01:00:00.000000000 +0100 @@ -92,6 +92,7 @@ "//host{base_url}tree", "https://google.com", "/absolute/not/base_url", + "https:///a%40b/extra/slash", ), ) async def test_next_bad(login, jp_base_url, bad_next): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/tests/services/contents/test_manager.py new/jupyter_server-2.7.2/tests/services/contents/test_manager.py --- old/jupyter_server-2.6.0/tests/services/contents/test_manager.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/tests/services/contents/test_manager.py 2020-02-02 01:00:00.000000000 +0100 @@ -448,19 +448,19 @@ with pytest.raises(HTTPError) as e: await ensure_async(cm.get("..")) - expected_http_error(e, 404) + assert expected_http_error(e, 404) with pytest.raises(HTTPError) as e: await ensure_async(cm.get("foo/../../../bar")) - expected_http_error(e, 404) + assert expected_http_error(e, 404) with pytest.raises(HTTPError) as e: await ensure_async(cm.delete("../foo")) - expected_http_error(e, 404) + assert expected_http_error(e, 404) with pytest.raises(HTTPError) as e: await ensure_async(cm.rename("../foo", "../bar")) - expected_http_error(e, 404) + assert expected_http_error(e, 404) with pytest.raises(HTTPError) as e: await ensure_async( @@ -473,7 +473,7 @@ path="../foo", ) ) - expected_http_error(e, 404) + assert expected_http_error(e, 404) async def test_new_untitled(jp_contents_manager): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/tests/services/events/test_api.py new/jupyter_server-2.7.2/tests/services/events/test_api.py --- old/jupyter_server-2.6.0/tests/services/events/test_api.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/tests/services/events/test_api.py 2020-02-02 01:00:00.000000000 +0100 @@ -123,7 +123,7 @@ with pytest.raises(tornado.httpclient.HTTPClientError) as e: await jp_fetch("api", "events", method="POST", body=payload) - expected_http_error(e, 400) + assert expected_http_error(e, 400) payload_7 = """\ @@ -152,4 +152,4 @@ with pytest.raises(tornado.httpclient.HTTPClientError) as e: await jp_fetch("api", "events", method="POST", body=payload) - expected_http_error(e, 500) + assert expected_http_error(e, 500) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_server-2.6.0/tests/test_terminal.py new/jupyter_server-2.7.2/tests/test_terminal.py --- old/jupyter_server-2.6.0/tests/test_terminal.py 2020-02-02 01:00:00.000000000 +0100 +++ new/jupyter_server-2.7.2/tests/test_terminal.py 2020-02-02 01:00:00.000000000 +0100 @@ -7,6 +7,7 @@ import warnings import pytest +from flaky import flaky # type:ignore from tornado.httpclient import HTTPClientError from traitlets.config import Config @@ -229,6 +230,7 @@ assert non_existing_path not in message_stdout +@flaky def test_culling_config(jp_server_config, jp_configurable_serverapp): app = jp_configurable_serverapp() terminal_mgr_config = app.config.ServerApp.TerminalManager @@ -240,6 +242,7 @@ assert terminal_mgr_settings.cull_interval == CULL_INTERVAL +@flaky async def test_culling(jp_server_config, jp_fetch): # POST request resp = await jp_fetch(