PageRenderTime 44ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/ZendTest/Validator/CsrfTest.php

http://github.com/zendframework/zf2
PHP | 286 lines | 219 code | 45 blank | 22 comment | 2 complexity | db2ce69bf88ada4ce2908f7115a793b4 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace ZendTest\Validator;
  10. use Zend\Session\Config\StandardConfig;
  11. use Zend\Session\Container;
  12. use Zend\Validator\Csrf;
  13. /**
  14. * Zend\Csrf
  15. *
  16. * @group Zend_Validator
  17. */
  18. class CsrfTest extends \PHPUnit_Framework_TestCase
  19. {
  20. /** @var Csrf */
  21. public $validator;
  22. /** @var TestAsset\SessionManager */
  23. public $sessionManager;
  24. public function setUp()
  25. {
  26. // Setup session handling
  27. $_SESSION = array();
  28. $sessionConfig = new StandardConfig(array(
  29. 'storage' => 'Zend\Session\Storage\ArrayStorage',
  30. ));
  31. $sessionManager = new TestAsset\SessionManager($sessionConfig);
  32. $this->sessionManager = $sessionManager;
  33. Container::setDefaultManager($sessionManager);
  34. $this->validator = new Csrf;
  35. }
  36. public function tearDown()
  37. {
  38. $_SESSION = array();
  39. Container::setDefaultManager(null);
  40. }
  41. public function testSaltHasDefaultValueIfNotSet()
  42. {
  43. $this->assertEquals('salt', $this->validator->getSalt());
  44. }
  45. public function testSaltIsMutable()
  46. {
  47. $this->validator->setSalt('pepper');
  48. $this->assertEquals('pepper', $this->validator->getSalt());
  49. }
  50. public function testSessionContainerIsLazyLoadedIfNotSet()
  51. {
  52. $container = $this->validator->getSession();
  53. $this->assertInstanceOf('Zend\Session\Container', $container);
  54. }
  55. public function testSessionContainerIsMutable()
  56. {
  57. $container = new Container('foo', $this->sessionManager);
  58. $this->validator->setSession($container);
  59. $this->assertSame($container, $this->validator->getSession());
  60. }
  61. public function testNameHasDefaultValue()
  62. {
  63. $this->assertEquals('csrf', $this->validator->getName());
  64. }
  65. public function testNameIsMutable()
  66. {
  67. $this->validator->setName('foo');
  68. $this->assertEquals('foo', $this->validator->getName());
  69. }
  70. public function testTimeoutHasDefaultValue()
  71. {
  72. $this->assertEquals(300, $this->validator->getTimeout());
  73. }
  74. public function timeoutValuesDataProvider()
  75. {
  76. return array(
  77. // timeout expected
  78. array(600, 600),
  79. array(null, null),
  80. array("0", 0),
  81. array("100", 100),
  82. );
  83. }
  84. /**
  85. * @dataProvider timeoutValuesDataProvider
  86. */
  87. public function testTimeoutIsMutable($timeout, $expected)
  88. {
  89. $this->validator->setTimeout($timeout);
  90. $this->assertEquals($expected, $this->validator->getTimeout());
  91. }
  92. public function testAllOptionsMayBeSetViaConstructor()
  93. {
  94. $container = new Container('foo', $this->sessionManager);
  95. $options = array(
  96. 'name' => 'hash',
  97. 'salt' => 'hashful',
  98. 'session' => $container,
  99. 'timeout' => 600,
  100. );
  101. $validator = new Csrf($options);
  102. foreach ($options as $key => $value) {
  103. if ($key == 'session') {
  104. $this->assertSame($container, $value);
  105. continue;
  106. }
  107. $method = 'get' . $key;
  108. $this->assertEquals($value, $validator->$method());
  109. }
  110. }
  111. public function testHashIsGeneratedOnFirstRetrieval()
  112. {
  113. $hash = $this->validator->getHash();
  114. $this->assertNotEmpty($hash);
  115. $test = $this->validator->getHash();
  116. $this->assertEquals($hash, $test);
  117. }
  118. public function testSessionNameIsDerivedFromClassSaltAndName()
  119. {
  120. $class = get_class($this->validator);
  121. $class = str_replace('\\', '_', $class);
  122. $expected = sprintf('%s_%s_%s', $class, $this->validator->getSalt(), $this->validator->getName());
  123. $this->assertEquals($expected, $this->validator->getSessionName());
  124. }
  125. public function testSessionNameRemainsValidForElementBelongingToFieldset()
  126. {
  127. $this->validator->setName('fieldset[csrf]');
  128. $class = get_class($this->validator);
  129. $class = str_replace('\\', '_', $class);
  130. $name = strtr($this->validator->getName(), array('[' => '_', ']' => ''));
  131. $expected = sprintf('%s_%s_%s', $class, $this->validator->getSalt(), $name);
  132. $this->assertEquals($expected, $this->validator->getSessionName());
  133. }
  134. public function testIsValidReturnsFalseWhenValueDoesNotMatchHash()
  135. {
  136. $this->assertFalse($this->validator->isValid('foo'));
  137. }
  138. public function testValidationErrorMatchesNotSameConstantAndRelatedMessage()
  139. {
  140. $this->validator->isValid('foo');
  141. $messages = $this->validator->getMessages();
  142. $this->assertArrayHasKey(Csrf::NOT_SAME, $messages);
  143. $this->assertEquals("The form submitted did not originate from the expected site", $messages[Csrf::NOT_SAME]);
  144. }
  145. public function testIsValidReturnsTrueWhenValueMatchesHash()
  146. {
  147. $hash = $this->validator->getHash();
  148. $this->assertTrue($this->validator->isValid($hash));
  149. }
  150. public function testSessionContainerContainsHashAfterHashHasBeenGenerated()
  151. {
  152. $hash = $this->validator->getHash();
  153. $container = $this->validator->getSession();
  154. $test = $container->hash; // Doing this, as expiration hops are 1; have to grab on first access
  155. $this->assertEquals($hash, $test);
  156. }
  157. public function testSettingNewSessionContainerSetsHashInNewContainer()
  158. {
  159. $hash = $this->validator->getHash();
  160. $container = new Container('foo', $this->sessionManager);
  161. $this->validator->setSession($container);
  162. $test = $container->hash; // Doing this, as expiration hops are 1; have to grab on first access
  163. $this->assertEquals($hash, $test);
  164. }
  165. public function testMultipleValidatorsSharingContainerGenerateDifferentHashes()
  166. {
  167. $validatorOne = new Csrf();
  168. $validatorTwo = new Csrf();
  169. $containerOne = $validatorOne->getSession();
  170. $containerTwo = $validatorOne->getSession();
  171. $this->assertSame($containerOne, $containerTwo);
  172. $hashOne = $validatorOne->getHash();
  173. $hashTwo = $validatorTwo->getHash();
  174. $this->assertNotEquals($hashOne, $hashTwo);
  175. }
  176. public function testCanValidateAnyHashWithinTheSameContainer()
  177. {
  178. $validatorOne = new Csrf();
  179. $validatorTwo = new Csrf();
  180. $hashOne = $validatorOne->getHash();
  181. $hashTwo = $validatorTwo->getHash();
  182. $this->assertTrue($validatorOne->isValid($hashOne));
  183. $this->assertTrue($validatorOne->isValid($hashTwo));
  184. $this->assertTrue($validatorTwo->isValid($hashOne));
  185. $this->assertTrue($validatorTwo->isValid($hashTwo));
  186. }
  187. public function testCannotValidateHashesOfOtherContainers()
  188. {
  189. $validatorOne = new Csrf();
  190. $validatorTwo = new Csrf(array('name' => 'foo'));
  191. $containerOne = $validatorOne->getSession();
  192. $containerTwo = $validatorTwo->getSession();
  193. $this->assertNotSame($containerOne, $containerTwo);
  194. $hashOne = $validatorOne->getHash();
  195. $hashTwo = $validatorTwo->getHash();
  196. $this->assertTrue($validatorOne->isValid($hashOne));
  197. $this->assertFalse($validatorOne->isValid($hashTwo));
  198. $this->assertFalse($validatorTwo->isValid($hashOne));
  199. $this->assertTrue($validatorTwo->isValid($hashTwo));
  200. }
  201. public function testCannotReValidateAnExpiredHash()
  202. {
  203. $hash = $this->validator->getHash();
  204. $this->assertTrue($this->validator->isValid($hash));
  205. $this->sessionManager->getStorage()->setMetadata(
  206. $this->validator->getSession()->getName(),
  207. array('EXPIRE' => $_SERVER['REQUEST_TIME'] - 18600)
  208. );
  209. $this->assertFalse($this->validator->isValid($hash));
  210. }
  211. public function testCanValidateHasheWithoutId()
  212. {
  213. $method = new \ReflectionMethod(get_class($this->validator), 'getTokenFromHash');
  214. $method->setAccessible(true);
  215. $hash = $this->validator->getHash();
  216. $bareToken = $method->invoke($this->validator, $hash);
  217. $this->assertTrue($this->validator->isValid($bareToken));
  218. }
  219. public function fakeValuesDataProvider()
  220. {
  221. return array(
  222. array(''),
  223. array('-fakeTokenId'),
  224. array('fakeTokenId-fakeTokenId'),
  225. array('fakeTokenId-'),
  226. array('fakeTokenId'),
  227. array(md5(uniqid()) . '-'),
  228. array(md5(uniqid()) . '-' . md5(uniqid())),
  229. array('-' . md5(uniqid()))
  230. );
  231. }
  232. /**
  233. * @dataProvider fakeValuesDataProvider
  234. */
  235. public function testWithFakeValues($value)
  236. {
  237. $validator = new Csrf();
  238. $this->assertFalse($validator->isValid($value));
  239. }
  240. }