[!!!][TASK] Extract testing framework for TYPO3
[Packages/TYPO3.CMS.git] / typo3 / sysext / saltedpasswords / Tests / Unit / Salt / SaltFactoryTest.php
1 <?php
2 namespace TYPO3\CMS\Saltedpasswords\Tests\Unit\Salt;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Crypto\Random;
18
19 /**
20 * Testcase for SaltFactory
21 */
22 class SaltFactoryTest extends \TYPO3\CMS\Components\TestingFramework\Core\UnitTestCase
23 {
24 /**
25 * Keeps instance of object to test.
26 *
27 * @var \TYPO3\CMS\Saltedpasswords\Salt\AbstractSalt
28 */
29 protected $objectInstance = null;
30
31 /**
32 * Sets up the fixtures for this testcase.
33 *
34 * @return void
35 */
36 protected function setUp()
37 {
38 $this->objectInstance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance();
39 }
40
41 /**
42 * @test
43 */
44 public function objectInstanceNotNull()
45 {
46 $this->assertNotNull($this->objectInstance);
47 }
48
49 /**
50 * @test
51 */
52 public function objectInstanceExtendsAbstractClass()
53 {
54 $this->assertTrue(is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\AbstractSalt::class));
55 }
56
57 /**
58 * @test
59 */
60 public function objectInstanceImplementsInterface()
61 {
62 $this->assertTrue(method_exists($this->objectInstance, 'checkPassword'), 'Missing method checkPassword() from interface ' . \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface::class . '.');
63 $this->assertTrue(method_exists($this->objectInstance, 'isHashUpdateNeeded'), 'Missing method isHashUpdateNeeded() from interface ' . \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface::class . '.');
64 $this->assertTrue(method_exists($this->objectInstance, 'isValidSalt'), 'Missing method isValidSalt() from interface ' . \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface::class . '.');
65 $this->assertTrue(method_exists($this->objectInstance, 'isValidSaltedPW'), 'Missing method isValidSaltedPW() from interface ' . \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface::class . '.');
66 $this->assertTrue(method_exists($this->objectInstance, 'getHashedPassword'), 'Missing method getHashedPassword() from interface ' . \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface::class . '.');
67 $this->assertTrue(method_exists($this->objectInstance, 'getSaltLength'), 'Missing method getSaltLength() from interface ' . \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface::class . '.');
68 }
69
70 /**
71 * @test
72 */
73 public function base64EncodeReturnsProperLength()
74 {
75 // 3 Bytes should result in a 6 char length base64 encoded string
76 // used for MD5 and PHPass salted hashing
77 $byteLength = 3;
78 $reqLengthBase64 = (int)ceil($byteLength * 8 / 6);
79 $randomBytes = (new Random())->generateRandomBytes($byteLength);
80 $this->assertTrue(strlen($this->objectInstance->base64Encode($randomBytes, $byteLength)) == $reqLengthBase64);
81 // 16 Bytes should result in a 22 char length base64 encoded string
82 // used for Blowfish salted hashing
83 $byteLength = 16;
84 $reqLengthBase64 = (int)ceil($byteLength * 8 / 6);
85 $randomBytes = (new Random())->generateRandomBytes($byteLength);
86 $this->assertTrue(strlen($this->objectInstance->base64Encode($randomBytes, $byteLength)) == $reqLengthBase64);
87 }
88
89 /**
90 * @test
91 */
92 public function objectInstanceForMD5Salts()
93 {
94 $saltMD5 = '$1$rasmusle$rISCgZzpwk3UhDidwXvin0';
95 $this->objectInstance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltMD5);
96 $this->assertTrue(get_class($this->objectInstance) == \TYPO3\CMS\Saltedpasswords\Salt\Md5Salt::class || is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\Md5Salt::class));
97 }
98
99 /**
100 * @test
101 */
102 public function objectInstanceForBlowfishSalts()
103 {
104 $saltBlowfish = '$2a$07$abcdefghijklmnopqrstuuIdQV69PAxWYTgmnoGpe0Sk47GNS/9ZW';
105 $this->objectInstance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltBlowfish);
106 $this->assertTrue(get_class($this->objectInstance) == \TYPO3\CMS\Saltedpasswords\Salt\BlowfishSalt::class || is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\BlowfishSalt::class));
107 }
108
109 /**
110 * @test
111 */
112 public function objectInstanceForPhpassSalts()
113 {
114 $saltPhpass = '$P$CWF13LlG/0UcAQFUjnnS4LOqyRW43c.';
115 $this->objectInstance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltPhpass);
116 $this->assertTrue(get_class($this->objectInstance) == \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class || is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class));
117 }
118
119 /**
120 * @test
121 */
122 public function objectInstanceForPbkdf2Salts()
123 {
124 $saltPbkdf2 = '$pbkdf2-sha256$6400$0ZrzXitFSGltTQnBWOsdAw$Y11AchqV4b0sUisdZd0Xr97KWoymNE0LNNrnEgY4H9M';
125 $this->objectInstance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltPbkdf2);
126 $this->assertTrue(get_class($this->objectInstance) == \TYPO3\CMS\Saltedpasswords\Salt\Pbkdf2Salt::class || is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\Pbkdf2Salt::class));
127 }
128
129 /**
130 * @test
131 */
132 public function resettingFactoryInstanceSucceeds()
133 {
134 $defaultClassNameToUse = \TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::getDefaultSaltingHashingMethod();
135 if ($defaultClassNameToUse == \TYPO3\CMS\Saltedpasswords\Salt\Md5Salt::class) {
136 $saltedPW = '$P$CWF13LlG/0UcAQFUjnnS4LOqyRW43c.';
137 } else {
138 $saltedPW = '$1$rasmusle$rISCgZzpwk3UhDidwXvin0';
139 }
140 $this->objectInstance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltedPW);
141 // resetting
142 $this->objectInstance = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(null);
143 $this->assertTrue(get_class($this->objectInstance) == $defaultClassNameToUse || is_subclass_of($this->objectInstance, $defaultClassNameToUse));
144 }
145 }