Hide keyboard shortcuts

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 

9 

10 

11logger = logging.getLogger(__name__) 

12 

13 

14class EnsureOriginMiddleware: 

15 """ 

16 Ensures that request META 'HTTP_ORIGIN' is set. 

17 Uses request get_host() to set it if missing. 

18 """ 

19 

20 def __init__(self, get_response=None): 

21 self.get_response = get_response 

22 

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() 

28 

29 # get response 

30 response = self.get_response(request) 

31 

32 # Code to be executed for each request/response after 

33 # the view is called. 

34 return response 

35 

36 

37class LogExceptionMiddleware: 

38 """ 

39 Logs exception and sends email to admins about it. 

40 Uses list of emails from settings.ADMINS. 

41 """ 

42 

43 def __init__(self, get_response=None): 

44 self.get_response = get_response 

45 

46 def __call__(self, request): 

47 return self.get_response(request) 

48 

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) 

65 

66 

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). 

73 

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]] 

80 

81 def __init__(self, get_response=None): 

82 self.get_response = get_response 

83 self._languages = None 

84 

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 

90 

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 

100 

101 res = self.get_response(request) 

102 

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 

108 

109 

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 

116 

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') 

132 

133 # get response 

134 response = self.get_response(request) 

135 

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