Ticket #11506: django-session-flush.diff

File django-session-flush.diff, 5.5 KB (added by Glenn Maynard, 15 years ago)
  • django/contrib/sessions/tests.py

     
    3333>>> prev_key = db_session.session_key
    3434>>> db_session.flush()
    3535>>> db_session.exists(prev_key)
    36 False
     36True
    3737>>> db_session.session_key == prev_key
    3838False
    3939>>> db_session.modified, db_session.accessed
     
    4848>>> db_session.items() == prev_data
    4949True
    5050
     51# Calling cycle_key when no session exists does not raise AttributeError.
     52>>> db_session = DatabaseSession()
     53>>> db_session.cycle_key()
     54
    5155# Submitting an invalid session key (either by guessing, or if the db has
    5256# removed the key) results in a new key being generated.
    5357>>> Session.objects.filter(pk=db_session.session_key).delete()
     
    110114>>> prev_key = file_session.session_key
    111115>>> file_session.flush()
    112116>>> file_session.exists(prev_key)
    113 False
     117True
    114118>>> file_session.session_key == prev_key
    115119False
    116120>>> file_session.modified, file_session.accessed
     
    168172>>> prev_key = cache_session.session_key
    169173>>> cache_session.flush()
    170174>>> cache_session.exists(prev_key)
    171 False
     175True
    172176>>> cache_session.session_key == prev_key
    173177False
    174178>>> cache_session.modified, cache_session.accessed
     
    383387>>> settings.SESSION_EXPIRE_AT_BROWSER_CLOSE = original_expire_at_browser_close
    384388"""
    385389
     390from django.test import TestCase
     391from django.http import HttpRequest, HttpResponse
     392from django.contrib.sessions.middleware import SessionMiddleware
     393from django.conf import settings
     394
     395class SessionTest(TestCase):
     396    def generic_view(self, request):
     397        request.session["seen_this_user_before"] = 1
     398        return HttpResponse("")
     399
     400    def cycle_view(self, request):
     401        request.session.cycle_key()
     402        request.session["login_key"] = 1
     403        return HttpResponse("")
     404
     405    def flush_view(self, request):
     406        request.session.flush()
     407        request.session["login_key"] = 1
     408        return HttpResponse("")
     409
     410    def ajax_view(self, request):
     411        self.assertEqual(request.session.get("login_key", None), None)
     412        return HttpResponse("")
     413
     414    def still_logged_in_view(self, request):
     415        self.assertEqual(request.session.get("login_key"), 1)
     416        return HttpResponse("")
     417
     418    @staticmethod
     419    def run_view(view, client_cookies, session_cookie_override = None):
     420        request_cookies = client_cookies.copy()
     421        if session_cookie_override is not None:
     422            request_cookies[settings.SESSION_COOKIE_NAME] = session_cookie_override
     423
     424        request = HttpRequest()
     425        request.COOKIES = request_cookies
     426
     427        mid = SessionMiddleware()
     428        mid.process_request(request)
     429        response = view(request)
     430        mid.process_response(request, response)
     431
     432        for cookie in response.cookies.itervalues():
     433            client_cookies[cookie.key] = cookie.value
     434        return response
     435
     436    def _test_session_race(self, flush):
     437        # This test will fail if settings.SESSION_SAVE_EVERY_REQUEST is set.
     438        if settings.SESSION_SAVE_EVERY_REQUEST:
     439            return
     440
     441        # This dict simulates the cookie store on a user client.
     442        cookies = {}
     443
     444        # The user logs in, and receives a session cookie for a login key.
     445        # The user accesses the site, and receives a session cookie.
     446        response = self.run_view(self.generic_view, cookies)
     447        original_session_cookie = response.cookies.get(settings.SESSION_COOKIE_NAME, False)
     448        self.assertNotEqual(original_session_cookie, False)
     449
     450        # The user logs into the site, triggering session.flush, and receives a new session cookie.
     451        if flush:
     452            response = self.run_view(self.flush_view, cookies)
     453        else:
     454            response = self.run_view(self.cycle_view, cookies)
     455        new_session_cookie = response.cookies.get(settings.SESSION_COOKIE_NAME, False)
     456        self.assertNotEqual(new_session_cookie, False)
     457        self.assertNotEqual(new_session_cookie.value, original_session_cookie.value)
     458
     459        # A delayed AJAX request comes in using the original session.  The request should use
     460        # the old session and not set a session.  The user is not logged in during this request.
     461        response = self.run_view(self.ajax_view, cookies, original_session_cookie.value)
     462        unset_session_cookie = response.cookies.get(settings.SESSION_COOKIE_NAME, False)
     463        self.assertEqual(unset_session_cookie, False)
     464
     465        # The user should still be logged in.
     466        response = self.run_view(self.still_logged_in_view, cookies)
     467
     468    def test_session_race_with_flush(self):
     469        self._test_session_race(True)
     470
     471    def test_session_race_with_cycle(self):
     472        self._test_session_race(False)
     473
    386474if __name__ == '__main__':
    387475    import doctest
    388476    doctest.testmod()
  • django/contrib/sessions/backends/base.py

     
    236236        key.
    237237        """
    238238        self.clear()
    239         self.delete()
    240239        self.create()
    241240
    242241    def cycle_key(self):
    243242        """
    244243        Creates a new session key, whilst retaining the current session data.
    245244        """
    246         data = self._session_cache
    247         key = self.session_key
    248         self.create()
     245        data = self._get_session()
     246        self.flush()
    249247        self._session_cache = data
    250         self.delete(key)
    251248
    252249    # Methods that child classes must implement.
    253250
Back to Top