Merge pull request #18913 from owncloud/put-in-single-field-for-speed
Put session data in single field for speed
This commit is contained in:
commit
a05ccd969c
|
@ -177,8 +177,6 @@ class Server extends SimpleContainer implements IServerContainer {
|
||||||
$manager = $c->getUserManager();
|
$manager = $c->getUserManager();
|
||||||
|
|
||||||
$session = new \OC\Session\Memory('');
|
$session = new \OC\Session\Memory('');
|
||||||
$cryptoWrapper = $c->getSessionCryptoWrapper();
|
|
||||||
$session = $cryptoWrapper->wrapSession($session);
|
|
||||||
|
|
||||||
$userSession = new \OC\User\Session($manager, $session);
|
$userSession = new \OC\User\Session($manager, $session);
|
||||||
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
|
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
|
||||||
|
@ -252,7 +250,7 @@ class Server extends SimpleContainer implements IServerContainer {
|
||||||
|
|
||||||
if($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
|
if($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
|
||||||
$v = \OC_App::getAppVersions();
|
$v = \OC_App::getAppVersions();
|
||||||
$v['core'] = implode('.', \OC_Util::getVersion());
|
$v['core'] = md5(file_get_contents(\OC::$SERVERROOT . '/version.php'));
|
||||||
$version = implode(',', $v);
|
$version = implode(',', $v);
|
||||||
$instanceId = \OC_Util::getInstanceId();
|
$instanceId = \OC_Util::getInstanceId();
|
||||||
$path = \OC::$SERVERROOT;
|
$path = \OC::$SERVERROOT;
|
||||||
|
|
|
@ -32,22 +32,47 @@ use OCP\Security\ICrypto;
|
||||||
class CryptoSessionData implements \ArrayAccess, ISession {
|
class CryptoSessionData implements \ArrayAccess, ISession {
|
||||||
/** @var ISession */
|
/** @var ISession */
|
||||||
protected $session;
|
protected $session;
|
||||||
|
|
||||||
/** @var \OCP\Security\ICrypto */
|
/** @var \OCP\Security\ICrypto */
|
||||||
protected $crypto;
|
protected $crypto;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $passphrase;
|
protected $passphrase;
|
||||||
|
/** @var array */
|
||||||
|
protected $sessionValues;
|
||||||
|
/** @var bool */
|
||||||
|
protected $isModified = false;
|
||||||
|
CONST encryptedSessionName = 'encrypted_session_data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ISession $session
|
* @param ISession $session
|
||||||
* @param ICrypto $crypto
|
* @param ICrypto $crypto
|
||||||
* @param string $passphrase
|
* @param string $passphrase
|
||||||
*/
|
*/
|
||||||
public function __construct(ISession $session, ICrypto $crypto, $passphrase) {
|
public function __construct(ISession $session,
|
||||||
|
ICrypto $crypto,
|
||||||
|
$passphrase) {
|
||||||
$this->crypto = $crypto;
|
$this->crypto = $crypto;
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
$this->passphrase = $passphrase;
|
$this->passphrase = $passphrase;
|
||||||
|
$this->initializeSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close session if class gets destructed
|
||||||
|
*/
|
||||||
|
public function __destruct() {
|
||||||
|
$this->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function initializeSession() {
|
||||||
|
$encryptedSessionData = $this->session->get(self::encryptedSessionName);
|
||||||
|
try {
|
||||||
|
$this->sessionValues = json_decode(
|
||||||
|
$this->crypto->decrypt($encryptedSessionData, $this->passphrase),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->sessionValues = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,8 +82,8 @@ class CryptoSessionData implements \ArrayAccess, ISession {
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
public function set($key, $value) {
|
public function set($key, $value) {
|
||||||
$encryptedValue = $this->crypto->encrypt(json_encode($value), $this->passphrase);
|
$this->sessionValues[$key] = $value;
|
||||||
$this->session->set($key, $encryptedValue);
|
$this->isModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,17 +93,11 @@ class CryptoSessionData implements \ArrayAccess, ISession {
|
||||||
* @return string|null Either the value or null
|
* @return string|null Either the value or null
|
||||||
*/
|
*/
|
||||||
public function get($key) {
|
public function get($key) {
|
||||||
$encryptedValue = $this->session->get($key);
|
if(isset($this->sessionValues[$key])) {
|
||||||
if ($encryptedValue === null) {
|
return $this->sessionValues[$key];
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return null;
|
||||||
$value = $this->crypto->decrypt($encryptedValue, $this->passphrase);
|
|
||||||
return json_decode($value);
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,7 +107,7 @@ class CryptoSessionData implements \ArrayAccess, ISession {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function exists($key) {
|
public function exists($key) {
|
||||||
return $this->session->exists($key);
|
return isset($this->sessionValues[$key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,20 +116,29 @@ class CryptoSessionData implements \ArrayAccess, ISession {
|
||||||
* @param string $key
|
* @param string $key
|
||||||
*/
|
*/
|
||||||
public function remove($key) {
|
public function remove($key) {
|
||||||
$this->session->remove($key);
|
$this->isModified = true;
|
||||||
|
unset($this->sessionValues[$key]);
|
||||||
|
$this->session->remove(self::encryptedSessionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset and recreate the session
|
* Reset and recreate the session
|
||||||
*/
|
*/
|
||||||
public function clear() {
|
public function clear() {
|
||||||
|
$this->sessionValues = [];
|
||||||
|
$this->isModified = true;
|
||||||
$this->session->clear();
|
$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() {
|
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();
|
$this->session->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,10 @@ namespace OC\Session;
|
||||||
* @package OC\Session
|
* @package OC\Session
|
||||||
*/
|
*/
|
||||||
class Internal extends Session {
|
class Internal extends Session {
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
public function __construct($name) {
|
public function __construct($name) {
|
||||||
session_name($name);
|
session_name($name);
|
||||||
set_error_handler(array($this, 'trapError'));
|
set_error_handler(array($this, 'trapError'));
|
||||||
|
@ -42,10 +46,6 @@ class Internal extends Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __destruct() {
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param integer $value
|
* @param integer $value
|
||||||
|
|
|
@ -57,26 +57,17 @@ class CryptoWrappingTest extends TestCase {
|
||||||
$this->instance = new CryptoSessionData($this->wrappedSession, $this->crypto, 'PASS');
|
$this->instance = new CryptoSessionData($this->wrappedSession, $this->crypto, 'PASS');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testWrappingSet() {
|
|
||||||
$unencryptedValue = 'foobar';
|
|
||||||
|
|
||||||
$this->wrappedSession->expects($this->once())
|
|
||||||
->method('set')
|
|
||||||
->with('key', $this->crypto->encrypt(json_encode($unencryptedValue)));
|
|
||||||
$this->instance->set('key', $unencryptedValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testUnwrappingGet() {
|
public function testUnwrappingGet() {
|
||||||
$unencryptedValue = 'foobar';
|
$unencryptedValue = 'foobar';
|
||||||
$encryptedValue = $this->crypto->encrypt($unencryptedValue);
|
$encryptedValue = $this->crypto->encrypt($unencryptedValue);
|
||||||
|
|
||||||
$this->wrappedSession->expects($this->once())
|
$this->wrappedSession->expects($this->once())
|
||||||
->method('get')
|
->method('get')
|
||||||
->with('key')
|
->with('encrypted_session_data')
|
||||||
->willReturnCallback(function () use ($encryptedValue) {
|
->willReturnCallback(function () use ($encryptedValue) {
|
||||||
return $encryptedValue;
|
return $encryptedValue;
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->assertSame($unencryptedValue, $this->wrappedSession->get('key'));
|
$this->assertSame($unencryptedValue, $this->wrappedSession->get('encrypted_session_data'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue