public inbox for [email protected]  
help / color / mirror / Atom feed
From: Aditya Toshniwal <[email protected]>
To: pgadmin-hackers <[email protected]>
Subject: [pgAdmin4][RM3371] Ping endpoint still send a pg4a_session cookie
Date: Mon, 2 Jul 2018 18:05:59 +0530
Message-ID: <CAM9w-_=9x+L5S7OUGreVu-je9ADJPJv37uQ5UWqCYtGPw=5G6w@mail.gmail.com> (raw)

Hi Hackers,

Attached is the patch for fixing RM3371 where /misc/ping service generate
session file for each call and so cannot be used frequently.
The patch is to skip session file generation and session caching for the
URLs provided in SESSION_SKIP_PATH list config parameter.
pg4a_session_cookie value will still be generated but nothing will be
stored at the backend.
Also, I have separated the garbage collection code in current ping service
to a new url /misc/cleanup. /misc/ping will be purely for is alive check.

Request you to kindly review.

-- 
Thanks and Regards,
Aditya Toshniwal
Software Engineer | EnterpriseDB Software Solutions | Pune
"Don't Complain about Heat, Plant a tree"


Attachments:

  [application/octet-stream] RM3371.patch (7.3K, 3-RM3371.patch)
  download | inline diff:
diff --git a/web/config.py b/web/config.py
index a8a9ce01..128ad11b 100644
--- a/web/config.py
+++ b/web/config.py
@@ -391,3 +391,11 @@ if (SUPPORT_SSH_TUNNEL is True and
     ((sys.version_info[0] == 2 and sys.version_info[1] < 7) or
      (sys.version_info[0] == 3 and sys.version_info[1] < 4))):
     SUPPORT_SSH_TUNNEL = False
+
+
+#########################################################################
+# Skip session stroing in files and cache for paths
+#########################################################################
+SESSION_SKIP_PATHS = [
+    '/misc/ping'
+]
diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py
index e4c9c484..5926559d 100644
--- a/web/pgadmin/__init__.py
+++ b/web/pgadmin/__init__.py
@@ -354,7 +354,9 @@ def create_app(app_name=None):
     # register custom unauthorised handler.
     app.login_manager.unauthorized_handler(pga_unauthorised)
 
-    app.session_interface = create_session_interface(app)
+    app.session_interface = create_session_interface(
+        app, config.SESSION_SKIP_PATHS
+    )
 
     # Make the Session more secure against XSS & CSRF when running in web mode
     if config.SERVER_MODE:
diff --git a/web/pgadmin/browser/static/js/browser.js b/web/pgadmin/browser/static/js/browser.js
index b26738cf..d0efe468 100644
--- a/web/pgadmin/browser/static/js/browser.js
+++ b/web/pgadmin/browser/static/js/browser.js
@@ -490,7 +490,7 @@ define('pgadmin.browser', [
       // Ping the server every 5 minutes
       setInterval(function() {
         $.ajax({
-          url: url_for('misc.ping'),
+          url: url_for('misc.cleanup'),
           type:'POST',
           success: function() {},
           error: function() {},
diff --git a/web/pgadmin/misc/__init__.py b/web/pgadmin/misc/__init__.py
index 55e3fe73..ad4f9254 100644
--- a/web/pgadmin/misc/__init__.py
+++ b/web/pgadmin/misc/__init__.py
@@ -74,7 +74,7 @@ class MiscModule(PgAdminModule):
         Returns:
             list: a list of url endpoints exposed to the client.
         """
-        return ['misc.ping', 'misc.index']
+        return ['misc.ping', 'misc.index', 'misc.cleanup']
 
 
 # Initialise the module
@@ -92,14 +92,19 @@ def index():
 ##########################################################################
 # A special URL used to "ping" the server
 ##########################################################################
[email protected]("/ping", methods=('get', 'post'))
[email protected]("/ping")
 def ping():
     """Generate a "PING" response to indicate that the server is alive."""
-    driver.ping()
-
     return "PING"
 
 
+# For Garbage Collecting closed connections
[email protected]("/cleanup", methods=['POST'])
+def cleanup():
+    driver.ping()
+    return ""
+
+
 @blueprint.route("/explain/explain.js")
 def explain_js():
     """
diff --git a/web/pgadmin/utils/session.py b/web/pgadmin/utils/session.py
index 266f83b3..fa313e0a 100644
--- a/web/pgadmin/utils/session.py
+++ b/web/pgadmin/utils/session.py
@@ -102,10 +102,11 @@ class SessionManager(object):
 
 
 class CachingSessionManager(SessionManager):
-    def __init__(self, parent, num_to_store):
+    def __init__(self, parent, num_to_store, skip_paths=[]):
         self.parent = parent
         self.num_to_store = num_to_store
         self._cache = OrderedDict()
+        self.skip_paths = skip_paths
 
     def _normalize(self):
         if len(self._cache) > self.num_to_store:
@@ -115,6 +116,12 @@ class CachingSessionManager(SessionManager):
 
     def new_session(self):
         session = self.parent.new_session()
+
+        # Do not store the session if skip paths
+        for sp in self.skip_paths:
+            if request.path.startswith(sp):
+                return session
+
         self._cache[session.sid] = session
         self._normalize()
 
@@ -143,6 +150,11 @@ class CachingSessionManager(SessionManager):
         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
+
         self._cache[sid] = session
         self._normalize()
 
@@ -150,23 +162,31 @@ class CachingSessionManager(SessionManager):
 
     def put(self, session):
         self.parent.put(session)
+
+        # 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
+
         self._cache[session.sid] = session
         self._normalize()
 
 
 class FileBackedSessionManager(SessionManager):
 
-    def __init__(self, path, secret, disk_write_delay):
+    def __init__(self, path, secret, disk_write_delay, skip_paths=[]):
         self.path = path
         self.secret = secret
         self.disk_write_delay = disk_write_delay
         if not os.path.exists(self.path):
             os.makedirs(self.path)
+        self.skip_paths = skip_paths
 
     def exists(self, sid):
         fname = os.path.join(self.path, sid)
@@ -185,6 +205,11 @@ class FileBackedSessionManager(SessionManager):
             sid = str(uuid4())
             fname = os.path.join(self.path, sid)
 
+        # Do not store the session if skip paths
+        for sp in self.skip_paths:
+            if request.path.startswith(sp):
+                return ManagedSession(sid=sid)
+
         # touch the file
         with open(fname, 'wb'):
             pass
@@ -233,6 +258,12 @@ class FileBackedSessionManager(SessionManager):
 
         session.last_write = current_time
         session.force_write = False
+
+        # Do not store the session if skip paths
+        for sp in self.skip_paths:
+            if request.path.startswith(sp):
+                return
+
         fname = os.path.join(self.path, session.sid)
         with open(fname, 'wb') as f:
             dump(
@@ -242,9 +273,8 @@ class FileBackedSessionManager(SessionManager):
 
 
 class ManagedSessionInterface(SessionInterface):
-    def __init__(self, manager, skip_paths, cookie_timedelta):
+    def __init__(self, manager, cookie_timedelta):
         self.manager = manager
-        self.skip_paths = skip_paths
         self.cookie_timedelta = cookie_timedelta
 
     def get_expiration_time(self, app, session):
@@ -256,11 +286,6 @@ class ManagedSessionInterface(SessionInterface):
         cookie_val = request.cookies.get(app.session_cookie_name)
 
         if not cookie_val or '!' not in cookie_val:
-            # Don't bother creating a cookie for static resources
-            for sp in self.skip_paths:
-                if request.path.startswith(sp):
-                    return None
-
             return self.manager.new_session()
 
         sid, digest = cookie_val.split('!', 1)
@@ -301,10 +326,12 @@ def create_session_interface(app, skip_paths=[]):
             FileBackedSessionManager(
                 app.config['SESSION_DB_PATH'],
                 app.config['SECRET_KEY'],
-                app.config.get('PGADMIN_SESSION_DISK_WRITE_DELAY', 10)
+                app.config.get('PGADMIN_SESSION_DISK_WRITE_DELAY', 10),
+                skip_paths
             ),
-            1000
-        ), skip_paths,
+            1000,
+            skip_paths
+        ),
         datetime.timedelta(days=1))
 
 


view thread (4+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected]
  Subject: Re: [pgAdmin4][RM3371] Ping endpoint still send a pg4a_session cookie
  In-Reply-To: <CAM9w-_=9x+L5S7OUGreVu-je9ADJPJv37uQ5UWqCYtGPw=5G6w@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox