-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
login/logout of magpie as well (#17)
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
Showing
1 changed file
with
35 additions
and
6 deletions.
There are no files selected for viewing
41 changes: 35 additions & 6 deletions
41
jupyterhub_magpie_authenticator/jupyterhub_magpie_authenticator.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'] |