remotes/origin/notification-style
parent
510010e774
commit
36eef2ddab
@ -0,0 +1,140 @@ |
||||
<?php |
||||
/** |
||||
* @author Joas Schilling <nickvergessen@owncloud.com> |
||||
* |
||||
* @copyright Copyright (c) 2015, ownCloud, Inc. |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
* |
||||
*/ |
||||
|
||||
namespace OC\Session; |
||||
|
||||
|
||||
use OCP\ISession; |
||||
use OCP\Security\ICrypto; |
||||
|
||||
class CryptoSessionData implements \ArrayAccess, ISession { |
||||
/** @var ISession */ |
||||
protected $session; |
||||
|
||||
/** @var \OCP\Security\ICrypto */ |
||||
protected $crypto; |
||||
|
||||
/** @var string */ |
||||
protected $passphrase; |
||||
|
||||
/** |
||||
* @param ISession $session |
||||
* @param ICrypto $crypto |
||||
* @param string $passphrase |
||||
*/ |
||||
public function __construct(ISession $session, ICrypto $crypto, $passphrase) { |
||||
$this->crypto = $crypto; |
||||
$this->session = $session; |
||||
$this->passphrase = $passphrase; |
||||
} |
||||
|
||||
/** |
||||
* Set a value in the session |
||||
* |
||||
* @param string $key |
||||
* @param mixed $value |
||||
*/ |
||||
public function set($key, $value) { |
||||
$encryptedValue = $this->crypto->encrypt($value, $this->passphrase); |
||||
$this->session->set($key, $encryptedValue); |
||||
} |
||||
|
||||
/** |
||||
* Get a value from the session |
||||
* |
||||
* @param string $key |
||||
* @return mixed should return null if $key does not exist |
||||
* @throws \Exception when the data could not be decrypted |
||||
*/ |
||||
public function get($key) { |
||||
$encryptedValue = $this->session->get($key); |
||||
if ($encryptedValue === null) { |
||||
return null; |
||||
} |
||||
|
||||
$value = $this->crypto->decrypt($encryptedValue, $this->passphrase); |
||||
return $value; |
||||
} |
||||
|
||||
/** |
||||
* Check if a named key exists in the session |
||||
* |
||||
* @param string $key |
||||
* @return bool |
||||
*/ |
||||
public function exists($key) { |
||||
return $this->session->exists($key); |
||||
} |
||||
|
||||
/** |
||||
* Remove a $key/$value pair from the session |
||||
* |
||||
* @param string $key |
||||
*/ |
||||
public function remove($key) { |
||||
$this->session->remove($key); |
||||
} |
||||
|
||||
/** |
||||
* Reset and recreate the session |
||||
*/ |
||||
public function clear() { |
||||
$this->session->clear(); |
||||
} |
||||
|
||||
/** |
||||
* Close the session and release the lock |
||||
*/ |
||||
public function close() { |
||||
$this->session->close(); |
||||
} |
||||
|
||||
/** |
||||
* @param mixed $offset |
||||
* @return bool |
||||
*/ |
||||
public function offsetExists($offset) { |
||||
return $this->exists($offset); |
||||
} |
||||
|
||||
/** |
||||
* @param mixed $offset |
||||
* @return mixed |
||||
*/ |
||||
public function offsetGet($offset) { |
||||
return $this->get($offset); |
||||
} |
||||
|
||||
/** |
||||
* @param mixed $offset |
||||
* @param mixed $value |
||||
*/ |
||||
public function offsetSet($offset, $value) { |
||||
$this->set($offset, $value); |
||||
} |
||||
|
||||
/** |
||||
* @param mixed $offset |
||||
*/ |
||||
public function offsetUnset($offset) { |
||||
$this->remove($offset); |
||||
} |
||||
} |
||||
@ -0,0 +1,81 @@ |
||||
<?php |
||||
/** |
||||
* @author Joas Schilling <nickvergessen@owncloud.com> |
||||
* |
||||
* @copyright Copyright (c) 2015, ownCloud, Inc. |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
* |
||||
*/ |
||||
|
||||
namespace OC\Session; |
||||
|
||||
use OCP\IConfig; |
||||
use OCP\ISession; |
||||
use OCP\Security\ICrypto; |
||||
use OCP\Security\ISecureRandom; |
||||
|
||||
class CryptoWrapper { |
||||
const COOKIE_NAME = 'oc_sessionPassphrase'; |
||||
|
||||
/** @var ISession */ |
||||
protected $session; |
||||
|
||||
/** @var \OCP\Security\ICrypto */ |
||||
protected $crypto; |
||||
|
||||
/** @var ISecureRandom */ |
||||
protected $random; |
||||
|
||||
/** |
||||
* @param IConfig $config |
||||
* @param ICrypto $crypto |
||||
* @param ISecureRandom $random |
||||
*/ |
||||
public function __construct(IConfig $config, ICrypto $crypto, ISecureRandom $random) { |
||||
$this->crypto = $crypto; |
||||
$this->config = $config; |
||||
$this->random = $random; |
||||
|
||||
if (isset($_COOKIE[self::COOKIE_NAME])) { |
||||
// TODO circular dependency |
||||
// $request = \OC::$server->getRequest(); |
||||
// $this->passphrase = $request->getCookie(self::COOKIE_NAME); |
||||
$this->passphrase = $_COOKIE[self::COOKIE_NAME]; |
||||
} else { |
||||
$this->passphrase = $this->random->getMediumStrengthGenerator()->generate(128); |
||||
|
||||
// TODO circular dependency |
||||
// $secureCookie = \OC::$server->getRequest()->getServerProtocol() === 'https'; |
||||
$secureCookie = false; |
||||
$expires = time() + $this->config->getSystemValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15); |
||||
|
||||
if (!defined('PHPUNIT_RUN')) { |
||||
setcookie(self::COOKIE_NAME, $this->passphrase, $expires, \OC::$WEBROOT, '', $secureCookie); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param ISession $session |
||||
* @return ISession |
||||
*/ |
||||
public function wrapSession(ISession $session) { |
||||
if (!($session instanceof CryptoSessionData) && $this->config->getSystemValue('encrypt.session', false)) { |
||||
return new \OC\Session\CryptoSessionData($session, $this->crypto, $this->passphrase); |
||||
} |
||||
|
||||
return $session; |
||||
} |
||||
} |
||||
@ -0,0 +1,53 @@ |
||||
<?php |
||||
/** |
||||
* @author Joas Schilling <nickvergessen@owncloud.com> |
||||
* |
||||
* @copyright Copyright (c) 2015, ownCloud, Inc. |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
* |
||||
*/ |
||||
|
||||
namespace Test\Session; |
||||
|
||||
use OC\Session\CryptoSessionData; |
||||
|
||||
class CryptoSessionDataTest extends Session { |
||||
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCP\Security\ICrypto */ |
||||
protected $crypto; |
||||
|
||||
/** @var \OCP\ISession */ |
||||
protected $wrappedSession; |
||||
|
||||
protected function setUp() { |
||||
parent::setUp(); |
||||
|
||||
$this->wrappedSession = new \OC\Session\Memory($this->getUniqueID()); |
||||
$this->crypto = $this->getMockBuilder('OCP\Security\ICrypto') |
||||
->disableOriginalConstructor() |
||||
->getMock(); |
||||
$this->crypto->expects($this->any()) |
||||
->method('encrypt') |
||||
->willReturnCallback(function ($input) { |
||||
return '#' . $input . '#'; |
||||
}); |
||||
$this->crypto->expects($this->any()) |
||||
->method('decrypt') |
||||
->willReturnCallback(function ($input) { |
||||
return substr($input, 1, -1); |
||||
}); |
||||
|
||||
$this->instance = new CryptoSessionData($this->wrappedSession, $this->crypto, 'PASS'); |
||||
} |
||||
} |
||||
@ -0,0 +1,81 @@ |
||||
<?php |
||||
/** |
||||
* @author Joas Schilling <nickvergessen@owncloud.com> |
||||
* |
||||
* @copyright Copyright (c) 2015, ownCloud, Inc. |
||||
* @license AGPL-3.0 |
||||
* |
||||
* This code is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU Affero General Public License, version 3, |
||||
* as published by the Free Software Foundation. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Affero General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Affero General Public License, version 3, |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
||||
* |
||||
*/ |
||||
|
||||
namespace Test\Session; |
||||
|
||||
use OC\Session\CryptoSessionData; |
||||
use Test\TestCase; |
||||
|
||||
class CryptoWrappingTest extends TestCase { |
||||
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCP\Security\ICrypto */ |
||||
protected $crypto; |
||||
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCP\ISession */ |
||||
protected $wrappedSession; |
||||
|
||||
/** @var \OC\Session\CryptoSessionData */ |
||||
protected $instance; |
||||
|
||||
protected function setUp() { |
||||
parent::setUp(); |
||||
|
||||
$this->wrappedSession = $this->getMockBuilder('OCP\ISession') |
||||
->disableOriginalConstructor() |
||||
->getMock(); |
||||
$this->crypto = $this->getMockBuilder('OCP\Security\ICrypto') |
||||
->disableOriginalConstructor() |
||||
->getMock(); |
||||
$this->crypto->expects($this->any()) |
||||
->method('encrypt') |
||||
->willReturnCallback(function ($input) { |
||||
return '#' . $input . '#'; |
||||
}); |
||||
$this->crypto->expects($this->any()) |
||||
->method('decrypt') |
||||
->willReturnCallback(function ($input) { |
||||
return substr($input, 1, -1); |
||||
}); |
||||
|
||||
$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($unencryptedValue)); |
||||
$this->instance->set('key', $unencryptedValue); |
||||
} |
||||
|
||||
public function testUnwrappingGet() { |
||||
$unencryptedValue = 'foobar'; |
||||
$encryptedValue = $this->crypto->encrypt($unencryptedValue); |
||||
|
||||
$this->wrappedSession->expects($this->once()) |
||||
->method('get') |
||||
->with('key') |
||||
->willReturnCallback(function () use ($encryptedValue) { |
||||
return $encryptedValue; |
||||
}); |
||||
$this->assertSame($unencryptedValue, $this->instance->get('key')); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue