Code

Ticket #2548: session_middleware.6.diff

File session_middleware.6.diff, 5.7 KB (added by upadhyay@…, 7 years ago)

with docs, without newline munging.

Line 
1Index: django/contrib/sessions/middleware.py
2===================================================================
3--- django/contrib/sessions/middleware.py       (revision 5468)
4+++ django/contrib/sessions/middleware.py       (working copy)
5@@ -1,5 +1,5 @@
6 from django.conf import settings
7-from django.contrib.sessions.models import Session
8+from django.contrib.sessions.models import Session, TILL_BROWSER_CLOSE
9 from django.core.exceptions import SuspiciousOperation
10 from django.utils.cache import patch_vary_headers
11 import datetime
12@@ -48,6 +48,19 @@
13     def delete_test_cookie(self):
14         del self[TEST_COOKIE_NAME]
15 
16+    def set_life(self, val):
17+        """
18+            sets the life of the session, irrespective of global settings.
19+            val is in seconds.
20+
21+            django.contrib.sessions.models.TILL_BROWSER_CLOSE can also be passed
22+            to ask django to quell session on browser close, overwriting global settings.
23+        """
24+        if val == TILL_BROWSER_CLOSE:
25+            self["_expires_on"] = TILL_BROWSER_CLOSE
26+        else:
27+            self["_expires_on"] = datetime.datetime.now() + datetime.timedelta(seconds=val)
28+
29     def _get_session(self):
30         # Lazily loads session from storage.
31         self.accessed = True
32@@ -92,15 +105,31 @@
33                     obj = Session.objects.get_new_session_object()
34                     session_key = obj.session_key
35 
36-                if settings.SESSION_EXPIRE_AT_BROWSER_CLOSE:
37-                    max_age = None
38-                    expires = None
39-                else:
40-                    max_age = settings.SESSION_COOKIE_AGE
41-                    expires = datetime.datetime.strftime(datetime.datetime.utcnow() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT")
42-                new_session = Session.objects.save(session_key, request.session._session,
43-                    datetime.datetime.now() + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE))
44-                response.set_cookie(settings.SESSION_COOKIE_NAME, session_key,
45+                now = datetime.datetime.now()
46+                delta_yield = now + datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE)
47+                if (
48+                    (
49+                        # if session is set to expire on browser close globally
50+                        settings.SESSION_EXPIRE_AT_BROWSER_CLOSE and
51+                        # but someone did not set _expires_on, or set it to TILL_BROWSER_CLOSE
52+                        request.session.get("_expires_on", TILL_BROWSER_CLOSE) == TILL_BROWSER_CLOSE
53+                    ) or
54+                    (
55+                        # if someone asked as to expire on browser close irrespective of global setting
56+                        request.session.get("_expires_on") == TILL_BROWSER_CLOSE
57+                    )
58+                ):
59+                    max_age = None # session expiry is simulated by cookie deletion.
60+                    expires = None # which is done by setting these two to None
61+                else: # session need to be preserved, cookie has to be set
62+                    delta_yield = request.session.get("_expires_on", delta_yield)
63+                    max_age_timedelta = delta_yield - now
64+                    max_age = max_age_timedelta.days * 24 * 60 * 60 + max_age_timedelta.seconds
65+                    expires = datetime.datetime.strftime(delta_yield, "%a, %d-%b-%Y %H:%M:%S GMT")
66+                Session.objects.save(session_key, request.session._session, delta_yield)
67+                response.set_cookie(
68+                    settings.SESSION_COOKIE_NAME, session_key,
69                     max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
70-                    secure=settings.SESSION_COOKIE_SECURE or None)
71+                    secure=settings.SESSION_COOKIE_SECURE or None
72+                )
73         return response
74Index: django/contrib/sessions/models.py
75===================================================================
76--- django/contrib/sessions/models.py   (revision 5468)
77+++ django/contrib/sessions/models.py   (working copy)
78@@ -4,6 +4,8 @@
79 from django.utils.translation import gettext_lazy as _
80 from django.conf import settings
81 
82+TILL_BROWSER_CLOSE = -1
83+
84 class SessionManager(models.Manager):
85     def encode(self, session_dict):
86         "Returns the given session dictionary pickled and encoded as a string."
87Index: docs/sessions.txt
88===================================================================
89--- docs/sessions.txt   (revision 5468)
90+++ docs/sessions.txt   (working copy)
91@@ -58,7 +58,7 @@
92 
93     * ``items()``
94 
95-It also has these three methods:
96+It also has these four methods:
97 
98     * ``set_test_cookie()``
99       Sets a test cookie to determine whether the user's browser supports
100@@ -75,6 +75,14 @@
101     * ``delete_test_cookie()``
102       Deletes the test cookie. Use this to clean up after yourself.
103 
104+    * ``set_life(val)``
105+      It takes an integer, number of seconds for which the session should be
106+      valid. It can also take django.contrib.session.models.TILL_BROWSER_CLOSE,
107+      that will quell the session at the close of browser. Calling set_life
108+      will overwrite the global/default session expiry policy. See
109+      `browser-length sessions vs. persistent sessions` for default session expiry
110+      policy.
111+
112 You can edit ``request.session`` at any point in your view. You can edit it
113 multiple times.
114 
115@@ -217,6 +225,9 @@
116 her browser. Use this if you want people to have to log in every time they open
117 a browser.
118 
119+These settings are global defaults, and can be overwritten by explicitly calling
120+``request.session.set_life()`` as described above.
121+
122 Clearing the session table
123 ==========================
124