mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-17 15:03:02 +00:00
@@ -1625,10 +1625,7 @@ class JupyterHub(Application):
|
||||
if not self.io_loop:
|
||||
return
|
||||
if self.http_server:
|
||||
if self.io_loop._running:
|
||||
self.io_loop.add_callback(self.http_server.stop)
|
||||
else:
|
||||
self.http_server.stop()
|
||||
self.http_server.stop()
|
||||
self.io_loop.add_callback(self.io_loop.stop)
|
||||
|
||||
@gen.coroutine
|
||||
|
@@ -778,7 +778,14 @@ class HubAuthenticated(object):
|
||||
except UserNotAllowed as e:
|
||||
# cache None, in case get_user is called again while processing the error
|
||||
self._hub_auth_user_cache = None
|
||||
raise HTTPError(403, "{kind} {name} is not allowed.".format(**e.model))
|
||||
# Override redirect so if/when tornado @web.authenticated
|
||||
# tries to redirect to login URL, 403 will be raised instead.
|
||||
# This is not the best, but avoids problems that can be caused
|
||||
# when get_current_user is allowed to raise.
|
||||
def raise_on_redirect(*args, **kwargs):
|
||||
raise HTTPError(403, "{kind} {name} is not allowed.".format(**user_model))
|
||||
self.redirect = raise_on_redirect
|
||||
return
|
||||
except Exception:
|
||||
self._hub_auth_user_cache = None
|
||||
raise
|
||||
|
@@ -1,5 +1,6 @@
|
||||
"""mock utilities for testing"""
|
||||
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import os
|
||||
import sys
|
||||
from tempfile import NamedTemporaryFile
|
||||
@@ -202,11 +203,11 @@ class MockHub(JupyterHub):
|
||||
@default('authenticator_class')
|
||||
def _authenticator_class_default(self):
|
||||
return MockPAMAuthenticator
|
||||
|
||||
|
||||
@default('spawner_class')
|
||||
def _spawner_class_default(self):
|
||||
return MockSpawner
|
||||
|
||||
|
||||
def init_signal(self):
|
||||
pass
|
||||
|
||||
@@ -229,11 +230,25 @@ class MockHub(JupyterHub):
|
||||
|
||||
def stop(self):
|
||||
super().stop()
|
||||
IOLoop().run_sync(self.cleanup)
|
||||
|
||||
# run cleanup in a background thread
|
||||
# to avoid multiple eventloops in the same thread errors from asyncio
|
||||
|
||||
def cleanup():
|
||||
loop = IOLoop.current()
|
||||
loop.run_sync(self.cleanup)
|
||||
loop.close()
|
||||
|
||||
pool = ThreadPoolExecutor(1)
|
||||
f = pool.submit(cleanup)
|
||||
# wait for cleanup to finish
|
||||
f.result()
|
||||
pool.shutdown()
|
||||
|
||||
# ignore the call that will fire in atexit
|
||||
self.cleanup = lambda : None
|
||||
self.db_file.close()
|
||||
|
||||
|
||||
@gen.coroutine
|
||||
def login_user(self, name):
|
||||
"""Login a user by name, returning her cookies."""
|
||||
|
@@ -1,6 +1,6 @@
|
||||
alembic
|
||||
traitlets>=4.3.2
|
||||
tornado>=4.1,<5.0
|
||||
tornado>=4.1
|
||||
jinja2
|
||||
pamela
|
||||
python-oauth2>=1.0
|
||||
|
Reference in New Issue
Block a user