Hi,
Please find attached patch to fix RM3547
Thanks,
--
*Harshal Dhumal*
*Sr. Software Engineer*
EnterpriseDB India: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
diff --git a/web/pgadmin/utils/session.py b/web/pgadmin/utils/session.py
index fa313e0..cdf39ce 100644
--- a/web/pgadmin/utils/session.py
+++ b/web/pgadmin/utils/session.py
@@ -24,6 +24,7 @@ import random
import string
import time
from uuid import uuid4
+from threading import Lock
from flask import current_app, request, flash, redirect
from flask_login import login_url
from pgadmin.utils.ajax import make_json_response
@@ -50,6 +51,9 @@ def _calc_hmac(body, secret):
).decode()
+sess_lock = Lock()
+
+
class ManagedSession(CallbackDict, SessionMixin):
def __init__(self, initial=None, sid=None, new=False, randval=None,
hmac_digest=None):
@@ -111,8 +115,9 @@ class CachingSessionManager(SessionManager):
def _normalize(self):
if len(self._cache) > self.num_to_store:
# Flush 20% of the cache
- while len(self._cache) > (self.num_to_store * 0.8):
- self._cache.popitem(False)
+ with sess_lock:
+ while len(self._cache) > (self.num_to_store * 0.8):
+ self._cache.popitem(False)
def new_session(self):
session = self.parent.new_session()
@@ -122,59 +127,64 @@ class CachingSessionManager(SessionManager):
if request.path.startswith(sp):
return session
- self._cache[session.sid] = session
+ with sess_lock:
+ self._cache[session.sid] = session
self._normalize()
return session
def remove(self, sid):
- self.parent.remove(sid)
- if sid in self._cache:
- del self._cache[sid]
+ with sess_lock:
+ self.parent.remove(sid)
+ if sid in self._cache:
+ del self._cache[sid]
def exists(self, sid):
- if sid in self._cache:
- return True
- return self.parent.exists(sid)
+ with sess_lock:
+ if sid in self._cache:
+ return True
+ return self.parent.exists(sid)
def get(self, sid, digest):
session = None
- if sid in self._cache:
- session = self._cache[sid]
- if session.hmac_digest != digest:
- session = None
+ with sess_lock:
+ if sid in self._cache:
+ session = self._cache[sid]
+ if session.hmac_digest != digest:
+ session = None
- # reset order in Dict
- del self._cache[sid]
+ # reset order in Dict
+ del self._cache[sid]
- if not session:
- session = self.parent.get(sid, digest)
+ if not session:
+ session = self.parent.get(sid, digest)
- # Do not store the session if skip paths
- for sp in self.skip_paths:
- if request.path.startswith(sp):
- return session
+ # Do not store the session if skip paths
+ for sp in self.skip_paths:
+ if request.path.startswith(sp):
+ return session
- self._cache[sid] = session
+ self._cache[sid] = session
self._normalize()
return session
def put(self, session):
- self.parent.put(session)
+ with sess_lock:
+ self.parent.put(session)
- # Do not store the session if skip paths
- for sp in self.skip_paths:
- if request.path.startswith(sp):
- return
+ # Do not store the session if skip paths
+ for sp in self.skip_paths:
+ if request.path.startswith(sp):
+ return
- if session.sid in self._cache:
- try:
- del self._cache[session.sid]
- except Exception:
- pass
+ if session.sid in self._cache:
+ try:
+ del self._cache[session.sid]
+ except Exception:
+ pass
- self._cache[session.sid] = session
+ self._cache[session.sid] = session
self._normalize()