Browse Source
Add new CSRF manager for unit testing purposes
Add new CSRF manager for unit testing purposes
This adds a new CSRF manager for unit testing purposes, it's interface is based upon https://github.com/symfony/security-csrf. Due to some of our required custom changes it is however not possible to use the Symfony component directly.remotes/origin/comments-markallread-dav
17 changed files with 762 additions and 79 deletions
-
30lib/private/appframework/http/request.php
-
69lib/private/security/csrf/csrftoken.php
-
52lib/private/security/csrf/csrftokengenerator.php
-
97lib/private/security/csrf/csrftokenmanager.php
-
80lib/private/security/csrf/tokenstorage/sessionstorage.php
-
27lib/private/server.php
-
4lib/private/template.php
-
5lib/private/template/base.php
-
2lib/private/user.php
-
36lib/private/util.php
-
16lib/public/util.php
-
90tests/lib/appframework/http/RequestTest.php
-
54tests/lib/security/csrf/CsrfTokenGeneratorTest.php
-
134tests/lib/security/csrf/CsrfTokenManagerTest.php
-
33tests/lib/security/csrf/CsrfTokenTest.php
-
107tests/lib/security/csrf/tokenstorage/SessionStorageTest.php
-
5tests/lib/util.php
@ -0,0 +1,69 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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\Security\CSRF; |
|||
|
|||
/** |
|||
* Class CsrfToken represents the stored or provided CSRF token. To mitigate |
|||
* BREACH alike vulnerabilities the token is returned in an encrypted value as |
|||
* well in an unencrypted value. For display measures to the user always the |
|||
* unencrypted one should be chosen. |
|||
* |
|||
* @package OC\Security\CSRF |
|||
*/ |
|||
class CsrfToken { |
|||
/** @var string */ |
|||
private $value; |
|||
|
|||
/** |
|||
* @param string $value Value of the token. Can be encrypted or not encrypted. |
|||
*/ |
|||
public function __construct($value) { |
|||
$this->value = $value; |
|||
} |
|||
|
|||
/** |
|||
* Encrypted value of the token. This is used to mitigate BREACH alike |
|||
* vulnerabilities. For display measures do use this functionality. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getEncryptedValue() { |
|||
$sharedSecret = base64_encode(random_bytes(strlen($this->value))); |
|||
return base64_encode($this->value ^ $sharedSecret) .':'.$sharedSecret; |
|||
} |
|||
|
|||
/** |
|||
* The unencrypted value of the token. Used for decrypting an already |
|||
* encrypted token. |
|||
* |
|||
* @return int |
|||
*/ |
|||
public function getDecryptedValue() { |
|||
$token = explode(':', $this->value); |
|||
if (count($token) !== 2) { |
|||
return ''; |
|||
} |
|||
$obfuscatedToken = $token[0]; |
|||
$secret = $token[1]; |
|||
return base64_decode($obfuscatedToken) ^ $secret; |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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\Security\CSRF; |
|||
|
|||
use OCP\Security\ISecureRandom; |
|||
|
|||
/** |
|||
* Class CsrfTokenGenerator is used to generate a cryptographically secure |
|||
* pseudo-random number for the token. |
|||
* |
|||
* @package OC\Security\CSRF |
|||
*/ |
|||
class CsrfTokenGenerator { |
|||
/** @var ISecureRandom */ |
|||
private $random; |
|||
|
|||
/** |
|||
* @param ISecureRandom $random |
|||
*/ |
|||
public function __construct(ISecureRandom $random) { |
|||
$this->random = $random; |
|||
} |
|||
|
|||
/** |
|||
* Generate a new CSRF token. |
|||
* |
|||
* @param int $length Length of the token in characters. |
|||
* @return string |
|||
*/ |
|||
public function generateToken($length = 32) { |
|||
return $this->random->generate($length); |
|||
} |
|||
} |
|||
@ -0,0 +1,97 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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\Security\CSRF; |
|||
|
|||
use OC\Security\CSRF\TokenStorage\SessionStorage; |
|||
|
|||
/** |
|||
* Class CsrfTokenManager is the manager for all CSRF token related activities. |
|||
* |
|||
* @package OC\Security\CSRF |
|||
*/ |
|||
class CsrfTokenManager { |
|||
/** @var CsrfTokenGenerator */ |
|||
private $tokenGenerator; |
|||
/** @var SessionStorage */ |
|||
private $sessionStorage; |
|||
|
|||
/** |
|||
* @param CsrfTokenGenerator $tokenGenerator |
|||
* @param SessionStorage $storageInterface |
|||
*/ |
|||
public function __construct(CsrfTokenGenerator $tokenGenerator, |
|||
SessionStorage $storageInterface) { |
|||
$this->tokenGenerator = $tokenGenerator; |
|||
$this->sessionStorage = $storageInterface; |
|||
} |
|||
|
|||
/** |
|||
* Returns the current CSRF token, if none set it will create a new one. |
|||
* |
|||
* @return CsrfToken |
|||
*/ |
|||
public function getToken() { |
|||
if($this->sessionStorage->hasToken()) { |
|||
$value = $this->sessionStorage->getToken(); |
|||
} else { |
|||
$value = $this->tokenGenerator->generateToken(); |
|||
$this->sessionStorage->setToken($value); |
|||
} |
|||
|
|||
return new CsrfToken($value); |
|||
} |
|||
|
|||
/** |
|||
* Invalidates any current token and sets a new one. |
|||
* |
|||
* @return CsrfToken |
|||
*/ |
|||
public function refreshToken() { |
|||
$value = $this->tokenGenerator->generateToken(); |
|||
$this->sessionStorage->setToken($value); |
|||
return new CsrfToken($value); |
|||
} |
|||
|
|||
/** |
|||
* Remove the current token from the storage. |
|||
*/ |
|||
public function removeToken() { |
|||
$this->sessionStorage->removeToken(); |
|||
} |
|||
|
|||
/** |
|||
* Verifies whether the provided token is valid. |
|||
* |
|||
* @param CsrfToken $token |
|||
* @return bool |
|||
*/ |
|||
public function isTokenValid(CsrfToken $token) { |
|||
if(!$this->sessionStorage->hasToken()) { |
|||
return false; |
|||
} |
|||
|
|||
return hash_equals( |
|||
$this->sessionStorage->getToken(), |
|||
$token->getDecryptedValue() |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,80 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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\Security\CSRF\TokenStorage; |
|||
|
|||
use OCP\ISession; |
|||
|
|||
/** |
|||
* Class SessionStorage provides the session storage |
|||
* |
|||
* @package OC\Security\CSRF\TokenStorage |
|||
*/ |
|||
class SessionStorage { |
|||
/** @var ISession */ |
|||
private $session; |
|||
|
|||
/** |
|||
* @param ISession $session |
|||
*/ |
|||
public function __construct(ISession $session) { |
|||
$this->session = $session; |
|||
} |
|||
|
|||
/** |
|||
* Returns the current token or throws an exception if none is found. |
|||
* |
|||
* @return string |
|||
* @throws \Exception |
|||
*/ |
|||
public function getToken() { |
|||
$token = $this->session->get('requesttoken'); |
|||
if(empty($token)) { |
|||
throw new \Exception('Session does not contain a requesttoken'); |
|||
} |
|||
|
|||
return $token; |
|||
} |
|||
|
|||
/** |
|||
* Set the valid current token to $value. |
|||
* |
|||
* @param string $value |
|||
*/ |
|||
public function setToken($value) { |
|||
$this->session->set('requesttoken', $value); |
|||
} |
|||
|
|||
/** |
|||
* Removes the current token. |
|||
*/ |
|||
public function removeToken() { |
|||
$this->session->remove('requesttoken'); |
|||
} |
|||
/** |
|||
* Whether the storage has a storage. |
|||
* |
|||
* @return bool |
|||
*/ |
|||
public function hasToken() { |
|||
return $this->session->exists('requesttoken'); |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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/> |
|||
* |
|||
*/ |
|||
|
|||
class CsrfTokenGeneratorTest extends \Test\TestCase { |
|||
/** @var \OCP\Security\ISecureRandom */ |
|||
private $random; |
|||
/** @var \OC\Security\CSRF\CsrfTokenGenerator */ |
|||
private $csrfTokenGenerator; |
|||
|
|||
public function setUp() { |
|||
parent::setUp(); |
|||
$this->random = $this->getMockBuilder('\OCP\Security\ISecureRandom') |
|||
->disableOriginalConstructor()->getMock(); |
|||
$this->csrfTokenGenerator = new \OC\Security\CSRF\CsrfTokenGenerator($this->random); |
|||
|
|||
} |
|||
|
|||
public function testGenerateTokenWithCustomNumber() { |
|||
$this->random |
|||
->expects($this->once()) |
|||
->method('generate') |
|||
->with(3) |
|||
->willReturn('abc'); |
|||
$this->assertSame('abc', $this->csrfTokenGenerator->generateToken(3)); |
|||
} |
|||
|
|||
public function testGenerateTokenWithDefault() { |
|||
$this->random |
|||
->expects($this->once()) |
|||
->method('generate') |
|||
->with(32) |
|||
->willReturn('12345678901234567890123456789012'); |
|||
$this->assertSame('12345678901234567890123456789012', $this->csrfTokenGenerator->generateToken(32)); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,134 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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/> |
|||
* |
|||
*/ |
|||
|
|||
class CsrfTokenManagerTest extends \Test\TestCase { |
|||
/** @var \OC\Security\CSRF\CsrfTokenManager */ |
|||
private $csrfTokenManager; |
|||
/** @var \OC\Security\CSRF\CsrfTokenGenerator */ |
|||
private $tokenGenerator; |
|||
/** @var \OC\Security\CSRF\TokenStorage\SessionStorage */ |
|||
private $storageInterface; |
|||
|
|||
public function setUp() { |
|||
parent::setUp(); |
|||
$this->tokenGenerator = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenGenerator') |
|||
->disableOriginalConstructor()->getMock(); |
|||
$this->storageInterface = $this->getMockBuilder('\OC\Security\CSRF\TokenStorage\SessionStorage') |
|||
->disableOriginalConstructor()->getMock(); |
|||
|
|||
$this->csrfTokenManager = new \OC\Security\CSRF\CsrfTokenManager( |
|||
$this->tokenGenerator, |
|||
$this->storageInterface |
|||
); |
|||
} |
|||
|
|||
public function testGetTokenWithExistingToken() { |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('hasToken') |
|||
->willReturn(true); |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('getToken') |
|||
->willReturn('MyExistingToken'); |
|||
|
|||
$expected = new \OC\Security\CSRF\CsrfToken('MyExistingToken'); |
|||
$this->assertEquals($expected, $this->csrfTokenManager->getToken()); |
|||
} |
|||
|
|||
public function testGetTokenWithoutExistingToken() { |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('hasToken') |
|||
->willReturn(false); |
|||
$this->tokenGenerator |
|||
->expects($this->once()) |
|||
->method('generateToken') |
|||
->willReturn('MyNewToken'); |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('setToken') |
|||
->with('MyNewToken'); |
|||
|
|||
$expected = new \OC\Security\CSRF\CsrfToken('MyNewToken'); |
|||
$this->assertEquals($expected, $this->csrfTokenManager->getToken()); |
|||
} |
|||
|
|||
public function testRefreshToken() { |
|||
$this->tokenGenerator |
|||
->expects($this->once()) |
|||
->method('generateToken') |
|||
->willReturn('MyNewToken'); |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('setToken') |
|||
->with('MyNewToken'); |
|||
|
|||
$expected = new \OC\Security\CSRF\CsrfToken('MyNewToken'); |
|||
$this->assertEquals($expected, $this->csrfTokenManager->refreshToken()); |
|||
} |
|||
|
|||
public function testRemoveToken() { |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('removeToken'); |
|||
|
|||
$this->csrfTokenManager->removeToken(); |
|||
} |
|||
|
|||
public function testIsTokenValidWithoutToken() { |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('hasToken') |
|||
->willReturn(false); |
|||
$token = new \OC\Security\CSRF\CsrfToken('Token'); |
|||
|
|||
$this->assertSame(false, $this->csrfTokenManager->isTokenValid($token)); |
|||
} |
|||
|
|||
public function testIsTokenValidWithWrongToken() { |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('hasToken') |
|||
->willReturn(true); |
|||
$token = new \OC\Security\CSRF\CsrfToken('Token'); |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('getToken') |
|||
->willReturn('MyToken'); |
|||
|
|||
$this->assertSame(false, $this->csrfTokenManager->isTokenValid($token)); |
|||
} |
|||
|
|||
public function testIsTokenValidWithValidToken() { |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('hasToken') |
|||
->willReturn(true); |
|||
$token = new \OC\Security\CSRF\CsrfToken('XlQhHjgWCgBXAEI0Khl+IQEiCXN2LUcDHAQTQAc1HQs=:qgkUlg8l3m8WnkOG4XM9Az33pAt1vSVMx4hcJFsxdqc='); |
|||
$this->storageInterface |
|||
->expects($this->once()) |
|||
->method('getToken') |
|||
->willReturn('/3JKTq2ldmzcDr1f5zDJ7Wt0lEgqqfKF'); |
|||
|
|||
$this->assertSame(true, $this->csrfTokenManager->isTokenValid($token)); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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/> |
|||
* |
|||
*/ |
|||
|
|||
class CsrfTokenTest extends \Test\TestCase { |
|||
public function testGetEncryptedValue() { |
|||
$csrfToken = new \OC\Security\CSRF\CsrfToken('MyCsrfToken'); |
|||
$this->assertSame(33, strlen($csrfToken->getEncryptedValue())); |
|||
$this->assertSame(':', $csrfToken->getEncryptedValue()[16]); |
|||
} |
|||
|
|||
public function testGetDecryptedValue() { |
|||
$csrfToken = new \OC\Security\CSRF\CsrfToken('XlQhHjgWCgBXAEI0Khl+IQEiCXN2LUcDHAQTQAc1HQs=:qgkUlg8l3m8WnkOG4XM9Az33pAt1vSVMx4hcJFsxdqc='); |
|||
$this->assertSame('/3JKTq2ldmzcDr1f5zDJ7Wt0lEgqqfKF', $csrfToken->getDecryptedValue()); |
|||
} |
|||
} |
|||
@ -0,0 +1,107 @@ |
|||
<?php |
|||
/** |
|||
* @author Lukas Reschke <lukas@owncloud.com> |
|||
* |
|||
* @copyright Copyright (c) 2016, 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/> |
|||
* |
|||
*/ |
|||
|
|||
class SessionStorageTest extends \Test\TestCase { |
|||
/** @var \OCP\ISession */ |
|||
private $session; |
|||
/** @var \OC\Security\CSRF\TokenStorage\SessionStorage */ |
|||
private $sessionStorage; |
|||
|
|||
public function setUp() { |
|||
parent::setUp(); |
|||
$this->session = $this->getMockBuilder('\OCP\ISession') |
|||
->disableOriginalConstructor()->getMock(); |
|||
$this->sessionStorage = new \OC\Security\CSRF\TokenStorage\SessionStorage($this->session); |
|||
} |
|||
|
|||
/** |
|||
* @return array |
|||
*/ |
|||
public function getTokenDataProvider() { |
|||
return [ |
|||
[ |
|||
'', |
|||
], |
|||
[ |
|||
null, |
|||
], |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* @param string $token |
|||
* @dataProvider getTokenDataProvider |
|||
* |
|||
* @expectedException \Exception |
|||
* @expectedExceptionMessage Session does not contain a requesttoken |
|||
*/ |
|||
public function testGetTokenWithEmptyToken($token) { |
|||
$this->session |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('requesttoken') |
|||
->willReturn($token); |
|||
$this->sessionStorage->getToken(); |
|||
} |
|||
|
|||
public function testGetTokenWithValidToken() { |
|||
$this->session |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('requesttoken') |
|||
->willReturn('MyFancyCsrfToken'); |
|||
$this->assertSame('MyFancyCsrfToken', $this->sessionStorage->getToken()); |
|||
} |
|||
|
|||
public function testSetToken() { |
|||
$this->session |
|||
->expects($this->once()) |
|||
->method('set') |
|||
->with('requesttoken', 'TokenToSet'); |
|||
$this->sessionStorage->setToken('TokenToSet'); |
|||
} |
|||
|
|||
public function testRemoveToken() { |
|||
$this->session |
|||
->expects($this->once()) |
|||
->method('remove') |
|||
->with('requesttoken'); |
|||
$this->sessionStorage->removeToken(); |
|||
} |
|||
|
|||
public function testHasTokenWithExistingToken() { |
|||
$this->session |
|||
->expects($this->once()) |
|||
->method('exists') |
|||
->with('requesttoken') |
|||
->willReturn(true); |
|||
$this->assertSame(true, $this->sessionStorage->hasToken()); |
|||
} |
|||
|
|||
public function testHasTokenWithoutExistingToken() { |
|||
$this->session |
|||
->expects($this->once()) |
|||
->method('exists') |
|||
->with('requesttoken') |
|||
->willReturn(false); |
|||
$this->assertSame(false, $this->sessionStorage->hasToken()); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue