Coverage for jutil/middleware.py : 90%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import logging
2import traceback
3from typing import Dict, Optional
4from django.conf import settings
5from django.http import HttpRequest
6from django.utils import timezone
7from ipware import get_client_ip # type: ignore
8from jutil.email import send_email
11logger = logging.getLogger(__name__)
14class EnsureOriginMiddleware:
15 """
16 Ensures that request META 'HTTP_ORIGIN' is set.
17 Uses request get_host() to set it if missing.
18 """
20 def __init__(self, get_response=None):
21 self.get_response = get_response
23 def __call__(self, request):
24 # Code to be executed for each request before
25 # the view (and later middleware) are called.
26 if not request.META.get('HTTP_ORIGIN', None): 26 ↛ 30line 26 didn't jump to line 30, because the condition on line 26 was never false
27 request.META['HTTP_ORIGIN'] = request.get_host()
29 # get response
30 response = self.get_response(request)
32 # Code to be executed for each request/response after
33 # the view is called.
34 return response
37class LogExceptionMiddleware:
38 """
39 Logs exception and sends email to admins about it.
40 Uses list of emails from settings.ADMINS.
41 """
43 def __init__(self, get_response=None):
44 self.get_response = get_response
46 def __call__(self, request):
47 return self.get_response(request)
49 def process_exception(self, request, e):
50 """
51 Logs exception error message and sends email to ADMINS if hostname is not testserver and DEBUG=False.
52 :param request: HttpRequest
53 :param e: Exception
54 """
55 assert isinstance(request, HttpRequest)
56 full_path = request.get_full_path()
57 user = request.user
58 msg = '{full_path}\n{err} (IP={ip}, user={user}) {trace}'.format(full_path=full_path, user=user,
59 ip=get_client_ip(request)[0], err=e,
60 trace=str(traceback.format_exc()))
61 logger.error(msg)
62 hostname = request.get_host()
63 if not settings.DEBUG and hostname != 'testserver': 63 ↛ 64line 63 didn't jump to line 64, because the condition on line 63 was never true
64 send_email(settings.ADMINS, 'Error @ {}'.format(hostname), msg)
67class EnsureLanguageCookieMiddleware:
68 """
69 Ensures language cookie (by name settings.LANGUAGE_COOKIE_NAME) is set.
70 Sets it as settings.LANGUAGE_CODE if missing.
71 Allows changing settings by passing querystring parameter named settings.LANGUAGE_COOKIE_NAME
72 (default: django_language).
74 Order of preference for the language (must be one of settings.LANGUAGES to be used):
75 1) Explicit querystring GET parameter (e.g. ?lang=en)
76 2) Previously stored cookie
77 3) settings.LANGUAGE_CODE
78 """
79 _languages: Optional[Dict[str, str]]
81 def __init__(self, get_response=None):
82 self.get_response = get_response
83 self._languages = None
85 @property
86 def languages(self) -> Dict[str, str]:
87 if self._languages is None:
88 self._languages = dict(settings.LANGUAGES)
89 return self._languages
91 def __call__(self, request):
92 lang_cookie_name = settings.LANGUAGE_COOKIE_NAME if hasattr(settings, 'LANGUAGE_COOKIE_NAME') else 'django_language'
93 lang_cookie = request.COOKIES.get(lang_cookie_name)
94 lang = request.GET.get(lang_cookie_name)
95 if not lang:
96 lang = lang_cookie
97 if not lang or lang not in self.languages:
98 lang = settings.LANGUAGE_CODE if hasattr(settings, 'LANGUAGE_CODE') else 'en'
99 request.COOKIES[lang_cookie_name] = lang
101 res = self.get_response(request)
103 if lang_cookie is None or lang != lang_cookie:
104 secure = hasattr(settings, 'LANGUAGE_COOKIE_SECURE') and settings.LANGUAGE_COOKIE_SECURE
105 httponly = hasattr(settings, 'LANGUAGE_COOKIE_HTTPONLY') and settings.LANGUAGE_COOKIE_HTTPONLY
106 res.set_cookie(lang_cookie_name, lang, secure=secure, httponly=httponly)
107 return res
110class ActivateUserProfileTimezoneMiddleware:
111 """
112 Uses 'timezone' string in request.user.profile to activate user-specific timezone.
113 """
114 def __init__(self, get_response=None):
115 self.get_response = get_response
117 def __call__(self, request):
118 # Code to be executed for each request before
119 # the view (and later middleware) are called.
120 activated = False
121 if request.user.is_authenticated: 121 ↛ 134line 121 didn't jump to line 134, because the condition on line 121 was never false
122 user = request.user
123 if hasattr(user, 'profile') and user.profile: 123 ↛ 131line 123 didn't jump to line 131, because the condition on line 123 was never false
124 up = user.profile
125 if hasattr(up, 'timezone') and up.timezone: 125 ↛ 129line 125 didn't jump to line 129, because the condition on line 125 was never false
126 timezone.activate(up.timezone)
127 activated = True
128 else:
129 logger.warning('User profile timezone missing so user.profile.timezone could not be activated')
130 else:
131 logger.warning('User profile missing so user.profile.timezone could not be activated')
133 # get response
134 response = self.get_response(request)
136 # Code to be executed for each request/response after
137 # the view is called.
138 if activated: 138 ↛ 140line 138 didn't jump to line 140, because the condition on line 138 was never false
139 timezone.deactivate()
140 return response