Skip to content

Commit

Permalink
login/logout of magpie as well (#17)
Browse files Browse the repository at this point in the history
This unifies the login/logout capabilities of jupyterhub and magpie so
that when logging in to jupyterhub, the user is simultaneously logged in
to magpie. Similarly, when logging out of jupyterhub, the user is also
logged out of magpie.

This change requires that one additional parameter be set:
- `c.MagpieAuthenticator.public_fqdn` which is the publicly available
FQDN where magpie is running (this is required when setting the domain
on cookies)

Note:
- the `@gen.coroutine` decorator is replaced with the (now recommended)
`async` syntax

This change was first proposed here:
bird-house/birdhouse-deploy#358
  • Loading branch information
mishaschwartz authored Jul 31, 2023
2 parents bdd9c48 + 2816b84 commit f0d6f06
Showing 1 changed file with 35 additions and 6 deletions.
41 changes: 35 additions & 6 deletions jupyterhub_magpie_authenticator/jupyterhub_magpie_authenticator.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
from traitlets import Unicode
from jupyterhub.auth import Authenticator
from tornado import gen
from jupyterhub.handlers.login import LogoutHandler
import requests


class MagpieLogoutHandler(LogoutHandler):
"""
Logout Handler that also logs the user out of magpie when logging out of jupyterhub.
"""

async def handle_logout(self):
cookies = {key: morsel.coded_value for key, morsel in self.request.cookies.items()}
signout_url = self.authenticator.magpie_url.rstrip("/") + "/signout"
response = requests.get(signout_url, cookies=cookies, headers={"Host": self.authenticator.public_fqdn})
if response.ok and 'Set-Cookie' in response.headers:
self.set_header("Set-Cookie", response.headers["Set-Cookie"])


class MagpieAuthenticator(Authenticator):
"""Authenticate to JupyterHub using Magpie.
To use this authenticator, set the following parameters in the `jupyterhub_config.py` file:
- c.JupyterHub.authenticator_class = 'jupyterhub_magpie_authenticator.MagpieAuthenticator'
- c.MagpieAuthenticator.magpie_url = "https://www.example.com/magpie"
- c.MagpieAuthenticator.magpie_url = "magpie:2000" # url where magpie is running (does not need to be public)
- c.MagpieAuthenticator.public_fqdn = "www.example.com" # fqdn of server where magpie is running
"""
default_provider = "ziggurat"
magpie_url = Unicode(
default_value="https://www.example.com/magpie",
config=True,
help="Magpie endpoint to signin to"
)
public_fqdn = Unicode(
config=True,
help="Public fully qualified domain name. Used to set the magpie login cookie."
)

def get_handlers(self, app):
return [
('/logout', MagpieLogoutHandler)
]

@gen.coroutine
def authenticate(self, handler, data):
async def authenticate(self, handler, data):
signin_url = self.magpie_url.rstrip('/') + '/signin'

post_data = {
"user_name": data["username"],
"password": data["password"],
"provider_name": self.default_provider,
}
response = requests.post(signin_url, data=post_data)

if response.ok:
for cookie in response.cookies:
handler.set_cookie(name=cookie.name,
value=cookie.value,
domain=self.public_fqdn,
expires=cookie.expires,
path=cookie.path,
secure=cookie.secure)
return data['username']

0 comments on commit f0d6f06

Please sign in to comment.