authentic/authentic2/middleware.py

106 lines
3.5 KiB
Python

import logging
import datetime
try:
import threading
except ImportError:
threading = None
from django.conf import settings
from . import app_settings
class ThreadCollector(object):
def __init__(self):
if threading is None:
raise NotImplementedError(
"threading module is not available, "
"this panel cannot be used without it")
self.collections = {} # a dictionary that maps threads to collections
def get_collection(self, thread=None):
"""
Returns a list of collected items for the provided thread, of if none
is provided, returns a list for the current thread.
"""
if thread is None:
thread = threading.currentThread()
if thread not in self.collections:
self.collections[thread] = []
return self.collections[thread]
def clear_collection(self, thread=None):
if thread is None:
thread = threading.currentThread()
if thread in self.collections:
del self.collections[thread]
def collect(self, item, thread=None):
self.get_collection(thread).append(item)
MESSAGE_IF_STRING_REPRESENTATION_INVALID = '[Could not get log message]'
class ThreadTrackingHandler(logging.Handler):
def __init__(self, collector):
logging.Handler.__init__(self)
self.collector = collector
def emit(self, record):
try:
message = self.format(record)
except Exception:
message = MESSAGE_IF_STRING_REPRESENTATION_INVALID
record = {
'message': message,
'time': datetime.datetime.fromtimestamp(record.created),
'level': record.levelname,
'file': record.pathname,
'line': record.lineno,
'channel': record.name,
}
self.collector.collect(record)
# We don't use enable/disable_instrumentation because logging is global.
# We can't add thread-local logging handlers. Hopefully logging is cheap.
collector = ThreadCollector()
logging_handler = ThreadTrackingHandler(collector)
logging.root.addHandler(logging_handler)
class LoggingCollectorMiddleware(object):
def process_request(self, request):
collector.clear_collection()
def show_logs(self, request):
if request.META.get('REMOTE_ADDR', None) in settings.INTERNAL_IPS:
return True
def process_exception(self, request, exception):
if self.show_logs(request):
request.logs = collector.get_collection()
request.exception = exception
class CollectIPMiddleware(object):
def process_request(self, request):
ips = request.session.setdefault('ips', set())
ip = request.META.get('REMOTE_ADDR', None)
if ip and ip not in ips:
ips.add(ip)
request.session.modified = True
class OpenedSessionCookieMiddleware(object):
def process_response(self, request, response):
if hasattr(request, 'user') and request.user.is_authenticated():
if app_settings.A2_OPENED_SESSION_COOKIE_DOMAIN:
response.set_cookie(
app_settings.A2_OPENED_SESSION_COOKIE_NAME,
value='1',
max_age=None,
domain=app_settings.A2_OPENED_SESSION_COOKIE_DOMAIN)
else:
response.delete_cookie(
app_settings.A2_OPENED_SESSION_COOKIE_NAME,
domain=app_settings.A2_OPENED_SESSION_COOKIE_DOMAIN)
return response