From d4d2df10d316e3da03a8be6edac564e16026b2f7 Mon Sep 17 00:00:00 2001
From: Ere Maijala <ere.maijala@helsinki.fi>
Date: Mon, 14 Nov 2016 11:42:05 +0200
Subject: [PATCH] Improved handling of limit_by_path session setting - Verify
 that any existing session path is correct - Avoid trying to set an empty path
 for the session cookie.

---
 module/VuFind/src/VuFind/Service/Factory.php    |  3 +++
 .../VuFind/src/VuFind/Session/AbstractBase.php  | 10 ++++++++++
 .../src/VuFind/Session/ManagerFactory.php       | 17 +++++++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/module/VuFind/src/VuFind/Service/Factory.php b/module/VuFind/src/VuFind/Service/Factory.php
index 27f6e2239db..6593137e45e 100644
--- a/module/VuFind/src/VuFind/Service/Factory.php
+++ b/module/VuFind/src/VuFind/Service/Factory.php
@@ -205,6 +205,9 @@ class Factory
             && $config->Cookies->limit_by_path
         ) {
             $path = $sm->get('Request')->getBasePath();
+            if (empty($path)) {
+                $path = '/';
+            }
         }
         $secure = isset($config->Cookies->only_secure)
             ? $config->Cookies->only_secure
diff --git a/module/VuFind/src/VuFind/Session/AbstractBase.php b/module/VuFind/src/VuFind/Session/AbstractBase.php
index d8231664bab..0adaa6914c3 100644
--- a/module/VuFind/src/VuFind/Session/AbstractBase.php
+++ b/module/VuFind/src/VuFind/Session/AbstractBase.php
@@ -66,6 +66,16 @@ abstract class AbstractBase implements SaveHandlerInterface,
      */
     protected $writesDisabled = false;
 
+    /**
+     * Enable session writing (default)
+     *
+     * @return void
+     */
+    public function enableWrites()
+    {
+        $this->writesDisabled = false;
+    }
+
     /**
      * Disable session writing, i.e. make it read-only
      *
diff --git a/module/VuFind/src/VuFind/Session/ManagerFactory.php b/module/VuFind/src/VuFind/Session/ManagerFactory.php
index f779d974a39..4210d729bd3 100644
--- a/module/VuFind/src/VuFind/Session/ManagerFactory.php
+++ b/module/VuFind/src/VuFind/Session/ManagerFactory.php
@@ -128,6 +128,23 @@ class ManagerFactory implements \Zend\ServiceManager\FactoryInterface
         // Start up the session:
         $sessionManager->start();
 
+        // Verify that any existing session has the correct path to avoid using
+        // a cookie from a service higher up in the path hierarchy.
+        $storage = new \Zend\Session\Container('SessionState', $sessionManager);
+        if (null !== $storage->cookiePath) {
+            if ($storage->cookiePath != $sessionConfig->getCookiePath()) {
+                // Disable writes temporarily to keep the existing session intact
+                $sessionManager->getSaveHandler()->disableWrites();
+                // Regenerate session ID and reset the session data
+                $sessionManager->regenerateId(false);
+                session_unset();
+                $sessionManager->getSaveHandler()->enableWrites();
+                $storage->cookiePath = $sessionConfig->getCookiePath();
+            }
+        } else {
+            $storage->cookiePath = $sessionConfig->getCookiePath();
+        }
+
         // Check if we need to immediately stop it based on the settings object
         // (which may have been informed by a controller that sessions should not
         // be written as part of the current process):
-- 
GitLab