mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-03 20:28:12 +08:00
auth: logging out should keep the user on the same page (#1877)
previous behavior is that logout would redirect to the index page.
This commit is contained in:
@@ -114,6 +114,7 @@ class AuthTypeOAuth(AuthTypeClientBase):
|
||||
parse = urlparse(self.api_base_url)
|
||||
app.add_url_rule(f"{parse.path}/login", "login", self.login, methods=["GET"])
|
||||
app.add_url_rule(f"{parse.path}/logout", "logout", self.logout, methods=["GET"])
|
||||
app.add_url_rule(f"{parse.path}/logout_redirect", "logout_redirect", self.logout_redirect, methods=["GET"])
|
||||
app.add_url_rule(f"{parse.path}/oauth2/callback", "callback", self.callback, methods=["GET"])
|
||||
|
||||
def complete_setup(self, flask_app):
|
||||
@@ -166,12 +167,29 @@ class AuthTypeOAuth(AuthTypeClientBase):
|
||||
return response
|
||||
|
||||
def logout(self):
|
||||
"""
|
||||
We would like for the user to remain on the same dataset after logout. oauth requires that
|
||||
the redirect `returnTo` path be whitelisted by the oauth server, therefore a level of
|
||||
indirection is used. We first redirect to a single path "logout_redirect", and logout_redirect
|
||||
will redirect the user's browser back to the current page.
|
||||
"""
|
||||
self.remove_tokens()
|
||||
params = {"returnTo": self.web_base_url, "client_id": self.client_id}
|
||||
redirect_path = request.args.get("dataset", "")
|
||||
redirect_to = f"{self.web_base_url}/{redirect_path}"
|
||||
session["oauth_logout_redirect"] = redirect_to
|
||||
|
||||
return_to = f"{self.api_base_url}/logout_redirect"
|
||||
params = {"returnTo": return_to, "client_id": self.client_id}
|
||||
response = redirect(self.client.api_base_url + "/v2/logout?" + urlencode(params))
|
||||
self.update_response(response)
|
||||
return response
|
||||
|
||||
def logout_redirect(self):
|
||||
oauth_logout_redirect = session.pop("oauth_logout_redirect", "/")
|
||||
response = redirect(oauth_logout_redirect)
|
||||
self.update_response(response)
|
||||
return response
|
||||
|
||||
def callback(self):
|
||||
data = self.client.authorize_access_token()
|
||||
tokens = Tokens(
|
||||
@@ -253,7 +271,10 @@ class AuthTypeOAuth(AuthTypeClientBase):
|
||||
|
||||
def get_logout_url(self, data_adaptor):
|
||||
"""Return the url for the logout route"""
|
||||
return f"{self.api_base_url}/logout"
|
||||
if data_adaptor and current_app.app_config.is_multi_dataset():
|
||||
return f"{self.api_base_url}/logout?dataset={data_adaptor.uri_path}/"
|
||||
else:
|
||||
return f"{self.api_base_url}/logout"
|
||||
|
||||
def check_jwt_payload(self, id_token):
|
||||
try:
|
||||
|
||||
@@ -112,7 +112,7 @@ class AuthTest(unittest.TestCase):
|
||||
logout_uri = config["config"]["authentication"]["logout"]
|
||||
|
||||
self.assertEqual(login_uri, f"{server}/login?dataset=d/pbmc3k.cxg/")
|
||||
self.assertEqual(logout_uri, f"{server}/logout")
|
||||
self.assertEqual(logout_uri, f"{server}/logout?dataset=d/pbmc3k.cxg/")
|
||||
|
||||
r = session.get(login_uri)
|
||||
# check that the login redirect worked
|
||||
@@ -151,7 +151,7 @@ class AuthTest(unittest.TestCase):
|
||||
r = session.get(logout_uri)
|
||||
# check that the logout redirect worked
|
||||
self.assertEqual(r.history[0].status_code, 302)
|
||||
self.assertEqual(r.url, f"{server}")
|
||||
self.assertEqual(r.url, f"{server}/d/pbmc3k.cxg/")
|
||||
config = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/config").json()
|
||||
userinfo = session.get(f"{server}/d/pbmc3k.cxg/api/v0.2/userinfo").json()
|
||||
self.assertFalse(userinfo["userinfo"]["is_authenticated"])
|
||||
|
||||
Reference in New Issue
Block a user