Opened 7 years ago
Closed 7 years ago
#12929 closed defect (fixed)
Known users cache may not be invalidated when creating a session
Reported by: | Ryan J Ollos | Owned by: | Ryan J Ollos |
---|---|---|---|
Priority: | normal | Milestone: | 1.2.3 |
Component: | general | Version: | |
Severity: | normal | Keywords: | |
Cc: | Branch: | ||
Release Notes: | |||
API Changes: |
Authenticated session without any session attributes is persisted when the session is saved. Previously the session would only be persisted if one or more session attributes were set. |
||
Internal Changes: |
Description
The case was missed in #11868. The known users cache will not be invalidated when creating a session without setting the name and email.
session = DetachedSession(self.env, sid) session['authenticated'] = True session.save()
Attachments (0)
Change History (3)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
The authenticated
is an attribute of session object, not an item of the object.
-session['authenticated'] = True +session.authenticated = True
>>> from trac.test import EnvironmentStub, MockRequest >>> from trac.web.session import Session >>> env = EnvironmentStub() >>> req = MockRequest(env, authname='user') >>> req.authname 'user' >>> sess = Session(env, req) >>> sess.authenticated True >>> list(env.get_known_users()) [] >>> sess.save() >>> list(env.get_known_users()) [] # should be 1 entry
Currently, new session without associated data is not be persisted, even if authenticated/anonymous session.
def save(self): items = self.items() if not self._old and not items: # The session doesn't have associated data, so there's no need to # persist it return
If we should persist new authenticated session without associated data:
-
trac/web/session.py
diff --git a/trac/web/session.py b/trac/web/session.py index 2b43535e5..d1ef6fd40 100644
a b class DetachedSession(SessionDict): 136 136 self._old = {} 137 137 138 138 def save(self): 139 items = self.items()140 if not self._old and not items:141 # The session doesn't have associated data, so there's no need to142 # persist it143 return144 145 139 authenticated = int(self.authenticated) 146 140 now = int(time_now()) 141 items = self.items() 142 if not authenticated and not self._old and not items: 143 # The session for anonymous doesn't have associated data, 144 # so there's no need to persist it 145 return 147 146 148 147 # We can't do the session management in one big transaction, 149 148 # as the intertwined changes to both the session and … … class DetachedSession(SessionDict): 173 172 db.rollback() 174 173 return 175 174 175 if authenticated and \ 176 (new or self._old.get('name') != self.get('name') or \ 177 self._old.get('email') != self.get('email')): 178 self.env.invalidate_known_users_cache() 179 176 180 # Remove former values for session_attribute and save the 177 181 # new ones. The last concurrent request to do so "wins". 178 182 179 183 if self._old != self: 180 if new or self._old.get('name') != self.get('name') or \181 self._old.get('email') != self.get('email'):182 self.env.invalidate_known_users_cache()183 184 if not items and not authenticated: 184 185 # No need to keep around empty unauthenticated sessions 185 186 db("DELETE FROM session WHERE sid=%s AND authenticated=0", -
trac/web/tests/session.py
diff --git a/trac/web/tests/session.py b/trac/web/tests/session.py index 6f0b01b91..f20984e21 100644
a b class SessionTestCase(unittest.TestCase): 563 563 """Setting attribute on a new session invalidates known_users cache.""" 564 564 sid = 'user' 565 565 session = DetachedSession(self.env, sid) 566 session ['authenticated']= True566 session.authenticated = True 567 567 568 568 self.assertEqual([], list(self.env.get_known_users())) 569 569 session.save() … … class SessionTestCase(unittest.TestCase): 573 573 self.assertIsNone(known_users[0][1]) 574 574 self.assertIsNone(known_users[0][2]) 575 575 576 def test_create_new_anonymous_session(self): 577 """Setting attribute on a new anonymous session doesn't invalidate 578 known_users cache.""" 579 sid = 'anonymous' 580 session = DetachedSession(self.env, sid) 581 session.authenticated = False 582 583 self.assertEqual([], list(self.env.get_known_users())) 584 # insert a session record without invalidating cache 585 self.env.insert_users([('user', 'Name' 'user@example.com', 1)]) 586 session.save() 587 self.assertEqual([], list(self.env.get_known_users())) 588 589 self.env.invalidate_known_users_cache() 590 self.assertEqual(1, len(list(self.env.get_known_users()))) 591 576 592 def test_session_set_email(self): 577 593 """Setting session email invalidates known_users cache.""" 578 594 sid = 'user'
Proposed changes: [54236d4d1/rjollos.git].