From 5e8efa9a6032f9c4278199ab354c3ff742387263 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Thu, 14 Aug 2008 03:57:46 +0000 Subject: [PATCH] Implemented a flush() method on sessions that cleans out the session and regenerates the key. Used to ensure the caller gets a fresh session at logout, for example. Based on a patch from mrts. Refs #7515. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8342 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/sessions/backends/base.py | 14 +++++++-- django/contrib/sessions/backends/cache.py | 4 ++- django/contrib/sessions/backends/db.py | 4 ++- django/contrib/sessions/backends/file.py | 4 ++- django/contrib/sessions/tests.py | 38 +++++++++++++++++++++++ docs/sessions.txt | 10 ++++++ 6 files changed, 69 insertions(+), 5 deletions(-) diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py index a267eb1875..cc823c537e 100644 --- a/django/contrib/sessions/backends/base.py +++ b/django/contrib/sessions/backends/base.py @@ -223,6 +223,15 @@ class SessionBase(object): return settings.SESSION_EXPIRE_AT_BROWSER_CLOSE return self.get('_session_expiry') == 0 + def flush(self): + """ + Removes the current session data from the database and regenerates the + key. + """ + self.clear() + self.delete() + self.create() + # Methods that child classes must implement. def exists(self, session_key): @@ -247,9 +256,10 @@ class SessionBase(object): """ raise NotImplementedError - def delete(self, session_key): + def delete(self, session_key=None): """ - Clears out the session data under this key. + Deletes the session data under this key. If the key is None, the + current session key value is used. """ raise NotImplementedError diff --git a/django/contrib/sessions/backends/cache.py b/django/contrib/sessions/backends/cache.py index 5729c85af8..2988d3ee09 100644 --- a/django/contrib/sessions/backends/cache.py +++ b/django/contrib/sessions/backends/cache.py @@ -39,6 +39,8 @@ class SessionStore(SessionBase): return True return False - def delete(self, session_key): + def delete(self, session_key=None): + if session_key is None: + session_key = self._session_key self._cache.delete(session_key) diff --git a/django/contrib/sessions/backends/db.py b/django/contrib/sessions/backends/db.py index b1dc6f49e3..df9d64e7c4 100644 --- a/django/contrib/sessions/backends/db.py +++ b/django/contrib/sessions/backends/db.py @@ -61,7 +61,9 @@ class SessionStore(SessionBase): raise CreateError raise - def delete(self, session_key): + def delete(self, session_key=None): + if session_key is None: + session_key = self._session_key try: Session.objects.get(session_key=session_key).delete() except Session.DoesNotExist: diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py index 00f374edfd..8290cad80a 100644 --- a/django/contrib/sessions/backends/file.py +++ b/django/contrib/sessions/backends/file.py @@ -89,7 +89,9 @@ class SessionStore(SessionBase): return True return False - def delete(self, session_key): + def delete(self, session_key=None): + if session_key is None: + session_key = self._session_key try: os.unlink(self._key_to_file(session_key)) except OSError: diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py index afb9b3dfd3..ec4da2d543 100644 --- a/django/contrib/sessions/tests.py +++ b/django/contrib/sessions/tests.py @@ -23,6 +23,19 @@ True >>> db_session.exists(db_session.session_key) False +>>> db_session['foo'] = 'bar' +>>> db_session.save() +>>> db_session.exists(db_session.session_key) +True +>>> prev_key = db_session.session_key +>>> db_session.flush() +>>> db_session.exists(prev_key) +False +>>> db_session.session_key == prev_key +False +>>> db_session.modified, db_session.accessed +(True, True) + >>> file_session = FileSession() >>> file_session.modified False @@ -40,6 +53,19 @@ True >>> file_session.exists(file_session.session_key) False +>>> file_session['foo'] = 'bar' +>>> file_session.save() +>>> file_session.exists(file_session.session_key) +True +>>> prev_key = file_session.session_key +>>> file_session.flush() +>>> file_session.exists(prev_key) +False +>>> file_session.session_key == prev_key +False +>>> file_session.modified, file_session.accessed +(True, True) + # Make sure the file backend checks for a good storage dir >>> settings.SESSION_FILE_PATH = "/if/this/directory/exists/you/have/a/weird/computer" >>> FileSession() @@ -61,6 +87,18 @@ True >>> cache_session.delete(cache_session.session_key) >>> cache_session.exists(cache_session.session_key) False +>>> cache_session['foo'] = 'bar' +>>> cache_session.save() +>>> cache_session.exists(cache_session.session_key) +True +>>> prev_key = cache_session.session_key +>>> cache_session.flush() +>>> cache_session.exists(prev_key) +False +>>> cache_session.session_key == prev_key +False +>>> cache_session.modified, cache_session.accessed +(True, True) >>> s = SessionBase() >>> s._session['some key'] = 'exists' # Pre-populate the session with some data diff --git a/docs/sessions.txt b/docs/sessions.txt index 39df04ad71..7971601c7a 100644 --- a/docs/sessions.txt +++ b/docs/sessions.txt @@ -110,6 +110,16 @@ A session object has the following standard dictionary methods: It also has these methods: + * ``flush()`` + + **New in Django development version** + + Delete the current session data from the database and regenerate the + session key value that is sent back to the user in the cookie. This is + used if you want to ensure that the previous session data can't be + accessed again from the user's browser (for example, the standard + ``logout()`` method calls it). + * ``set_test_cookie()`` Sets a test cookie to determine whether the user's browser supports