diff options
Diffstat (limited to 'Csrf')
-rw-r--r-- | Csrf/.gitignore | 3 | ||||
-rw-r--r-- | Csrf/CsrfTokenGenerator.php | 105 | ||||
-rw-r--r-- | Csrf/CsrfTokenGeneratorInterface.php | 52 | ||||
-rw-r--r-- | Csrf/LICENSE | 19 | ||||
-rw-r--r-- | Csrf/README.md | 21 | ||||
-rw-r--r-- | Csrf/Tests/CsrfTokenGeneratorTest.php | 148 | ||||
-rw-r--r-- | Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php | 99 | ||||
-rw-r--r-- | Csrf/Tests/TokenStorage/SessionTokenStorageTest.php | 144 | ||||
-rw-r--r-- | Csrf/TokenStorage/NativeSessionTokenStorage.php | 101 | ||||
-rw-r--r-- | Csrf/TokenStorage/SessionTokenStorage.php | 89 | ||||
-rw-r--r-- | Csrf/TokenStorage/TokenStorageInterface.php | 49 | ||||
-rw-r--r-- | Csrf/composer.json | 38 | ||||
-rw-r--r-- | Csrf/phpunit.xml.dist | 29 |
13 files changed, 897 insertions, 0 deletions
diff --git a/Csrf/.gitignore b/Csrf/.gitignore new file mode 100644 index 0000000..c49a5d8 --- /dev/null +++ b/Csrf/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/Csrf/CsrfTokenGenerator.php b/Csrf/CsrfTokenGenerator.php new file mode 100644 index 0000000..8ff3462 --- /dev/null +++ b/Csrf/CsrfTokenGenerator.php @@ -0,0 +1,105 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Csrf; + +use Symfony\Component\Security\Core\Util\SecureRandomInterface; +use Symfony\Component\Security\Core\Util\SecureRandom; +use Symfony\Component\Security\Core\Util\StringUtils; +use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage; +use Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface; + +/** + * Generates and validates CSRF tokens. + * + * @since 2.4 + * @author Bernhard Schussek <bernhard.schussek@symfony.com> + */ +class CsrfTokenGenerator implements CsrfTokenGeneratorInterface +{ + /** + * The entropy of the token in bits. + * @var integer + */ + const TOKEN_ENTROPY = 256; + + /** + * @var TokenStorageInterface + */ + private $storage; + + /** + * The generator for random values. + * @var SecureRandomInterface + */ + private $random; + + /** + * Creates a new CSRF provider using PHP's native session storage. + * + * @param TokenStorageInterface $storage The storage for storing generated + * CSRF tokens + * @param SecureRandomInterface $random The used random value generator + * @param integer $entropy The amount of entropy collected for + * newly generated tokens (in bits) + * + */ + public function __construct(TokenStorageInterface $storage = null, SecureRandomInterface $random = null, $entropy = self::TOKEN_ENTROPY) + { + if (null === $storage) { + $storage = new NativeSessionTokenStorage(); + } + + if (null === $random) { + $random = new SecureRandom(); + } + + $this->storage = $storage; + $this->random = $random; + $this->entropy = $entropy; + } + + /** + * {@inheritDoc} + */ + public function generateCsrfToken($tokenId) + { + $currentToken = $this->storage->getToken($tokenId, false); + + // Token exists and is still valid + if (false !== $currentToken) { + return $currentToken; + } + + // Token needs to be (re)generated + // Generate an URI safe base64 encoded string that does not contain "+", + // "/" or "=" which need to be URL encoded and make URLs unnecessarily + // longer. + $bytes = $this->random->nextBytes($this->entropy / 8); + $token = rtrim(strtr(base64_encode($bytes), '+/', '-_'), '='); + + $this->storage->setToken($tokenId, $token); + + return $token; + } + + /** + * {@inheritDoc} + */ + public function isCsrfTokenValid($tokenId, $token) + { + if (!$this->storage->hasToken($tokenId)) { + return false; + } + + return StringUtils::equals((string) $this->storage->getToken($tokenId), $token); + } +} diff --git a/Csrf/CsrfTokenGeneratorInterface.php b/Csrf/CsrfTokenGeneratorInterface.php new file mode 100644 index 0000000..c34549f --- /dev/null +++ b/Csrf/CsrfTokenGeneratorInterface.php @@ -0,0 +1,52 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Csrf; + +/** + * Generates and validates CSRF tokens. + * + * You can generate a CSRF token by using the method {@link generateCsrfToken()}. + * This method expects a unique token ID as argument. The token ID can later be + * used to validate a token provided by the user. + * + * Token IDs do not necessarily have to be secret, but they should NEVER be + * created from data provided by the client. A good practice is to hard-code the + * token IDs for the various CSRF tokens used by your application. + * + * You should use the method {@link isCsrfTokenValid()} to check a CSRF token + * submitted by the client. This method will return true if the CSRF token is + * valid. + * + * @since 2.4 + * @author Bernhard Schussek <bschussek@gmail.com> + */ +interface CsrfTokenGeneratorInterface +{ + /** + * Generates a CSRF token with the given token ID. + * + * @param string $tokenId An ID that identifies the token + * + * @return string The generated CSRF token + */ + public function generateCsrfToken($tokenId); + + /** + * Validates a CSRF token. + * + * @param string $tokenId The token ID used when generating the token + * @param string $token The token supplied by the client + * + * @return Boolean Whether the token supplied by the client is correct + */ + public function isCsrfTokenValid($tokenId, $token); +} diff --git a/Csrf/LICENSE b/Csrf/LICENSE new file mode 100644 index 0000000..88a57f8 --- /dev/null +++ b/Csrf/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2013 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Csrf/README.md b/Csrf/README.md new file mode 100644 index 0000000..394a29e --- /dev/null +++ b/Csrf/README.md @@ -0,0 +1,21 @@ +Security Component - CSRF +========================= + +The Security CSRF (cross-site request forgery) component provides a class +`CsrfTokenGenerator` for generating and validating CSRF tokens. + +Resources +--------- + +Documentation: + +http://symfony.com/doc/2.4/book/security.html + +Tests +----- + +You can run the unit tests with the following command: + + $ cd path/to/Symfony/Component/Security/Csrf/ + $ composer.phar install --dev + $ phpunit diff --git a/Csrf/Tests/CsrfTokenGeneratorTest.php b/Csrf/Tests/CsrfTokenGeneratorTest.php new file mode 100644 index 0000000..f5f9507 --- /dev/null +++ b/Csrf/Tests/CsrfTokenGeneratorTest.php @@ -0,0 +1,148 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\CsrfProvider; + +use Symfony\Component\Security\Csrf\CsrfTokenGenerator; + +/** + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class CsrfTokenGeneratorTest extends \PHPUnit_Framework_TestCase +{ + /** + * A non alpha-numeric byte string + * @var string + */ + private static $bytes; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $random; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $storage; + + /** + * @var CsrfTokenGenerator + */ + private $generator; + + public static function setUpBeforeClass() + { + self::$bytes = base64_decode('aMf+Tct/RLn2WQ=='); + } + + protected function setUp() + { + $this->random = $this->getMock('Symfony\Component\Security\Core\Util\SecureRandomInterface'); + $this->storage = $this->getMock('Symfony\Component\Security\Csrf\TokenStorage\TokenStorageInterface'); + $this->generator = new CsrfTokenGenerator($this->storage, $this->random); + } + + protected function tearDown() + { + $this->random = null; + $this->storage = null; + $this->generator = null; + } + + public function testGenerateNewToken() + { + $this->storage->expects($this->once()) + ->method('getToken') + ->with('token_id', false) + ->will($this->returnValue(false)); + + $this->storage->expects($this->once()) + ->method('setToken') + ->with('token_id', $this->anything()) + ->will($this->returnCallback(function ($tokenId, $token) use (&$storedToken) { + $storedToken = $token; + })); + + $this->random->expects($this->once()) + ->method('nextBytes') + ->will($this->returnValue(self::$bytes)); + + $token = $this->generator->generateCsrfToken('token_id'); + + $this->assertSame($token, $storedToken); + $this->assertTrue(ctype_print($token), 'is printable'); + $this->assertStringNotMatchesFormat('%S+%S', $token, 'is URI safe'); + $this->assertStringNotMatchesFormat('%S/%S', $token, 'is URI safe'); + $this->assertStringNotMatchesFormat('%S=%S', $token, 'is URI safe'); + } + + public function testUseExistingTokenIfAvailable() + { + $this->storage->expects($this->once()) + ->method('getToken') + ->with('token_id', false) + ->will($this->returnValue('TOKEN')); + + $this->storage->expects($this->never()) + ->method('setToken'); + + $this->random->expects($this->never()) + ->method('nextBytes'); + + $token = $this->generator->generateCsrfToken('token_id'); + + $this->assertEquals('TOKEN', $token); + } + + public function testMatchingTokenIsValid() + { + $this->storage->expects($this->once()) + ->method('hasToken') + ->with('token_id') + ->will($this->returnValue(true)); + + $this->storage->expects($this->once()) + ->method('getToken') + ->with('token_id') + ->will($this->returnValue('TOKEN')); + + $this->assertTrue($this->generator->isCsrfTokenValid('token_id', 'TOKEN')); + } + + public function testNonMatchingTokenIsNotValid() + { + $this->storage->expects($this->once()) + ->method('hasToken') + ->with('token_id') + ->will($this->returnValue(true)); + + $this->storage->expects($this->once()) + ->method('getToken') + ->with('token_id') + ->will($this->returnValue('TOKEN')); + + $this->assertFalse($this->generator->isCsrfTokenValid('token_id', 'FOOBAR')); + } + + public function testNonExistingTokenIsNotValid() + { + $this->storage->expects($this->once()) + ->method('hasToken') + ->with('token_id') + ->will($this->returnValue(false)); + + $this->storage->expects($this->never()) + ->method('getToken'); + + $this->assertFalse($this->generator->isCsrfTokenValid('token_id', 'FOOBAR')); + } +} diff --git a/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php b/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php new file mode 100644 index 0000000..69df061 --- /dev/null +++ b/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php @@ -0,0 +1,99 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\CsrfProvider; + +use Symfony\Component\Security\Csrf\TokenStorage\NativeSessionTokenStorage; + +/** + * @author Bernhard Schussek <bschussek@gmail.com> + * + * @runTestsInSeparateProcesses + */ +class NativeSessionTokenStorageTest extends \PHPUnit_Framework_TestCase +{ + const SESSION_NAMESPACE = 'foobar'; + + /** + * @var NativeSessionTokenStorage + */ + private $storage; + + public static function setUpBeforeClass() + { + ini_set('session.save_handler', 'files'); + ini_set('session.save_path', sys_get_temp_dir()); + + parent::setUpBeforeClass(); + } + + protected function setUp() + { + $_SESSION = array(); + + $this->storage = new NativeSessionTokenStorage(self::SESSION_NAMESPACE); + } + + public function testStoreTokenInClosedSession() + { + $this->storage->setToken('token_id', 'TOKEN'); + + $this->assertSame(array(self::SESSION_NAMESPACE => array('token_id' => 'TOKEN')), $_SESSION); + } + + public function testStoreTokenInClosedSessionWithExistingSessionId() + { + session_id('foobar'); + + $this->assertSame(PHP_SESSION_NONE, session_status()); + + $this->storage->setToken('token_id', 'TOKEN'); + + $this->assertSame(PHP_SESSION_ACTIVE, session_status()); + $this->assertSame(array(self::SESSION_NAMESPACE => array('token_id' => 'TOKEN')), $_SESSION); + } + + public function testStoreTokenInActiveSession() + { + session_start(); + + $this->storage->setToken('token_id', 'TOKEN'); + + $this->assertSame(array(self::SESSION_NAMESPACE => array('token_id' => 'TOKEN')), $_SESSION); + } + + /** + * @depends testStoreTokenInClosedSession + */ + public function testCheckToken() + { + $this->assertFalse($this->storage->hasToken('token_id')); + + $this->storage->setToken('token_id', 'TOKEN'); + + $this->assertTrue($this->storage->hasToken('token_id')); + } + + /** + * @depends testStoreTokenInClosedSession + */ + public function testGetExistingToken() + { + $this->storage->setToken('token_id', 'TOKEN'); + + $this->assertSame('TOKEN', $this->storage->getToken('token_id')); + } + + public function testGetNonExistingToken() + { + $this->assertSame('DEFAULT', $this->storage->getToken('token_id', 'DEFAULT')); + } +} diff --git a/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php b/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php new file mode 100644 index 0000000..5c8c173 --- /dev/null +++ b/Csrf/Tests/TokenStorage/SessionTokenStorageTest.php @@ -0,0 +1,144 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Form\Tests\Extension\Csrf\CsrfProvider; + +use Symfony\Component\Security\Csrf\TokenStorage\SessionTokenStorage; + +/** + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class SessionTokenStorageTest extends \PHPUnit_Framework_TestCase +{ + const SESSION_NAMESPACE = 'foobar'; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $session; + + /** + * @var SessionTokenStorage + */ + private $storage; + + protected function setUp() + { + if (!class_exists('Symfony\Component\HttpFoundation\Session\SessionInterface')) { + $this->markTestSkipped('The "HttpFoundation" component is not available'); + } + + $this->session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->storage = new SessionTokenStorage($this->session, self::SESSION_NAMESPACE); + } + + public function testStoreTokenInClosedSession() + { + $this->session->expects($this->any()) + ->method('isStarted') + ->will($this->returnValue(false)); + + $this->session->expects($this->once()) + ->method('start'); + + $this->session->expects($this->once()) + ->method('set') + ->with(self::SESSION_NAMESPACE.'/token_id', 'TOKEN'); + + $this->storage->setToken('token_id', 'TOKEN'); + } + + public function testStoreTokenInActiveSession() + { + $this->session->expects($this->any()) + ->method('isStarted') + ->will($this->returnValue(true)); + + $this->session->expects($this->never()) + ->method('start'); + + $this->session->expects($this->once()) + ->method('set') + ->with(self::SESSION_NAMESPACE.'/token_id', 'TOKEN'); + + $this->storage->setToken('token_id', 'TOKEN'); + } + + public function testCheckTokenInClosedSession() + { + $this->session->expects($this->any()) + ->method('isStarted') + ->will($this->returnValue(false)); + + $this->session->expects($this->once()) + ->method('start'); + + $this->session->expects($this->once()) + ->method('has') + ->with(self::SESSION_NAMESPACE.'/token_id') + ->will($this->returnValue('RESULT')); + + $this->assertSame('RESULT', $this->storage->hasToken('token_id')); + } + + public function testCheckTokenInActiveSession() + { + $this->session->expects($this->any()) + ->method('isStarted') + ->will($this->returnValue(true)); + + $this->session->expects($this->never()) + ->method('start'); + + $this->session->expects($this->once()) + ->method('has') + ->with(self::SESSION_NAMESPACE.'/token_id') + ->will($this->returnValue('RESULT')); + + $this->assertSame('RESULT', $this->storage->hasToken('token_id')); + } + + public function testGetTokenFromClosedSession() + { + $this->session->expects($this->any()) + ->method('isStarted') + ->will($this->returnValue(false)); + + $this->session->expects($this->once()) + ->method('start'); + + $this->session->expects($this->once()) + ->method('get') + ->with(self::SESSION_NAMESPACE.'/token_id', 'DEFAULT') + ->will($this->returnValue('RESULT')); + + $this->assertSame('RESULT', $this->storage->getToken('token_id', 'DEFAULT')); + } + + public function testGetTokenFromActiveSession() + { + $this->session->expects($this->any()) + ->method('isStarted') + ->will($this->returnValue(true)); + + $this->session->expects($this->never()) + ->method('start'); + + $this->session->expects($this->once()) + ->method('get') + ->with(self::SESSION_NAMESPACE.'/token_id', 'DEFAULT') + ->will($this->returnValue('RESULT')); + + $this->assertSame('RESULT', $this->storage->getToken('token_id', 'DEFAULT')); + } +} diff --git a/Csrf/TokenStorage/NativeSessionTokenStorage.php b/Csrf/TokenStorage/NativeSessionTokenStorage.php new file mode 100644 index 0000000..8956743 --- /dev/null +++ b/Csrf/TokenStorage/NativeSessionTokenStorage.php @@ -0,0 +1,101 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Csrf\TokenStorage; + +/** + * Token storage that uses PHP's native session handling. + * + * @since 2.4 + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class NativeSessionTokenStorage implements TokenStorageInterface +{ + /** + * The namespace used to store values in the session. + * @var string + */ + const SESSION_NAMESPACE = '_csrf'; + + /** + * @var Boolean + */ + private $sessionStarted = false; + + /** + * @var string + */ + private $namespace; + + /** + * Initializes the storage with a session namespace. + * + * @param string $namespace The namespace under which the token is stored + * in the session + */ + public function __construct($namespace = self::SESSION_NAMESPACE) + { + $this->namespace = $namespace; + } + + /** + * {@inheritdoc} + */ + public function getToken($tokenId, $default = null) + { + if (!$this->sessionStarted) { + $this->startSession(); + } + + if (isset($_SESSION[$this->namespace][$tokenId])) { + return $_SESSION[$this->namespace][$tokenId]; + } + + return $default; + } + + /** + * {@inheritdoc} + */ + public function setToken($tokenId, $token) + { + if (!$this->sessionStarted) { + $this->startSession(); + } + + $_SESSION[$this->namespace][$tokenId] = $token; + } + + /** + * {@inheritdoc} + */ + public function hasToken($tokenId) + { + if (!$this->sessionStarted) { + $this->startSession(); + } + + return isset($_SESSION[$this->namespace][$tokenId]); + } + + private function startSession() + { + if (version_compare(PHP_VERSION, '5.4', '>=')) { + if (PHP_SESSION_NONE === session_status()) { + session_start(); + } + } elseif (!session_id()) { + session_start(); + } + + $this->sessionStarted = true; + } +} diff --git a/Csrf/TokenStorage/SessionTokenStorage.php b/Csrf/TokenStorage/SessionTokenStorage.php new file mode 100644 index 0000000..3878e4c --- /dev/null +++ b/Csrf/TokenStorage/SessionTokenStorage.php @@ -0,0 +1,89 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Csrf\TokenStorage; + +use Symfony\Component\HttpFoundation\Session\SessionInterface; + +/** + * Token storage that uses a Symfony2 Session object. + * + * @since 2.4 + * @author Bernhard Schussek <bschussek@gmail.com> + */ +class SessionTokenStorage implements TokenStorageInterface +{ + /** + * The namespace used to store values in the session. + * @var string + */ + const SESSION_NAMESPACE = '_csrf'; + + /** + * The user session from which the session ID is returned + * @var SessionInterface + */ + private $session; + + /** + * @var string + */ + private $namespace; + + /** + * Initializes the storage with a Session object and a session namespace. + * + * @param SessionInterface $session The user session + * @param string $namespace The namespace under which the token + * is stored in the session + */ + public function __construct(SessionInterface $session, $namespace = self::SESSION_NAMESPACE) + { + $this->session = $session; + $this->namespace = $namespace; + } + + /** + * {@inheritdoc} + */ + public function getToken($tokenId, $default = null) + { + if (!$this->session->isStarted()) { + $this->session->start(); + } + + return $this->session->get($this->namespace . '/' . $tokenId, $default); + } + + /** + * {@inheritdoc} + */ + public function setToken($tokenId, $token) + { + if (!$this->session->isStarted()) { + $this->session->start(); + } + + $this->session->set($this->namespace . '/' . $tokenId, $token); + } + + /** + * {@inheritdoc} + */ + public function hasToken($tokenId) + { + if (!$this->session->isStarted()) { + $this->session->start(); + } + + return $this->session->has($this->namespace . '/' . $tokenId); + } +} diff --git a/Csrf/TokenStorage/TokenStorageInterface.php b/Csrf/TokenStorage/TokenStorageInterface.php new file mode 100644 index 0000000..7dba9e5 --- /dev/null +++ b/Csrf/TokenStorage/TokenStorageInterface.php @@ -0,0 +1,49 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Csrf\TokenStorage; + +/** + * Stores CSRF tokens. + * + * @since 2.4 + * @author Bernhard Schussek <bschussek@gmail.com> + */ +interface TokenStorageInterface +{ + /** + * Reads a stored CSRF token. + * + * @param string $tokenId The token ID + * @param mixed $default The value to be returned if no token is set + * + * @return mixed The stored token or the default value, if no token is set + */ + public function getToken($tokenId, $default = null); + + /** + * Stores a CSRF token. + * + * @param string $tokenId The token ID + * @param mixed $token The CSRF token + */ + public function setToken($tokenId, $token); + + /** + * Checks whether a token with the given token ID exists. + * + * @param string $tokenId The token ID + * + * @return Boolean Returns true if a token is stored for the given token ID, + * false otherwise. + */ + public function hasToken($tokenId); +} diff --git a/Csrf/composer.json b/Csrf/composer.json new file mode 100644 index 0000000..3cfc2b4 --- /dev/null +++ b/Csrf/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/security-csrf", + "type": "library", + "description": "Symfony Security Component - CSRF Library", + "keywords": [], + "homepage": "http://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3", + "symfony/security-core": "~2.4" + }, + "require-dev": { + "symfony/http-foundation": "~2.1" + }, + "suggest": { + "symfony/http-foundation": "For using the class SessionTokenStorage." + }, + "autoload": { + "psr-0": { "Symfony\\Component\\Security\\Csrf\\": "" } + }, + "target-dir": "Symfony/Component/Security/Csrf", + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + } +} diff --git a/Csrf/phpunit.xml.dist b/Csrf/phpunit.xml.dist new file mode 100644 index 0000000..0718c76 --- /dev/null +++ b/Csrf/phpunit.xml.dist @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<phpunit backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false" + bootstrap="vendor/autoload.php" +> + <testsuites> + <testsuite name="Symfony Security Component CSRF Test Suite"> + <directory>./Tests/</directory> + </testsuite> + </testsuites> + + <filter> + <whitelist> + <directory>./</directory> + <exclude> + <directory>./vendor</directory> + <directory>./Tests</directory> + </exclude> + </whitelist> + </filter> +</phpunit> |