Anonymous avatar Anonymous committed da478e3

Fixed #14685 - incompatible code in contrib.sessions.models

Thanks to PaulM for the report.

Comments (0)

Files changed (2)

django/contrib/sessions/models.py

 
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
-from django.conf import settings
-from django.utils.hashcompat import md5_constructor
-
 
 class SessionManager(models.Manager):
     def encode(self, session_dict):
         """
         Returns the given session dictionary pickled and encoded as a string.
         """
-        pickled = pickle.dumps(session_dict)
-        pickled_md5 = md5_constructor(pickled + settings.SECRET_KEY).hexdigest()
-        return base64.encodestring(pickled + pickled_md5)
+        return SessionStore().encode(session_dict)
 
     def save(self, session_key, session_dict, expire_date):
         s = self.model(session_key, self.encode(session_dict), expire_date)
         verbose_name_plural = _('sessions')
 
     def get_decoded(self):
-        encoded_data = base64.decodestring(self.session_data)
-        pickled, tamper_check = encoded_data[:-32], encoded_data[-32:]
-        if md5_constructor(pickled + settings.SECRET_KEY).hexdigest() != tamper_check:
-            from django.core.exceptions import SuspiciousOperation
-            raise SuspiciousOperation("User tampered with session cookie.")
-        try:
-            return pickle.loads(pickled)
-        # Unpickling can cause a variety of exceptions. If something happens,
-        # just return an empty dictionary (an empty session).
-        except:
-            return {}
+        return SessionStore().decode(self.session_data)
+
+from django.contrib.sessions.backends.db import SessionStore

django/contrib/sessions/tests.py

 
     backend = DatabaseSession
 
+    def test_session_get_decoded(self):
+        """
+        Test we can use Session.get_decoded to retrieve data stored
+        in normal way
+        """
+        self.session['x'] = 1
+        self.session.save()
+
+        s = Session.objects.get(session_key=self.session.session_key)
+
+        self.assertEqual(s.get_decoded(), {'x': 1})
+
+    def test_sessionmanager_save(self):
+        """
+        Test SessionManager.save method
+        """
+        # Create a session
+        self.session['y'] = 1
+        self.session.save()
+
+        s = Session.objects.get(session_key=self.session.session_key)
+        # Change it
+        Session.objects.save(s.session_key, {'y':2}, s.expire_date)
+        # Clear cache, so that it will be retrieved from DB
+        del self.session._session_cache
+        self.assertEqual(self.session['y'], 2)
+
 
 class CacheDBSessionTests(SessionTestsMixin, TestCase):
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.