PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/cases/template/helper/SecurityTest.php

http://github.com/UnionOfRAD/lithium
PHP | 227 lines | 174 code | 36 blank | 17 comment | 0 complexity | 33478f85e0bb2378b0138d23b9116671 MD5 | raw file
  1. <?php
  2. /**
  3. * li₃: the most RAD framework for PHP (http://li3.me)
  4. *
  5. * Copyright 2011, Union of RAD. All rights reserved. This source
  6. * code is distributed under the terms of the BSD 3-Clause License.
  7. * The full license text can be found in the LICENSE.txt file.
  8. */
  9. namespace lithium\tests\cases\template\helper;
  10. use lithium\aop\Filters;
  11. use lithium\action\Request;
  12. use lithium\template\helper\Form;
  13. use lithium\template\helper\Security;
  14. use lithium\security\validation\FormSignature;
  15. use lithium\tests\mocks\template\helper\MockFormRenderer;
  16. class SecurityTest extends \lithium\test\Unit {
  17. public $subject;
  18. public $context;
  19. public function tearDown() {
  20. Filters::clear('lithium\template\helper\Form');
  21. }
  22. public static function key($token) {
  23. return 'WORKING';
  24. }
  25. public static function hash($token) {
  26. return $token;
  27. }
  28. public function setUp() {
  29. $this->context = new MockFormRenderer();
  30. $this->subject = new Security(['context' => $this->context]);
  31. FormSignature::config([
  32. 'secret' => 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
  33. ]);
  34. }
  35. /**
  36. * Tests that the helper correctly generates a security token field.
  37. */
  38. public function testRequestToken() {
  39. $result = explode(' ', $this->subject->requestToken());
  40. $this->assertEqual('<input', $result[0]);
  41. $this->assertEqual('type="hidden"', $result[1]);
  42. $this->assertEqual('name="security[token]"', $result[2]);
  43. $this->assertEqual('/>', $result[4]);
  44. $result = explode('=', $result[3]);
  45. $this->assertEqual('value', $result[0]);
  46. $result = trim($result[1], '"');
  47. $this->assertPattern('/^\$\d\w\$\d{2}\$[A-Za-z0-9\.\/]{53}$/', $result);
  48. }
  49. /**
  50. * Tests that the helper can be constructed with a custom configuration.
  51. */
  52. public function testConstruct() {
  53. $this->subject = new Security(['context' => $this->context, 'classes' => [
  54. 'password' => __CLASS__,
  55. 'requestToken' => __CLASS__
  56. ]]);
  57. $this->assertPattern('/value="WORKING"/', $this->subject->requestToken());
  58. }
  59. /**
  60. * Tests that the `Security` helper correctly binds to the `Form` helper to collect field
  61. * information and generate a signature.
  62. */
  63. public function testFormSignatureGeneration() {
  64. $form = new Form(['context' => $this->context]);
  65. $this->subject->sign($form);
  66. ob_start();
  67. $content = [
  68. $form->create(null, ['url' => 'http:///']),
  69. $form->text('email', ['value' => 'foo@bar']),
  70. $form->password('pass'),
  71. $form->hidden('active', ['value' => 'true']),
  72. $form->end()
  73. ];
  74. $signature = ob_get_clean();
  75. preg_match('/value="([^"]+)"/', $signature, $match);
  76. list(, $signature) = $match;
  77. $expected = [
  78. '#a%3A1%3A%7Bs%3A6%3A%22active%22%3Bs%3A4%3A%22true%22%3B%7D',
  79. 'a%3A0%3A%7B%7D',
  80. '[a-z0-9]{128}#'
  81. ];
  82. $this->assertPattern(join('::', $expected), $signature);
  83. $request = new Request(['data' => [
  84. 'email' => 'foo@baz',
  85. 'pass' => 'whatever',
  86. 'active' => 'true',
  87. 'security' => compact('signature')
  88. ]]);
  89. $this->assertTrue(FormSignature::check($request));
  90. }
  91. public function testFormSignatureWithLockedAndExcluded() {
  92. $form = new Form(['context' => $this->context]);
  93. $validator = 'lithium\tests\mocks\security\validation\MockFormSignature';
  94. $helper = new Security([
  95. 'context' => $this->context,
  96. 'classes' => [
  97. 'formSignature' => $validator
  98. ]
  99. ]);
  100. $helper->sign($form);
  101. ob_start();
  102. $content = [
  103. $form->create(null, ['url' => 'http:///']),
  104. $form->text('email', ['value' => 'foo@bar']),
  105. $form->password('pass'),
  106. $form->hidden('id', ['value' => 23]),
  107. $form->text('foo', ['value' => 'bar', 'exclude' => true]),
  108. $form->hidden('active', ['value' => 'true', 'exclude' => true, 'locked' => false]),
  109. $form->end()
  110. ];
  111. ob_get_clean();
  112. $result = $validator::$compile[0]['in'];
  113. $expected = [
  114. 'fields' => [
  115. 'email', 'pass'
  116. ],
  117. 'excluded' => [
  118. 'foo',
  119. 'active'
  120. ],
  121. 'locked' => [
  122. 'id' => 23
  123. ]
  124. ];
  125. $compiledSignature = $validator::$compile[0]['out'];
  126. $this->assertEqual($expected, $result);
  127. $request = new Request([
  128. 'data' => [
  129. 'security' => ['signature' => $compiledSignature]
  130. ]
  131. ]);
  132. $validator::check($request);
  133. $expected = $compiledSignature;
  134. $result = $validator::$parse[0]['in']['signature'];
  135. $this->assertEqual($expected, $result);
  136. $result = $validator::$parse[0]['out'];
  137. $expected = [
  138. 'excluded' => [
  139. 'active',
  140. 'foo'
  141. ],
  142. 'locked' => [
  143. 'id' => 23
  144. ]
  145. ];
  146. $this->assertEqual($expected, $result);
  147. $validator::reset();
  148. }
  149. public function testFormSignatureWithLabelField() {
  150. $form = new Form(['context' => $this->context]);
  151. $this->subject->sign($form);
  152. ob_start();
  153. $content = [
  154. $form->create(null, ['url' => 'http:///']),
  155. $form->label('foo'),
  156. $form->text('email', ['value' => 'foo@bar']),
  157. $form->end()
  158. ];
  159. $signature = ob_get_clean();
  160. preg_match('/value="([^"]+)"/', $signature, $match);
  161. list(, $signature) = $match;
  162. $result = $signature;
  163. $data = [
  164. 'fields' => [
  165. 'email' => 'foo@bar',
  166. ]
  167. ];
  168. $expected = FormSignature::key($data);
  169. $this->assertEqual($expected, $result);
  170. }
  171. public function testFormSignatureWithMethodPUT() {
  172. $form = new Form(['context' => $this->context]);
  173. $this->subject->sign($form);
  174. ob_start();
  175. $content = [
  176. $form->create(null, ['url' => 'http:///', 'method' => 'PUT']),
  177. $form->text('email', ['value' => 'foo@bar']),
  178. $form->end()
  179. ];
  180. $signature = ob_get_clean();
  181. preg_match('/value="([^"]+)"/', $signature, $match);
  182. list(, $signature) = $match;
  183. $request = new Request(['data' => [
  184. '_method' => 'PUT',
  185. 'email' => 'foo@baz',
  186. 'security' => compact('signature')
  187. ]]);
  188. $this->assertTrue(FormSignature::check($request));
  189. }
  190. }
  191. ?>