Repository: jupyterhub/jupyterhub

Issue:
Added prehandle_logout
This pull request is to allow subclasses the ability to perform some action before starting the logout process. Use cases include: calling `self.current_user` right before logout. 

For example, app may need to perform some action with the user object (like removing information from a cache) before its unset via `self.default_logout()`. `self.current_user` is not exposed to the override-able method `self.handle_logout()` if `self.shutdown_on_logout` is specified.



Discussion:
Thanks for submitting your first pull request! You are awesome! :hugs:
<br>If you haven't done so already, check out [Jupyter's Code of Conduct](https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md). Also, please make sure you followed the pull request template, as this will help us review your contribution more quickly.
![welcome](https://raw.githubusercontent.com/jupyterhub/.github/master/images/welcome.jpg)
You can meet the other [Jovyans](https://jupyter.readthedocs.io/en/latest/community/content-community.html?highlight=jovyan#what-is-a-jovyan) by joining our [Discourse forum](http://discourse.jupyter.org/). There is also a intro thread there where you can stop by and say Hi! :wave:
<br>Welcome to the Jupyter community! :tada:

Thanks for the PR! Here's a question: if we fixed `self.current_user` so it's available in `handle_logout()`, would that solve your problem? If so, I might go for that rather than defining a new hook.
@minrk Thanks for the feedback and I think that would solve the problem. How that would be implemented since `default_handle_logout()` sets `self.current_user` to `None`?

Resolving patch:
diff --git a/jupyterhub/handlers/base.py b/jupyterhub/handlers/base.py
--- a/jupyterhub/handlers/base.py
+++ b/jupyterhub/handlers/base.py
@@ -542,8 +542,6 @@ def clear_login_cookie(self, name=None):
             '_xsrf',
             **clear_xsrf_cookie_kwargs,
         )
-        # Reset _jupyterhub_user
-        self._jupyterhub_user = None
 
     def _set_cookie(self, key, value, encrypted=True, **overrides):
         """Setting any cookie should go through here
diff --git a/jupyterhub/handlers/login.py b/jupyterhub/handlers/login.py
--- a/jupyterhub/handlers/login.py
+++ b/jupyterhub/handlers/login.py
@@ -84,6 +84,9 @@ async def get(self):
         """
         await self.default_handle_logout()
         await self.handle_logout()
+        # clear jupyterhub user before rendering logout page
+        # ensures the login button is shown instead of logout
+        self._jupyterhub_user = None
         await self.render_logout_page()
 
 


Test patch:
diff --git a/jupyterhub/tests/test_pages.py b/jupyterhub/tests/test_pages.py
--- a/jupyterhub/tests/test_pages.py
+++ b/jupyterhub/tests/test_pages.py
@@ -942,6 +942,14 @@ async def test_auto_login_logout(app):
     logout_url = public_host(app) + app.tornado_settings['logout_url']
     assert r.url == logout_url
     assert r.cookies == {}
+    # don't include logged-out user in page:
+    try:
+        idx = r.text.index(name)
+    except ValueError:
+        # not found, good!
+        pass
+    else:
+        assert name not in r.text[idx - 100 : idx + 100]
 
 
 async def test_logout(app):