Code

Ticket #10899: easy_session_manipulation6.diff

File easy_session_manipulation6.diff, 5.5 KB (added by tallfred, 5 years ago)
Line 
1Index: test/client.py
2===================================================================
3--- test/client.py      (revision 10620)
4+++ test/client.py      (working copy)
5@@ -166,6 +166,7 @@ class Client(object):
6         self.cookies = SimpleCookie()
7         self.exc_info = None
8         self.errors = StringIO()
9+        self._session_store = None
10 
11     def store_exc_info(self, **kwargs):
12         """
13@@ -175,15 +176,39 @@ class Client(object):
14 
15     def _session(self):
16         """
17-        Obtains the current session variables.
18+        Obtains a SessionStore containing all the current session variables.
19         """
20-        if 'django.contrib.sessions' in settings.INSTALLED_APPS:
21-            engine = import_module(settings.SESSION_ENGINE)
22-            cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
23-            if cookie:
24-                return engine.SessionStore(cookie.value)
25-        return {}
26-    session = property(_session)
27+        if self._session_store == None:
28+            if 'django.contrib.sessions' in settings.INSTALLED_APPS:
29+                cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
30+                engine = import_module(settings.SESSION_ENGINE)
31+                if cookie:
32+                    self._session_store = engine.SessionStore(cookie.value)
33+                else:
34+                    self._session_store = engine.SessionStore()
35+                    # if load() fails the cookie changes, so save() first
36+                    self._session_store.save() 
37+                    self.cookies[settings.SESSION_COOKIE_NAME] = \
38+                         self._session_store.session_key
39+            else:
40+                self._session_store = {}
41+        return self._session_store
42+    def _failure(self, *extra):
43+        assert False, "Don't replace the session store."
44+    session = property(_session, _failure, _failure)
45+
46+    def _session_save(self):
47+        """
48+        Push the session store to the database then delete the
49+        session store.  It's needed before calling a view.
50+        """
51+        if hasattr(self._session_store, 'modified'):
52+            if self._session_store.modified:
53+                self._session_store.save()
54+                # update the cookie in case cycle_key() was called
55+                self.cookies[settings.SESSION_COOKIE_NAME] = \
56+                     self._session_store.session_key
57+            self._session_store = None
58 
59     def request(self, **request):
60         """
61@@ -268,6 +293,7 @@ class Client(object):
62         """
63         Requests a response from the server using GET.
64         """
65+        self._session_save()
66         parsed = urlparse(path)
67         r = {
68             'CONTENT_TYPE':    'text/html; charset=utf-8',
69@@ -288,6 +314,7 @@ class Client(object):
70         """
71         Requests a response from the server using POST.
72         """
73+        self._session_save()
74         if content_type is MULTIPART_CONTENT:
75             post_data = encode_multipart(BOUNDARY, data)
76         else:
77@@ -319,6 +346,7 @@ class Client(object):
78         """
79         Request a response from the server using HEAD.
80         """
81+        self._session_save()
82         parsed = urlparse(path)
83         r = {
84             'CONTENT_TYPE':    'text/html; charset=utf-8',
85@@ -338,6 +366,7 @@ class Client(object):
86         """
87         Request a response from the server using OPTIONS.
88         """
89+        self._session_save()
90         parsed = urlparse(path)
91         r = {
92             'PATH_INFO':       urllib.unquote(parsed[2]),
93@@ -357,6 +386,7 @@ class Client(object):
94         """
95         Send a resource to the server using PUT.
96         """
97+        self._session_save()
98         if content_type is MULTIPART_CONTENT:
99             post_data = encode_multipart(BOUNDARY, data)
100         else:
101@@ -382,6 +412,7 @@ class Client(object):
102         """
103         Send a DELETE request to the server.
104         """
105+        self._session_save()
106         parsed = urlparse(path)
107         r = {
108             'PATH_INFO':       urllib.unquote(parsed[2]),
109@@ -407,31 +438,11 @@ class Client(object):
110         user = authenticate(**credentials)
111         if user and user.is_active \
112                 and 'django.contrib.sessions' in settings.INSTALLED_APPS:
113-            engine = import_module(settings.SESSION_ENGINE)
114-
115             # Create a fake request to store login details.
116             request = HttpRequest()
117-            if self.session:
118-                request.session = self.session
119-            else:
120-                request.session = engine.SessionStore()
121+            request.session = self.session
122             login(request, user)
123 
124-            # Set the cookie to represent the session.
125-            session_cookie = settings.SESSION_COOKIE_NAME
126-            self.cookies[session_cookie] = request.session.session_key
127-            cookie_data = {
128-                'max-age': None,
129-                'path': '/',
130-                'domain': settings.SESSION_COOKIE_DOMAIN,
131-                'secure': settings.SESSION_COOKIE_SECURE or None,
132-                'expires': None,
133-            }
134-            self.cookies[session_cookie].update(cookie_data)
135-
136-            # Save the session values.
137-            request.session.save()
138-
139             return True
140         else:
141             return False
142@@ -442,6 +453,7 @@ class Client(object):
143 
144         Causes the authenticated user to be logged out.
145         """
146+        self._session_store = None
147         session = import_module(settings.SESSION_ENGINE).SessionStore()
148         session_cookie = self.cookies.get(settings.SESSION_COOKIE_NAME)
149         if session_cookie: