post_auth_hook processor

Does what it sounds like, allows an arbitrary function to be called right before the return in `get_authenticated_user`
This commit is contained in:
Will Starms
2018-11-13 13:51:19 -06:00
committed by Min RK
parent fec3d959f2
commit 7c36ac93ba
2 changed files with 65 additions and 1 deletions

View File

@@ -7,8 +7,8 @@ from concurrent.futures import ThreadPoolExecutor
import inspect
import pipes
import re
from shutil import which
import sys
from shutil import which
from subprocess import Popen, PIPE, STDOUT
import warnings
@@ -216,6 +216,37 @@ class Authenticator(LoggingConfigurable):
"""
)
post_auth_hook = Any(config=True,
help="""
An optional hook function that you can implement to do some
bootstrapping work during authentication. For example, loading user account
details from an external system.
This function is called after the user has passed all authentication checks
and is ready to successfully authenticate.
This maybe a coroutine.
Example::
import os, pwd
def my_hook(authenticator, handler, authentication):
user_data = pwd.getpwnam(authentication['name'])
spawn_data = {
'pw_data': user_data
'gid_list': os.getgrouplist(authentication['name'], user_data.pw_gid)
}
if authentication['auth_data'] is None:
authentication['auth_data'] = {'spawn_data': spawn_data}
else:
authentication['auth_data']['spawn_data'] = spawn_data
c.Authenticator.post_auth_hook = my_hook
"""
)
def __init__(self, **kwargs):
super().__init__(**kwargs)
for method_name in ('check_whitelist', 'check_blacklist', 'check_group_whitelist'):
@@ -248,6 +279,22 @@ class Authenticator(LoggingConfigurable):
return original_method(username, **kwargs)
setattr(self, method_name, wrapped_method)
def run_post_auth_hook(self, handler, authentication):
"""
Run the post_auth_hook if defined
.. versionadded: 1.0
Args:
handler (tornado.web.RequestHandler): the current request handler
authentication (dict): User authentication data dictionary. Contains the
username ('name'), admin status ('admin'), and auth state dictionary ('auth_state').
Returns:
None
"""
if self.post_auth_hook is not None:
return self.post_auth_hook(self, handler, authentication)
def normalize_username(self, username):
"""Normalize the given username and return it
@@ -347,6 +394,8 @@ class Authenticator(LoggingConfigurable):
if authenticated['admin'] is None:
authenticated['admin'] = await maybe_future(self.is_admin(handler, authenticated))
self.run_post_auth_hook(handler, authenticated)
return authenticated
else:
self.log.warning("User %r not in whitelist.", username)