From 1b7714d21faf23d83cd458fa5eff9939470e3a65 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Thu, 2 Jan 2025 17:43:13 +0000
Subject: [PATCH] adjust session handling so that it corresponds to the
 previous behaviour, fixes #5038

Closes #5038

Merge request studip/studip!3791
---
 lib/cronjobs/session_gc.php |  2 +-
 lib/session/Manager.php     | 46 +++++++++++++++++++++++++------------
 2 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/lib/cronjobs/session_gc.php b/lib/cronjobs/session_gc.php
index 25d5f6c6f88..07d81e81d3e 100644
--- a/lib/cronjobs/session_gc.php
+++ b/lib/cronjobs/session_gc.php
@@ -22,6 +22,6 @@ class SessionGcJob extends CronJob
 
     public function execute($last_result, $parameters = [])
     {
-        return sess()->doGarbageCollect();
+        sess()->doGarbageCollect();
     }
 }
diff --git a/lib/session/Manager.php b/lib/session/Manager.php
index 3603d886e4e..169d89ed321 100644
--- a/lib/session/Manager.php
+++ b/lib/session/Manager.php
@@ -11,7 +11,6 @@
  */
 namespace Studip\Session;
 
-
 class Manager
 {
     public const STATE_UNKNOWN = false;
@@ -53,21 +52,23 @@ class Manager
     {
         if (!$this->isStarted()) {
             ini_set('session.use_strict_mode', 1);
-            $current = session_get_cookie_params();
 
-            $lifetime = (int) ($this->options['lifetime'] ?: $current['lifetime']);
-            $path = $this->options['path'] ?: $current['path'];
-            $domain = $this->options['domain'] ?: $current['domain'];
-            $samesite = $this->options['samesite'] ?: $current['samesite'];
-            $secure = (bool) $this->options['secure'];
-            $httponly = (bool) $this->options['httponly'];
+            session_set_cookie_params([
+                'lifetime' => 0,
+                'path'     => $this->getCookieParam('path'),
+                'domain'   => $this->getCookieParam('domain'),
+                'secure'   => (bool) $this->getCookieParam('secure', false),
+                'samesite' => $this->getCookieParam('samesite'),
+                'httponly' => (bool) $this->getCookieParam('httponly', false),
+            ]);
 
-            session_set_cookie_params(compact('lifetime', 'path', 'domain', 'secure', 'samesite', 'httponly'));
             session_name($this->options['name']);
             session_cache_limiter('nocache');
             session_set_save_handler($this->handler, true);
 
-            session_start();
+            session_start([
+                'gc_maxlifetime' => (int) $this->getCookieParam('lifetime'),
+            ]);
         }
     }
 
@@ -103,6 +104,25 @@ class Manager
         return $this->options['name'];
     }
 
+    /**
+     * Returns the value for the given cookie parameter. The value is taken
+     * from the configured options array (or from the current session
+     * configuration in php).
+     *
+     * If no value is found, null is retuned.
+     */
+    public function getCookieParam(string $key, bool $from_config = true): mixed
+    {
+        $value = $this->options[$key] ?? null;
+
+        if ($from_config) {
+            $current = session_get_cookie_params();
+            $value = $value ?: $current[$key] ?? null;
+        }
+
+        return $value;
+    }
+
     public function destroy(): void
     {
         if (!$this->isStarted()) {
@@ -174,12 +194,8 @@ class Manager
     /**
      * returns a SessionDecoder object containing the session variables
      * for the given session id
-     *
-     * @static
-     * @param string $sid a session id
-     * @return \SessionDecoder
      */
-    public function getSessionVars($sid): \SessionDecoder
+    public function getSessionVars(string $sid): \SessionDecoder
     {
         $data = $this->handler->read($sid);
         return new \SessionDecoder($data);
-- 
GitLab