Skip to content

Commit

Permalink
Merge pull request #146 from lsst-sqre/tickets/DM-34835
Browse files Browse the repository at this point in the history
Add GafaelfawrLogoutHandler
  • Loading branch information
athornton authored May 19, 2022
2 parents 900dd68 + 49d3d52 commit 4e205d1
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 18 deletions.
2 changes: 1 addition & 1 deletion requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with python 3.10
# This file is autogenerated by pip-compile with python 3.8
# To update, run:
#
# pip-compile --generate-hashes --output-file=requirements/dev.txt requirements/dev.in
Expand Down
33 changes: 20 additions & 13 deletions requirements/main.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with python 3.10
# This file is autogenerated by pip-compile with python 3.8
# To update, run:
#
# pip-compile --generate-hashes --output-file=requirements/main.txt requirements/main.in
Expand Down Expand Up @@ -137,9 +137,9 @@ cchardet==2.1.7 \
--hash=sha256:f86e0566cb61dc4397297696a4a1b30f6391b50bc52b4f073507a48466b6255a \
--hash=sha256:fdac1e4366d0579fff056d1280b8dc6348be964fda8ebb627c0269e097ab37fa
# via -r requirements/main.in
certifi==2021.10.8 \
--hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \
--hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569
certifi==2022.5.18 \
--hash=sha256:6ae10321df3e464305a46e997da41ea56c1d311fb9ff1dd4e04d6f14653ec63a \
--hash=sha256:8d15a5a7fde18536a249c49e07e8e462b8fc13de21b3c80e8a68315dfa227c99
# via
# kubernetes-asyncio
# requests
Expand Down Expand Up @@ -368,11 +368,16 @@ idna==3.3 \
importlib-metadata==4.11.3 \
--hash=sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6 \
--hash=sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539
# via -r requirements/main.in
# via
# -r requirements/main.in
# alembic
importlib-resources==5.7.1 \
--hash=sha256:b6062987dfc51f0fcb809187cffbd60f35df7acb4589091f154214af6d0d49d3 \
--hash=sha256:e447dc01619b1e951286f3929be820029d48c75eb25d265c28b92a16548212b8
# via -r requirements/main.in
# via
# -r requirements/main.in
# alembic
# jsonschema
inflect==5.6.0 \
--hash=sha256:967d6db69932bac9f1977b8f2dd131a59147f4b56134cfc74a3f44e5adb65223 \
--hash=sha256:a0612e7bba1028bb7efa121bf8f012aeda9355252d01b257057fa2a8f5859cef
Expand Down Expand Up @@ -402,9 +407,9 @@ jupyterhub-idle-culler==1.2.1 \
--hash=sha256:c84e45a51932a34bd95c08b3b6e8330fb0ee3391fa4d0f1ac0d4458a40492fd9 \
--hash=sha256:d80822982d2590cb876d01849cee028943fdbdcc991c0f02fce45af3f40dd415
# via -r requirements/main.in
jupyterhub-kubespawner==4.0.0 \
--hash=sha256:09d6005aa722a99f0a7e3127c6029465e5603451d4c0077fcef32834dba2892a \
--hash=sha256:d06a6f90711c6748fc48f681994f04f1240d23117c341b1f3ac9897fd9ef3da2
jupyterhub-kubespawner==4.1.0 \
--hash=sha256:77c669e00586529534aefe6ae8e6a39588b8ca3d58d21f1be4742b47062d78cf \
--hash=sha256:7fbcdf5ca7bd36bbe64c5ac5e76bdf76faa609949652ec6dc5b2f527542b55a9
# via -r requirements/main.in
kubernetes-asyncio==22.6.4 \
--hash=sha256:a552211c72c7452999d7bf3b09326a0557899d749b001743aa63f7fc3fcbcb2c \
Expand Down Expand Up @@ -805,9 +810,9 @@ tornado==6.1 \
# -r requirements/main.in
# jupyterhub
# jupyterhub-idle-culler
traitlets==5.2.0 \
--hash=sha256:60474f39bf1d39a11e0233090b99af3acee93bbc2281777e61dd8c87da8a0014 \
--hash=sha256:9dd4025123fbe018a2092b2ad6984792f53ea3362c698f37473258b1fa97b0bc
traitlets==5.2.1.post0 \
--hash=sha256:70815ecb20ec619d1af28910ade523383be13754283aef90528eb3d47b77c5db \
--hash=sha256:f44b708d33d98b0addb40c29d148a761f44af740603a8fd0e2f8b5b27cf0f087
# via
# jupyter-telemetry
# jupyterhub
Expand Down Expand Up @@ -895,7 +900,9 @@ yarl==1.7.2 \
zipp==3.8.0 \
--hash=sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad \
--hash=sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099
# via importlib-metadata
# via
# importlib-metadata
# importlib-resources

# WARNING: The following packages were not pinned, but pip requires them to be
# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
Expand Down
25 changes: 22 additions & 3 deletions src/nublado2/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import TYPE_CHECKING

from jupyterhub.auth import Authenticator
from jupyterhub.handlers import BaseHandler
from jupyterhub.handlers import BaseHandler, LogoutHandler
from jupyterhub.utils import url_path_join
from tornado import web

Expand Down Expand Up @@ -140,8 +140,11 @@ async def authenticate(
raise NotImplementedError()

def get_handlers(self, app: JupyterHub) -> List[Route]:
"""Register the header-only login handler."""
return [("/gafaelfawr/login", GafaelfawrLoginHandler)]
"""Register the header-only login and the logout handlers."""
return [
("/gafaelfawr/login", GafaelfawrLoginHandler),
("/logout", GafaelfawrLogoutHandler),
]

def login_url(self, base_url: str) -> str:
"""Override the login URL.
Expand Down Expand Up @@ -178,6 +181,22 @@ async def refresh_user(
return await _build_auth_info(handler.request.headers)


class GafaelfawrLogoutHandler(LogoutHandler):
"""Logout handler for Gafaelfawr authentication.
A logout should always stop all running servers, and then redirect to the
RSP logout page.
"""

@property
def shutdown_on_logout(self) -> bool:
"""Unconditionally true for Gafaelfawr logout"""
return True

async def render_logout_page(self) -> None:
self.redirect("/logout", permanent=False)


class GafaelfawrLoginHandler(BaseHandler):
"""Login handler for Gafaelfawr authentication.
Expand Down
4 changes: 3 additions & 1 deletion tests/auth_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from nublado2.auth import (
GafaelfawrAuthenticator,
GafaelfawrLoginHandler,
GafaelfawrLogoutHandler,
_build_auth_info,
)

Expand All @@ -36,7 +37,8 @@ async def config_mock() -> AsyncGenerator:
def test_authenticator() -> None:
authenticator = GafaelfawrAuthenticator()
assert authenticator.get_handlers(MagicMock()) == [
("/gafaelfawr/login", GafaelfawrLoginHandler)
("/gafaelfawr/login", GafaelfawrLoginHandler),
("/logout", GafaelfawrLogoutHandler),
]
assert authenticator.login_url("/hub") == "/hub/gafaelfawr/login"

Expand Down

0 comments on commit 4e205d1

Please sign in to comment.