mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-08 10:34:10 +00:00
talk to PAM in a thread
since PAM can be slow, we don't want to block the rest of the application
This commit is contained in:
@@ -3,19 +3,22 @@
|
|||||||
# Copyright (c) IPython Development Team.
|
# Copyright (c) IPython Development Team.
|
||||||
# Distributed under the terms of the Modified BSD License.
|
# Distributed under the terms of the Modified BSD License.
|
||||||
|
|
||||||
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
import pipes
|
import pipes
|
||||||
import re
|
import re
|
||||||
from shutil import which
|
from shutil import which
|
||||||
import sys
|
import sys
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
from tornado import gen
|
|
||||||
try:
|
try:
|
||||||
import pamela
|
import pamela
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pamela = None
|
pamela = None
|
||||||
_pamela_error = e
|
_pamela_error = e
|
||||||
|
|
||||||
|
from tornado.concurrent import run_on_executor
|
||||||
|
from tornado import gen
|
||||||
|
|
||||||
from traitlets.config import LoggingConfigurable
|
from traitlets.config import LoggingConfigurable
|
||||||
from traitlets import Bool, Set, Unicode, Dict, Any, default, observe
|
from traitlets import Bool, Set, Unicode, Dict, Any, default, observe
|
||||||
|
|
||||||
@@ -520,6 +523,12 @@ class LocalAuthenticator(Authenticator):
|
|||||||
class PAMAuthenticator(LocalAuthenticator):
|
class PAMAuthenticator(LocalAuthenticator):
|
||||||
"""Authenticate local UNIX users with PAM"""
|
"""Authenticate local UNIX users with PAM"""
|
||||||
|
|
||||||
|
# run PAM in a thread, since it can be slow
|
||||||
|
executor = Any()
|
||||||
|
@default('executor')
|
||||||
|
def _default_executor(self):
|
||||||
|
return ThreadPoolExecutor(1)
|
||||||
|
|
||||||
encoding = Unicode('utf8',
|
encoding = Unicode('utf8',
|
||||||
help="""
|
help="""
|
||||||
The text encoding to use when communicating with PAM
|
The text encoding to use when communicating with PAM
|
||||||
@@ -550,7 +559,7 @@ class PAMAuthenticator(LocalAuthenticator):
|
|||||||
raise _pamela_error from None
|
raise _pamela_error from None
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
@gen.coroutine
|
@run_on_executor
|
||||||
def authenticate(self, handler, data):
|
def authenticate(self, handler, data):
|
||||||
"""Authenticate with PAM, and return the username if login is successful.
|
"""Authenticate with PAM, and return the username if login is successful.
|
||||||
|
|
||||||
@@ -567,6 +576,7 @@ class PAMAuthenticator(LocalAuthenticator):
|
|||||||
else:
|
else:
|
||||||
return username
|
return username
|
||||||
|
|
||||||
|
@run_on_executor
|
||||||
def pre_spawn_start(self, user, spawner):
|
def pre_spawn_start(self, user, spawner):
|
||||||
"""Open PAM session for user if so configured"""
|
"""Open PAM session for user if so configured"""
|
||||||
if not self.open_sessions:
|
if not self.open_sessions:
|
||||||
@@ -578,6 +588,7 @@ class PAMAuthenticator(LocalAuthenticator):
|
|||||||
self.log.warning("Disabling PAM sessions from now on.")
|
self.log.warning("Disabling PAM sessions from now on.")
|
||||||
self.open_sessions = False
|
self.open_sessions = False
|
||||||
|
|
||||||
|
@run_on_executor
|
||||||
def post_spawn_stop(self, user, spawner):
|
def post_spawn_stop(self, user, spawner):
|
||||||
"""Close PAM session for user if we were configured to opened one"""
|
"""Close PAM session for user if we were configured to opened one"""
|
||||||
if not self.open_sessions:
|
if not self.open_sessions:
|
||||||
|
Reference in New Issue
Block a user