Ticket #9356: ticket_9356.2.diff
File ticket_9356.2.diff, 6.7 KB (added by , 16 years ago) |
---|
-
django/contrib/csrf/middleware.py
27 27 def _make_token(session_id): 28 28 return md5_constructor(settings.SECRET_KEY + session_id).hexdigest() 29 29 30 def _get_validated_session_id(request): 31 # This function might be called by a template tag. So, we don't make the 32 # session framework a requirement, otherwise people would have to change 33 # their templates if they disabled the session middleware 34 if hasattr(request, 'session'): 35 # Code that can create a session key will update 36 # request.session.session_key, so we don't need to check the outgoing 37 # response for cookies, request.session will reflect the same 38 # information. 39 if request.session.accessed or request.session.modified: 40 # Could be a new session, need to use new session ID 41 return request.session.session_key 42 else: 43 # Avoid use of session.session_key, which can trigger 44 # unecessary work 45 session_id = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None) 46 if session_id is not None and request.session.exists(session_id): 47 return session_id 48 else: 49 return None # not a valid session 50 return None 51 30 52 class CsrfViewMiddleware(object): 31 53 """ 32 54 Middleware that requires a present and correct csrfmiddlewaretoken … … 40 62 if request.is_ajax(): 41 63 return None 42 64 43 try: 44 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] 45 except KeyError: 65 session_id = _get_validated_session_id(request) 66 if session_id is None: 46 67 # No session, no check required 47 68 return None 48 69 … … 69 90 return response 70 91 71 92 csrf_token = None 72 try: 73 # This covers a corner case in which the outgoing response 74 # both contains a form and sets a session cookie. This 75 # really should not be needed, since it is best if views 76 # that create a new session (login pages) also do a 77 # redirect, as is done by all such view functions in 78 # Django. 79 cookie = response.cookies[settings.SESSION_COOKIE_NAME] 80 csrf_token = _make_token(cookie.value) 81 except KeyError: 82 # Normal case - look for existing session cookie 83 try: 84 session_id = request.COOKIES[settings.SESSION_COOKIE_NAME] 85 csrf_token = _make_token(session_id) 86 except KeyError: 87 # no incoming or outgoing cookie 88 pass 93 session_id = _get_validated_session_id(request) 94 if session_id is not None: 95 csrf_token = _make_token(session_id) 89 96 90 97 if csrf_token is not None and \ 91 98 response['Content-Type'].split(';')[0] in _HTML_TYPES: -
django/contrib/csrf/tests.py
1 1 # -*- coding: utf-8 -*- 2 2 3 from django.conf import settings 4 from django.contrib.csrf.middleware import CsrfMiddleware, _make_token, csrf_exempt 5 from django.contrib.sessions.middleware import SessionMiddleware 6 from django.http import HttpRequest, HttpResponse, HttpResponseForbidden 3 7 from django.test import TestCase 4 from django.http import HttpRequest, HttpResponse, HttpResponseForbidden 5 from django.contrib.csrf.middleware import CsrfMiddleware, _make_token, csrf_exempt 6 from django.conf import settings 8 from django.utils.importlib import import_module 7 9 8 10 9 11 def post_form_response(): … … 17 19 18 20 class CsrfMiddlewareTest(TestCase): 19 21 20 _session_id = "1" 22 def setUp(self, *args, **kwargs): 23 super(CsrfMiddlewareTest, self).setUp(*args, **kwargs) 24 # We have to create an actual session in the DB as the 25 # middleware validates the session 26 engine = import_module(settings.SESSION_ENGINE) 27 s = engine.SessionStore(None) 28 s.create() 29 self._session_id = s.session_key 21 30 31 def _apply_request_middleware(self, req): 32 SessionMiddleware().process_request(req) 33 return req 34 22 35 def _get_GET_no_session_request(self): 23 return HttpRequest()36 return self._apply_request_middleware(HttpRequest()) 24 37 25 38 def _get_GET_session_request(self): 26 req = self._get_GET_no_session_request()39 req = HttpRequest() 27 40 req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id 28 return req41 return self._apply_request_middleware(req) 29 42 30 43 def _get_POST_session_request(self): 31 req = self._get_GET_session_request() 44 req = HttpRequest() 45 req.COOKIES[settings.SESSION_COOKIE_NAME] = self._session_id 32 46 req.method = "POST" 33 return req47 return self._apply_request_middleware(req) 34 48 35 49 def _get_POST_no_session_request(self): 36 req = self._get_GET_no_session_request()50 req = HttpRequest() 37 51 req.method = "POST" 38 return req52 return self._apply_request_middleware(req) 39 53 40 54 def _get_POST_session_request_with_token(self): 41 55 req = self._get_POST_session_request() … … 50 64 resp.cookies[settings.SESSION_COOKIE_NAME] = self._session_id 51 65 return resp 52 66 53 def _check_token_present(self, response): 54 self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % _make_token(self._session_id)) 67 def _check_token_present(self, response, session_id=None): 68 if session_id is None: 69 session_id = self._session_id 70 self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % _make_token(session_id)) 55 71 56 72 def get_view(self): 57 73 return test_view … … 83 99 Check that the token is inserted if there is a new session being started 84 100 """ 85 101 req = self._get_GET_no_session_request() # no session in request 86 resp = self._get_new_session_response() # but new session started 102 req.session.create() # but new session started 103 resp = self._get_post_form_response() 87 104 resp_content = resp.content # needed because process_response modifies resp 88 105 resp2 = CsrfMiddleware().process_response(req, resp) 89 106 self.assertNotEqual(resp_content, resp2.content) 90 self._check_token_present(resp2 )107 self._check_token_present(resp2, session_id=req.session.session_key) 91 108 92 109 def test_process_response_exempt_view(self): 93 110 """