Browse Source

Fixed #28763 -- Allowed overriding the session cookie age with SessionStore.get_session_cookie_age().

Hasan Ramezani 5 years ago
parent
commit
9d6f981a66

+ 5 - 2
django/contrib/sessions/backends/base.py

@@ -206,6 +206,9 @@ class SessionBase:
 
     _session = property(_get_session)
 
+    def get_session_cookie_age(self):
+        return settings.SESSION_COOKIE_AGE
+
     def get_expiry_age(self, **kwargs):
         """Get the number of seconds until the session expires.
 
@@ -225,7 +228,7 @@ class SessionBase:
             expiry = self.get('_session_expiry')
 
         if not expiry:   # Checks both None and 0 cases
-            return settings.SESSION_COOKIE_AGE
+            return self.get_session_cookie_age()
         if not isinstance(expiry, datetime):
             return expiry
         delta = expiry - modification
@@ -249,7 +252,7 @@ class SessionBase:
 
         if isinstance(expiry, datetime):
             return expiry
-        expiry = expiry or settings.SESSION_COOKIE_AGE   # Checks both None and 0 cases
+        expiry = expiry or self.get_session_cookie_age()
         return modification + timedelta(seconds=expiry)
 
     def set_expiry(self, value):

+ 1 - 1
django/contrib/sessions/backends/file.py

@@ -69,7 +69,7 @@ class SessionStore(SessionBase):
         Return the expiry time of the file storing the session's content.
         """
         return session_data.get('_session_expiry') or (
-            self._last_modification() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE)
+            self._last_modification() + datetime.timedelta(seconds=self.get_session_cookie_age())
         )
 
     def load(self):

+ 1 - 2
django/contrib/sessions/backends/signed_cookies.py

@@ -1,4 +1,3 @@
-from django.conf import settings
 from django.contrib.sessions.backends.base import SessionBase
 from django.core import signing
 
@@ -16,7 +15,7 @@ class SessionStore(SessionBase):
                 self.session_key,
                 serializer=self.serializer,
                 # This doesn't handle non-default expiry dates, see #19201
-                max_age=settings.SESSION_COOKIE_AGE,
+                max_age=self.get_session_cookie_age(),
                 salt='django.contrib.sessions.backends.signed_cookies',
             )
         except Exception:

+ 3 - 1
docs/releases/3.0.txt

@@ -96,7 +96,9 @@ Minor features
 :mod:`django.contrib.sessions`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-* ...
+* The new
+  :meth:`~django.contrib.sessions.backends.base.SessionBase.get_session_cookie_age()`
+  methods allows dynamically specifying the session cookie age.
 
 :mod:`django.contrib.sitemaps`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ 7 - 0
docs/topics/http/sessions.txt

@@ -244,6 +244,13 @@ You can edit it multiple times.
 
       Deletes the test cookie. Use this to clean up after yourself.
 
+    .. method:: get_session_cookie_age()
+
+      .. versionadded:: 3.0
+
+      Returns the age of session cookies, in seconds. Defaults to
+      :setting:`SESSION_COOKIE_AGE`.
+
     .. method:: set_expiry(value)
 
       Sets the expiration time for the session. You can pass a number of

+ 3 - 0
tests/sessions_tests/models.py

@@ -38,3 +38,6 @@ class SessionStore(DBStore):
         obj.account_id = account_id
 
         return obj
+
+    def get_session_cookie_age(self):
+        return 60 * 60 * 24  # One day.

+ 12 - 0
tests/sessions_tests/tests.py

@@ -454,6 +454,7 @@ class DatabaseSessionWithTimeZoneTests(DatabaseSessionTests):
 class CustomDatabaseSessionTests(DatabaseSessionTests):
     backend = CustomDatabaseSession
     session_engine = 'sessions_tests.models'
+    custom_session_cookie_age = 60 * 60 * 24  # One day.
 
     def test_extra_session_field(self):
         # Set the account ID to be picked up by a custom session storage
@@ -473,6 +474,17 @@ class CustomDatabaseSessionTests(DatabaseSessionTests):
         s = self.model.objects.get(session_key=self.session.session_key)
         self.assertIsNone(s.account_id)
 
+    def test_custom_expiry_reset(self):
+        self.session.set_expiry(None)
+        self.session.set_expiry(10)
+        self.session.set_expiry(None)
+        self.assertEqual(self.session.get_expiry_age(), self.custom_session_cookie_age)
+
+    def test_default_expiry(self):
+        self.assertEqual(self.session.get_expiry_age(), self.custom_session_cookie_age)
+        self.session.set_expiry(0)
+        self.assertEqual(self.session.get_expiry_age(), self.custom_session_cookie_age)
+
 
 class CacheDBSessionTests(SessionTestsMixin, TestCase):