[web/session] make sure not to modify an inner value of session.data (closes #11217958)
When we modify a mutable value stored in the session's data (dict-like object)
we prevent an alternative session data handler (eg. pyramid-redis-session)
from detecting this update and synchronizing it in its backend (like redis).
--- a/web/request.py Fri Feb 19 12:11:31 2016 +0100
+++ b/web/request.py Mon Feb 29 17:07:56 2016 +0100
@@ -884,9 +884,15 @@
self.session.data.pop(self.pageid, None)
else:
try:
- del self.session.data[self.pageid][key]
+ page_data = self.session.data[self.pageid]
+ del page_data[key]
except KeyError:
pass
+ else:
+ # make sure we write the session data value in the
+ # self.session.data dict-like object so any session
+ # handler can "detect" and manage the persistency
+ self.session.data[self.pageid] = page_data
# user-agent detection ####################################################
--- a/web/views/autoform.py Fri Feb 19 12:11:31 2016 +0100
+++ b/web/views/autoform.py Mon Feb 29 17:07:56 2016 +0100
@@ -484,13 +484,19 @@
def _add_pending(req, eidfrom, rel, eidto, kind):
key = 'pending_%s' % kind
- pendings = req.session.data.setdefault(key, set())
- pendings.add( (int(eidfrom), rel, int(eidto)) )
+ pendings = req.session.data.get(key, [])
+ value = (int(eidfrom), rel, int(eidto))
+ if value not in pendings:
+ pendings.append(value)
+ req.session.data[key] = pendings
def _remove_pending(req, eidfrom, rel, eidto, kind):
key = 'pending_%s' % kind
pendings = req.session.data[key]
- pendings.remove( (int(eidfrom), rel, int(eidto)) )
+ value = (int(eidfrom), rel, int(eidto))
+ if value in pendings:
+ pendings.remove(value)
+ req.session.data[key] = pendings
@ajaxfunc(output_type='json')
def remove_pending_insert(self, args):