Get created_by and modified_by updating automatically.

This commit is contained in:
Chris Church
2014-04-01 21:27:32 -04:00
parent d632aa0af9
commit 118ddf97f6
12 changed files with 172 additions and 6 deletions

View File

@@ -17,6 +17,7 @@ d2to1==0.2.11 (d2to1/*)
distribute==0.7.3 (no files)
django-auth-ldap==1.1.8 (django_auth_ldap/*)
django-celery==3.1.10 (djcelery/*)
django-crum==0.6.1 (crum/*)
django-extensions==1.3.3 (django_extensions/*)
django-jsonfield==0.9.12 (jsonfield/*, minor fix in jsonfield/fields.py)
django-polymorphic==0.5.3 (polymorphic/*)

View File

@@ -0,0 +1,87 @@
# Python
import contextlib
import logging
import threading
_thread_locals = threading.local()
_logger = logging.getLogger('crum')
__version__ = '0.6.1'
__all__ = ['get_current_request', 'get_current_user', 'impersonate']
@contextlib.contextmanager
def impersonate(user=None):
"""Temporarily impersonate the given user for audit trails."""
try:
current_user = get_current_user(_return_false=True)
set_current_user(user)
yield user
finally:
set_current_user(current_user)
def get_current_request():
"""Return the request associated with the current thread."""
return getattr(_thread_locals, 'request', None)
def set_current_request(request=None):
"""Update the request associated with the current thread."""
_thread_locals.request = request
# Clear the current user if also clearing the request.
if not request:
set_current_user(False)
def get_current_user(_return_false=False):
"""Return the user associated with the current request thread."""
from crum.signals import current_user_getter
top_priority = -9999
top_user = False if _return_false else None
results = current_user_getter.send_robust(get_current_user)
for receiver, response in results:
priority = 0
if isinstance(response, Exception):
_logger.exception('%r raised exception: %s', receiver, response)
continue
elif isinstance(response, (tuple, list)) and response:
user = response[0]
if len(response) > 1:
priority = response[1]
elif response or response in (None, False):
user = response
else:
_logger.error('%r returned invalid response: %r', receiver,
response)
continue
if user is not False:
if priority > top_priority:
top_priority = priority
top_user = user
return top_user
def set_current_user(user=None):
"""Update the user associated with the current request thread."""
from crum.signals import current_user_setter
results = current_user_setter.send_robust(set_current_user, user=user)
for receiver, response in results:
if isinstance(response, Exception):
_logger.exception('%r raised exception: %s', receiver, response)
class CurrentRequestUserMiddleware(object):
"""Middleware to capture the request and user from the current thread."""
def process_request(self, request):
set_current_request(request)
def process_response(self, request, response):
set_current_request(None)
return response
def process_exception(self, request, exception):
set_current_request(None)

View File

@@ -0,0 +1,44 @@
# Django
from django.dispatch import Signal, receiver
__all__ = ['current_user_getter']
# Signal used when getting current user. Receivers should return a tuple of
# (user, priority).
current_user_getter = Signal(providing_args=[])
# Signal used when setting current user. Receivers should store the current
# user as needed. Return values are ignored.
current_user_setter = Signal(providing_args=['user'])
@receiver(current_user_getter)
def _get_current_user_from_request(sender, **kwargs):
"""Signal handler to retrieve current user from request."""
from crum import get_current_request
return (getattr(get_current_request(), 'user', False), -10)
@receiver(current_user_getter)
def _get_current_user_from_thread_locals(sender, **kwargs):
"""Signal handler to retrieve current user from thread locals."""
from crum import _thread_locals
return (getattr(_thread_locals, 'user', False), 10)
@receiver(current_user_setter)
def _set_current_user_on_request(sender, **kwargs):
"""Signal handler to store current user to request."""
from crum import get_current_request
request = get_current_request()
if request:
request.user = kwargs['user']
@receiver(current_user_setter)
def _set_current_user_on_thread_locals(sender, **kwargs):
"""Signal handler to store current user on thread locals."""
from crum import _thread_locals
_thread_locals.user = kwargs['user']