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.
This commit is contained in:
parent
37f5f5077a
commit
a977465af5
17 changed files with 762 additions and 79 deletions
|
@ -33,6 +33,8 @@
|
|||
|
||||
namespace OC\AppFramework\Http;
|
||||
|
||||
use OC\Security\CSRF\CsrfToken;
|
||||
use OC\Security\CSRF\CsrfTokenManager;
|
||||
use OC\Security\TrustedDomainHelper;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
|
@ -75,6 +77,8 @@ class Request implements \ArrayAccess, \Countable, IRequest {
|
|||
protected $requestId = '';
|
||||
/** @var ICrypto */
|
||||
protected $crypto;
|
||||
/** @var CsrfTokenManager|null */
|
||||
protected $csrfTokenManager;
|
||||
|
||||
/** @var bool */
|
||||
protected $contentDecoded = false;
|
||||
|
@ -92,17 +96,20 @@ class Request implements \ArrayAccess, \Countable, IRequest {
|
|||
* - string|false 'requesttoken' the requesttoken or false when not available
|
||||
* @param ISecureRandom $secureRandom
|
||||
* @param IConfig $config
|
||||
* @param CsrfTokenManager|null $csrfTokenManager
|
||||
* @param string $stream
|
||||
* @see http://www.php.net/manual/en/reserved.variables.php
|
||||
*/
|
||||
public function __construct(array $vars=array(),
|
||||
ISecureRandom $secureRandom = null,
|
||||
IConfig $config,
|
||||
$stream='php://input') {
|
||||
CsrfTokenManager $csrfTokenManager = null,
|
||||
$stream = 'php://input') {
|
||||
$this->inputStream = $stream;
|
||||
$this->items['params'] = array();
|
||||
$this->secureRandom = $secureRandom;
|
||||
$this->config = $config;
|
||||
$this->csrfTokenManager = $csrfTokenManager;
|
||||
|
||||
if(!array_key_exists('method', $vars)) {
|
||||
$vars['method'] = 'GET';
|
||||
|
@ -421,10 +428,9 @@ class Request implements \ArrayAccess, \Countable, IRequest {
|
|||
/**
|
||||
* Checks if the CSRF check was correct
|
||||
* @return bool true if CSRF check passed
|
||||
* @see OC_Util::callRegister()
|
||||
*/
|
||||
public function passesCSRFCheck() {
|
||||
if($this->items['requesttoken'] === false) {
|
||||
if($this->csrfTokenManager === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -438,23 +444,9 @@ class Request implements \ArrayAccess, \Countable, IRequest {
|
|||
//no token found.
|
||||
return false;
|
||||
}
|
||||
$token = new CsrfToken($token);
|
||||
|
||||
// Deobfuscate token to prevent BREACH like attacks
|
||||
$token = explode(':', $token);
|
||||
if (count($token) !== 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$obfuscatedToken = $token[0];
|
||||
$secret = $token[1];
|
||||
$deobfuscatedToken = base64_decode($obfuscatedToken) ^ $secret;
|
||||
|
||||
// Check if the token is valid
|
||||
if(hash_equals($deobfuscatedToken, $this->items['requesttoken'])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return $this->csrfTokenManager->isTokenValid($token);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
69
lib/private/security/csrf/csrftoken.php
Normal file
69
lib/private/security/csrf/csrftoken.php
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
52
lib/private/security/csrf/csrftokengenerator.php
Normal file
52
lib/private/security/csrf/csrftokengenerator.php
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
97
lib/private/security/csrf/csrftokenmanager.php
Normal file
97
lib/private/security/csrf/csrftokenmanager.php
Normal file
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
80
lib/private/security/csrf/tokenstorage/sessionstorage.php
Normal file
80
lib/private/security/csrf/tokenstorage/sessionstorage.php
Normal file
|
@ -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');
|
||||
}
|
||||
}
|
|
@ -64,6 +64,9 @@ use OC\Mail\Mailer;
|
|||
use OC\Notification\Manager;
|
||||
use OC\Security\CertificateManager;
|
||||
use OC\Security\Crypto;
|
||||
use OC\Security\CSRF\CsrfTokenGenerator;
|
||||
use OC\Security\CSRF\CsrfTokenManager;
|
||||
use OC\Security\CSRF\TokenStorage\SessionStorage;
|
||||
use OC\Security\Hasher;
|
||||
use OC\Security\CredentialsManager;
|
||||
use OC\Security\SecureRandom;
|
||||
|
@ -469,12 +472,6 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
$urlParams = [];
|
||||
}
|
||||
|
||||
if ($this->getSession()->exists('requesttoken')) {
|
||||
$requestToken = $this->getSession()->get('requesttoken');
|
||||
} else {
|
||||
$requestToken = false;
|
||||
}
|
||||
|
||||
if (defined('PHPUNIT_RUN') && PHPUNIT_RUN
|
||||
&& in_array('fakeinput', stream_get_wrappers())
|
||||
) {
|
||||
|
@ -495,10 +492,10 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
? $_SERVER['REQUEST_METHOD']
|
||||
: null,
|
||||
'urlParams' => $urlParams,
|
||||
'requesttoken' => $requestToken,
|
||||
],
|
||||
$this->getSecureRandom(),
|
||||
$this->getConfig(),
|
||||
$this->getCsrfTokenManager(),
|
||||
$stream
|
||||
);
|
||||
});
|
||||
|
@ -588,6 +585,15 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
$request
|
||||
);
|
||||
});
|
||||
$this->registerService('CsrfTokenManager', function (Server $c) {
|
||||
$tokenGenerator = new CsrfTokenGenerator($c->getSecureRandom());
|
||||
$sessionStorage = new SessionStorage($c->getSession());
|
||||
|
||||
return new CsrfTokenManager(
|
||||
$tokenGenerator,
|
||||
$sessionStorage
|
||||
);
|
||||
});
|
||||
$this->registerService('ShareManager', function(Server $c) {
|
||||
$config = $c->getConfig();
|
||||
$factoryClass = $config->getSystemValue('sharing.managerFactory', '\OC\Share20\ProviderFactory');
|
||||
|
@ -1204,6 +1210,13 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
return $this->query('CryptoWrapper');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CsrfTokenManager
|
||||
*/
|
||||
public function getCsrfTokenManager() {
|
||||
return $this->query('CsrfTokenManager');
|
||||
}
|
||||
|
||||
/**
|
||||
* Not a public API as of 8.2, wait for 9.0
|
||||
*
|
||||
|
|
|
@ -76,7 +76,7 @@ class OC_Template extends \OC\Template\Base {
|
|||
|
||||
$theme = OC_Util::getTheme();
|
||||
|
||||
$requesttoken = (OC::$server->getSession() and $registerCall) ? OC_Util::callRegister() : '';
|
||||
$requestToken = (OC::$server->getSession() && $registerCall) ? \OCP\Util::callRegister() : '';
|
||||
|
||||
$parts = explode('/', $app); // fix translation when app is something like core/lostpassword
|
||||
$l10n = \OC::$server->getL10N($parts[0]);
|
||||
|
@ -89,7 +89,7 @@ class OC_Template extends \OC\Template\Base {
|
|||
$this->path = $path;
|
||||
$this->app = $app;
|
||||
|
||||
parent::__construct($template, $requesttoken, $l10n, $themeDefaults);
|
||||
parent::__construct($template, $requestToken, $l10n, $themeDefaults);
|
||||
}
|
||||
|
||||
public static function initTemplateEngine($renderAs) {
|
||||
|
|
|
@ -34,12 +34,13 @@ class Base {
|
|||
|
||||
/**
|
||||
* @param string $template
|
||||
* @param string $requestToken
|
||||
* @param \OC_L10N $l10n
|
||||
* @param \OC_Defaults $theme
|
||||
*/
|
||||
public function __construct( $template, $requesttoken, $l10n, $theme ) {
|
||||
public function __construct($template, $requestToken, $l10n, $theme ) {
|
||||
$this->vars = array();
|
||||
$this->vars['requesttoken'] = $requesttoken;
|
||||
$this->vars['requesttoken'] = $requestToken;
|
||||
$this->l10n = $l10n;
|
||||
$this->template = $template;
|
||||
$this->theme = $theme;
|
||||
|
|
|
@ -328,7 +328,7 @@ class OC_User {
|
|||
return $backend->getLogoutAttribute();
|
||||
}
|
||||
|
||||
return 'href="' . link_to('', 'index.php') . '?logout=true&requesttoken=' . urlencode(OC_Util::callRegister()) . '"';
|
||||
return 'href="' . link_to('', 'index.php') . '?logout=true&requesttoken=' . urlencode(\OCP\Util::callRegister()) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1105,42 +1105,6 @@ class OC_Util {
|
|||
return $id;
|
||||
}
|
||||
|
||||
protected static $obfuscatedToken;
|
||||
/**
|
||||
* Register an get/post call. Important to prevent CSRF attacks.
|
||||
*
|
||||
* @return string The encrypted CSRF token, the shared secret is appended after the `:`.
|
||||
*
|
||||
* @description
|
||||
* Creates a 'request token' (random) and stores it inside the session.
|
||||
* Ever subsequent (ajax) request must use such a valid token to succeed,
|
||||
* otherwise the request will be denied as a protection against CSRF.
|
||||
*/
|
||||
public static function callRegister() {
|
||||
// Use existing token if function has already been called
|
||||
if(isset(self::$obfuscatedToken)) {
|
||||
return self::$obfuscatedToken;
|
||||
}
|
||||
|
||||
$tokenLength = 30;
|
||||
|
||||
// Check if a token exists
|
||||
if (!\OC::$server->getSession()->exists('requesttoken')) {
|
||||
// No valid token found, generate a new one.
|
||||
$requestToken = \OC::$server->getSecureRandom()->generate($tokenLength);
|
||||
\OC::$server->getSession()->set('requesttoken', $requestToken);
|
||||
} else {
|
||||
// Valid token already exists, send it
|
||||
$requestToken = \OC::$server->getSession()->get('requesttoken');
|
||||
}
|
||||
|
||||
// XOR the token to mitigate breach-like attacks
|
||||
$sharedSecret = \OC::$server->getSecureRandom()->generate($tokenLength);
|
||||
self::$obfuscatedToken = base64_encode($requestToken ^ $sharedSecret) .':'.$sharedSecret;
|
||||
|
||||
return self::$obfuscatedToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function to sanitize HTML
|
||||
*
|
||||
|
|
|
@ -479,19 +479,29 @@ class Util {
|
|||
return(\OC_Hook::emit( $signalclass, $signalname, $params ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached encrypted CSRF token. Some static unit-tests of ownCloud compare
|
||||
* multiple OC_Template elements which invoke `callRegister`. If the value
|
||||
* would not be cached these unit-tests would fail.
|
||||
* @var string
|
||||
*/
|
||||
private static $token = '';
|
||||
|
||||
/**
|
||||
* Register an get/post call. This is important to prevent CSRF attacks
|
||||
* TODO: write example
|
||||
* @since 4.5.0
|
||||
*/
|
||||
public static function callRegister() {
|
||||
return(\OC_Util::callRegister());
|
||||
if(self::$token === '') {
|
||||
self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue();
|
||||
}
|
||||
return self::$token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check an ajax get/post call if the request token is valid. exit if not.
|
||||
* Todo: Write howto
|
||||
* @since 4.5.0
|
||||
* @deprecated 9.0.0 Use annotations based on the app framework.
|
||||
*/
|
||||
public static function callCheck() {
|
||||
if (!(\OC::$server->getRequest()->passesCSRFCheck())) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
namespace OC\AppFramework\Http;
|
||||
|
||||
use OC\Security\CSRF\CsrfToken;
|
||||
use OC\Security\CSRF\CsrfTokenManager;
|
||||
use OCP\Security\ISecureRandom;
|
||||
use OCP\IConfig;
|
||||
|
||||
|
@ -25,6 +27,8 @@ class RequestTest extends \Test\TestCase {
|
|||
protected $secureRandom;
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
/** @var CsrfTokenManager */
|
||||
protected $csrfTokenManager;
|
||||
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
@ -37,6 +41,8 @@ class RequestTest extends \Test\TestCase {
|
|||
|
||||
$this->secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock();
|
||||
$this->config = $this->getMockBuilder('\OCP\IConfig')->getMock();
|
||||
$this->csrfTokenManager = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager')
|
||||
->disableOriginalConstructor()->getMock();
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
|
@ -54,6 +60,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -86,6 +93,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -108,6 +116,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -127,6 +136,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -146,6 +156,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -162,6 +173,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -183,6 +195,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -206,6 +219,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -227,6 +241,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -251,6 +266,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -271,6 +287,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -295,6 +312,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -324,6 +342,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -345,6 +364,7 @@ class RequestTest extends \Test\TestCase {
|
|||
$vars,
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -361,6 +381,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -372,6 +393,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
\OC::$server->getSecureRandom(),
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
$firstId = $request->getId();
|
||||
|
@ -396,6 +418,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -424,6 +447,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -452,6 +476,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -484,6 +509,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -534,6 +560,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -561,6 +588,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -582,6 +610,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
$requestHttp = new Request(
|
||||
|
@ -592,6 +621,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -615,6 +645,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
$this->assertSame('https', $request->getServerProtocol());
|
||||
|
@ -635,6 +666,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
$this->assertSame('http', $request->getServerProtocol());
|
||||
|
@ -655,6 +687,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
$this->assertSame('http', $request->getServerProtocol());
|
||||
|
@ -671,6 +704,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
$this->assertSame('http', $request->getServerProtocol());
|
||||
|
@ -691,6 +725,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -712,6 +747,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -729,6 +765,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -817,6 +854,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -833,6 +871,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -850,6 +889,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -867,6 +907,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -894,6 +935,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -915,6 +957,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -941,6 +984,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -967,6 +1011,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -983,6 +1028,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1010,6 +1056,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1025,6 +1072,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1045,6 +1093,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1065,6 +1114,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1087,6 +1137,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1109,6 +1160,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1131,6 +1183,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1153,6 +1206,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1207,6 +1261,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
);
|
||||
|
||||
|
@ -1246,6 +1301,7 @@ class RequestTest extends \Test\TestCase {
|
|||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
])
|
||||
->getMock();
|
||||
|
@ -1266,13 +1322,19 @@ class RequestTest extends \Test\TestCase {
|
|||
'get' => [
|
||||
'requesttoken' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
|
||||
],
|
||||
'requesttoken' => 'MyStoredRequestToken',
|
||||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
])
|
||||
->getMock();
|
||||
$token = new CsrfToken('AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds');
|
||||
$this->csrfTokenManager
|
||||
->expects($this->once())
|
||||
->method('isTokenValid')
|
||||
->with($token)
|
||||
->willReturn(true);
|
||||
|
||||
$this->assertTrue($request->passesCSRFCheck());
|
||||
}
|
||||
|
@ -1286,13 +1348,19 @@ class RequestTest extends \Test\TestCase {
|
|||
'post' => [
|
||||
'requesttoken' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
|
||||
],
|
||||
'requesttoken' => 'MyStoredRequestToken',
|
||||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
])
|
||||
->getMock();
|
||||
$token = new CsrfToken('AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds');
|
||||
$this->csrfTokenManager
|
||||
->expects($this->once())
|
||||
->method('isTokenValid')
|
||||
->with($token)
|
||||
->willReturn(true);
|
||||
|
||||
$this->assertTrue($request->passesCSRFCheck());
|
||||
}
|
||||
|
@ -1306,13 +1374,19 @@ class RequestTest extends \Test\TestCase {
|
|||
'server' => [
|
||||
'HTTP_REQUESTTOKEN' => 'AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds',
|
||||
],
|
||||
'requesttoken' => 'MyStoredRequestToken',
|
||||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
])
|
||||
->getMock();
|
||||
$token = new CsrfToken('AAAHGxsTCTc3BgMQESAcNR0OAR0=:MyTotalSecretShareds');
|
||||
$this->csrfTokenManager
|
||||
->expects($this->once())
|
||||
->method('isTokenValid')
|
||||
->with($token)
|
||||
->willReturn(true);
|
||||
|
||||
$this->assertTrue($request->passesCSRFCheck());
|
||||
}
|
||||
|
@ -1342,14 +1416,21 @@ class RequestTest extends \Test\TestCase {
|
|||
'server' => [
|
||||
'HTTP_REQUESTTOKEN' => $invalidToken,
|
||||
],
|
||||
'requesttoken' => 'MyStoredRequestToken',
|
||||
],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
])
|
||||
->getMock();
|
||||
|
||||
$token = new CsrfToken($invalidToken);
|
||||
$this->csrfTokenManager
|
||||
->expects($this->any())
|
||||
->method('isTokenValid')
|
||||
->with($token)
|
||||
->willReturn(false);
|
||||
|
||||
$this->assertFalse($request->passesCSRFCheck());
|
||||
}
|
||||
|
||||
|
@ -1361,6 +1442,7 @@ class RequestTest extends \Test\TestCase {
|
|||
[],
|
||||
$this->secureRandom,
|
||||
$this->config,
|
||||
$this->csrfTokenManager,
|
||||
$this->stream
|
||||
])
|
||||
->getMock();
|
||||
|
|
54
tests/lib/security/csrf/CsrfTokenGeneratorTest.php
Normal file
54
tests/lib/security/csrf/CsrfTokenGeneratorTest.php
Normal file
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
134
tests/lib/security/csrf/CsrfTokenManagerTest.php
Normal file
134
tests/lib/security/csrf/CsrfTokenManagerTest.php
Normal file
|
@ -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));
|
||||
}
|
||||
}
|
33
tests/lib/security/csrf/CsrfTokenTest.php
Normal file
33
tests/lib/security/csrf/CsrfTokenTest.php
Normal file
|
@ -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());
|
||||
}
|
||||
}
|
107
tests/lib/security/csrf/tokenstorage/SessionStorageTest.php
Normal file
107
tests/lib/security/csrf/tokenstorage/SessionStorageTest.php
Normal file
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -89,11 +89,6 @@ class Test_Util extends \Test\TestCase {
|
|||
});
|
||||
}
|
||||
|
||||
function testCallRegister() {
|
||||
$result = strlen(OC_Util::callRegister());
|
||||
$this->assertEquals(71, $result);
|
||||
}
|
||||
|
||||
function testSanitizeHTML() {
|
||||
$badArray = [
|
||||
'While it is unusual to pass an array',
|
||||
|
|
Loading…
Reference in a new issue