From 0b910874899b3c7cd839e8b0a0a8416e44e348bc Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Tue, 8 Sep 2015 22:05:36 +0200 Subject: [PATCH] Write to session in batch at the end of the request --- lib/private/session/cryptosessiondata.php | 22 ++++++++++++++++++---- lib/private/session/internal.php | 8 ++++---- tests/lib/session/cryptowrappingtest.php | 9 --------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/lib/private/session/cryptosessiondata.php b/lib/private/session/cryptosessiondata.php index a0d180757b..6826ede5e3 100644 --- a/lib/private/session/cryptosessiondata.php +++ b/lib/private/session/cryptosessiondata.php @@ -38,6 +38,8 @@ class CryptoSessionData implements \ArrayAccess, ISession { protected $passphrase; /** @var array */ protected $sessionValues; + /** @var bool */ + protected $isModified = false; CONST encryptedSessionName = 'encrypted_session_data'; /** @@ -54,6 +56,13 @@ class CryptoSessionData implements \ArrayAccess, ISession { $this->initializeSession(); } + /** + * Close session if class gets destructed + */ + public function __destruct() { + $this->close(); + } + protected function initializeSession() { $encryptedSessionData = $this->session->get(self::encryptedSessionName); try { @@ -74,8 +83,7 @@ class CryptoSessionData implements \ArrayAccess, ISession { */ public function set($key, $value) { $this->sessionValues[$key] = $value; - $encryptedValue = $this->crypto->encrypt(json_encode($this->sessionValues), $this->passphrase); - $this->session->set(self::encryptedSessionName, $encryptedValue); + $this->isModified = true; } /** @@ -85,7 +93,6 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @return string|null Either the value or null */ public function get($key) { - if(isset($this->sessionValues[$key])) { return $this->sessionValues[$key]; } @@ -109,6 +116,7 @@ class CryptoSessionData implements \ArrayAccess, ISession { * @param string $key */ public function remove($key) { + $this->isModified = true; unset($this->sessionValues[$key]); $this->session->remove(self::encryptedSessionName); } @@ -118,13 +126,19 @@ class CryptoSessionData implements \ArrayAccess, ISession { */ public function clear() { $this->sessionValues = []; + $this->isModified = true; $this->session->clear(); } /** - * Close the session and release the lock + * Close the session and release the lock, also writes all changed data in batch */ public function close() { + if($this->isModified) { + $encryptedValue = $this->crypto->encrypt(json_encode($this->sessionValues), $this->passphrase); + $this->session->set(self::encryptedSessionName, $encryptedValue); + $this->isModified = false; + } $this->session->close(); } diff --git a/lib/private/session/internal.php b/lib/private/session/internal.php index 7719788775..8ee2127210 100644 --- a/lib/private/session/internal.php +++ b/lib/private/session/internal.php @@ -32,6 +32,10 @@ namespace OC\Session; * @package OC\Session */ class Internal extends Session { + /** + * @param string $name + * @throws \Exception + */ public function __construct($name) { session_name($name); set_error_handler(array($this, 'trapError')); @@ -42,10 +46,6 @@ class Internal extends Session { } } - public function __destruct() { - $this->close(); - } - /** * @param string $key * @param integer $value diff --git a/tests/lib/session/cryptowrappingtest.php b/tests/lib/session/cryptowrappingtest.php index 1cbe60066f..e1fadbf933 100644 --- a/tests/lib/session/cryptowrappingtest.php +++ b/tests/lib/session/cryptowrappingtest.php @@ -57,15 +57,6 @@ class CryptoWrappingTest extends TestCase { $this->instance = new CryptoSessionData($this->wrappedSession, $this->crypto, 'PASS'); } - public function testWrappingSet() { - $unencryptedValue = 'foobar'; - - $this->wrappedSession->expects($this->once()) - ->method('set') - ->with('encrypted_session_data', $this->crypto->encrypt(json_encode(['encrypted_session_data' => $unencryptedValue]))); - $this->instance->set('encrypted_session_data', $unencryptedValue); - } - public function testUnwrappingGet() { $unencryptedValue = 'foobar'; $encryptedValue = $this->crypto->encrypt($unencryptedValue);