Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Auth0] Allow redirecting to custom URL after logout #722

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion oauthenticator/auth0.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
A JupyterHub authenticator class for use with Auth0 as an identity provider.
"""
import os
from urllib.parse import urlencode

from jupyterhub.auth import LocalAuthenticator
from traitlets import Unicode, default
Expand Down Expand Up @@ -41,6 +42,17 @@ def _auth0_domain_default(self):
"Configuring either auth0_domain or auth0_subdomain is required"
)

logout_redirect_to_url = Unicode(
config=True,
help="""
Redirect to this URL after the user is logged out.

Must be explicitly added to the "Allowed Logout URLs" in the configuration
for this Auth0 application. See https://auth0.com/docs/authenticate/login/logout/redirect-users-after-logout
for more information.
""",
)

auth0_subdomain = Unicode(
config=True,
help="""
Expand All @@ -57,7 +69,15 @@ def _auth0_subdomain_default(self):

@default("logout_redirect_url")
def _logout_redirect_url_default(self):
return f"https://{self.auth0_domain}/v2/logout"
url = f"https://{self.auth0_domain}/v2/logout"
if self.logout_redirect_to_url:
# If a redirectTo is set, we must also include the `client_id`
# Auth0 expects `client_id` to be snake cased while `redirectTo` is camel cased
params = urlencode(
{"client_id": self.client_id, "redirectTo": self.logout_redirect_to_url}
)
url = f"{url}?{params}"
return url

@default("authorize_url")
def _authorize_url_default(self):
Expand Down
16 changes: 13 additions & 3 deletions oauthenticator/tests/test_auth0.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,19 @@ async def test_auth0(
assert auth_model == None


async def test_custom_logout(monkeypatch):
@mark.parametrize(
("logout_redirect_to_url", "redirect_url"),
[
("", f"https://{AUTH0_DOMAIN}/v2/logout"),
(
"https://hub-url.com",
f"https://{AUTH0_DOMAIN}/v2/logout?client_id=&redirectTo=https%3A%2F%2Fhub-url.com",
),
],
)
async def test_custom_logout(monkeypatch, logout_redirect_to_url, redirect_url):
authenticator = Auth0OAuthenticator()
authenticator.logout_redirect_to_url = logout_redirect_to_url
logout_handler = mock_handler(OAuthLogoutHandler, authenticator=authenticator)
monkeypatch.setattr(web.RequestHandler, 'redirect', Mock())

Expand All @@ -114,8 +125,7 @@ async def test_custom_logout(monkeypatch):
# Check redirection to the custom logout url
authenticator.auth0_domain = AUTH0_DOMAIN
await logout_handler.get()
custom_logout_url = f'https://{AUTH0_DOMAIN}/v2/logout'
logout_handler.redirect.assert_called_with(custom_logout_url)
logout_handler.redirect.assert_called_with(redirect_url)


@mark.parametrize(
Expand Down