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 urllib.parse import urlencode 

5from django.conf import settings 

6from django.http import HttpRequest 

7from django.utils import timezone 

8from ipware import get_client_ip # type: ignore 

9from jutil.email import send_email 

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 

141 

142 

143class TestClientLogger: 

144 """ 

145 Logs requests for Django test client. 

146 """ 

147 ignored_paths = { 

148 '/admin/jsi18n/', 

149 '/favicon.ico', 

150 } 

151 

152 def __init__(self, get_response=None): 

153 self.get_response = get_response 

154 

155 def __call__(self, request): 

156 if settings.DEBUG: 

157 assert isinstance(request, HttpRequest) 

158 if request.path not in self.ignored_paths: 

159 url = request.path 

160 qs = request.GET.dict() 

161 if qs: 

162 url += '?' + urlencode(request.GET.dict()) 

163 logger.debug('[TestClientLogger] self.client.%s("%s", data=%s)', request.method.lower(), url, request.POST.dict()) 

164 response = self.get_response(request) 

165 return response