19 declare(strict_types=1);
59 return class_exists(
'org\bovigo\vfs\vfsStreamWrapper');
65 $this->markTestSkipped(
'Skipped test, vfsStream (https://github.com/bovigo/vfsStream) required');
67 vfs\vfsStream::setup();
68 $this->
setTestDirectory(vfs\vfsStream::newDirectory(
'test')->at(vfs\vfsStreamWrapper::getRoot()));
79 for ($i = 4; $i <= 31; ++$i) {
80 $data[sprintf(
'Costs: %s', $i)] = [(string) $i];
89 'data_directory' => $this->testDirectoryUrl
98 'ignore_security_flaw' =>
true,
99 'data_directory' => $this->testDirectoryUrl
101 $this->assertTrue($security_flaw_ignoring_encoder->isSecurityFlawIgnored());
104 'ignore_security_flaw' =>
false,
105 'data_directory' => $this->testDirectoryUrl
107 $this->assertFalse($security_flaw_respecting_encoder->isSecurityFlawIgnored());
110 'cost' => self::VALID_COSTS,
111 'data_directory' => $this->testDirectoryUrl
113 $this->assertInstanceOf(ilBcryptPasswordEncoder::class, $encoder);
114 $this->assertSame(self::VALID_COSTS, $encoder->getCosts());
115 $this->assertFalse($encoder->isSecurityFlawIgnored());
116 $encoder->setClientSalt(self::CLIENT_SALT);
121 #[Depends('testInstanceCanBeCreated')] 127 $this->assertSame($expected, $encoder->
getCosts());
130 #[Depends('testInstanceCanBeCreated')] 133 $this->expectException(ilPasswordException::class);
137 #[Depends('testInstanceCanBeCreated')] 140 $this->expectException(ilPasswordException::class);
144 #[DoesNotPerformAssertions] 145 #[Depends('testInstanceCanBeCreated')] 146 #[DataProvider('costsProvider')] 152 #[Depends('testInstanceCanBeCreated')] 156 $encoder->
setCosts(self::VALID_COSTS);
157 $encoded_password = $encoder->
encodePassword(self::PASSWORD, self::PASSWORD_SALT);
158 $this->assertTrue($encoder->
isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
159 $this->assertFalse($encoder->
isPasswordValid($encoded_password, self::WRONG_PASSWORD, self::PASSWORD_SALT));
164 #[Depends('testInstanceCanBeCreated')] 168 $this->expectException(ilPasswordException::class);
169 $encoder->
setCosts(self::VALID_COSTS);
170 $encoder->
encodePassword(str_repeat(
'a', 5000), self::PASSWORD_SALT);
173 #[Depends('testInstanceCanBeCreated')] 177 $encoder->
setCosts(self::VALID_COSTS);
178 $this->assertFalse($encoder->
isPasswordValid(
'encoded', str_repeat(
'a', 5000), self::PASSWORD_SALT));
181 #[Depends('testInstanceCanBeCreated')] 187 #[Depends('testInstanceCanBeCreated')] 193 #[Depends('testInstanceCanBeCreated')] 196 $this->assertSame(
'bcrypt', $encoder->
getName());
203 $this->expectException(ilPasswordException::class);
205 $encoder->setClientSalt(
null);
206 $encoder->setCosts(self::VALID_COSTS);
207 $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
214 $this->expectException(ilPasswordException::class);
216 $encoder->setClientSalt(
null);
217 $encoder->setCosts(self::VALID_COSTS);
218 $encoder->isPasswordValid(
'12121212', self::PASSWORD, self::PASSWORD_SALT);
225 $this->testDirectory->chmod(0777);
229 $this->assertSame(self::CLIENT_SALT, $encoder->getClientSalt());
236 $this->testDirectory->chmod(0777);
239 $this->assertNotNull($encoder->getClientSalt());
246 $this->expectException(ilPasswordException::class);
247 $this->testDirectory->chmod(0000);
257 $encoder->setBackwardCompatibility(
true);
258 $this->assertTrue($encoder->isBackwardCompatibilityEnabled());
259 $encoder->setBackwardCompatibility(
false);
260 $this->assertFalse($encoder->isBackwardCompatibilityEnabled());
268 $encoder->setClientSalt(self::CLIENT_SALT);
269 $encoder->setBackwardCompatibility(
true);
271 $encoded_password = $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
272 $this->assertTrue($encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
273 $this->assertSame(
'$2a$', substr($encoded_password, 0, 4));
276 $another_encoder->setClientSalt(self::CLIENT_SALT);
278 $another_encoder->setBackwardCompatibility(
false);
279 $another_encoded_password = $another_encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
280 $this->assertSame(
'$2y$', substr($another_encoded_password, 0, 4));
281 $this->assertTrue($another_encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
288 $this->expectException(ilPasswordException::class);
290 $encoder->setClientSalt(self::CLIENT_SALT);
291 $encoder->setBackwardCompatibility(
true);
292 $encoder->encodePassword(self::PASSWORD . chr(195), self::PASSWORD_SALT);
295 #[DoesNotPerformAssertions] 301 $encoder->setClientSalt(self::CLIENT_SALT);
302 $encoder->setBackwardCompatibility(
true);
303 $encoder->setIsSecurityFlawIgnored(
true);
304 $encoder->encodePassword(self::PASSWORD . chr(195), self::PASSWORD_SALT);
testExceptionIfPasswordsContainA8BitCharacterAndBackwardCompatibilityIsEnabled()
const string SALT_STORAGE_FILENAME
testCostsCannotBeSetAboveRange(ilBcryptPasswordEncoder $encoder)
const string WRONG_PASSWORD
requiresSalt()
Returns whether the encoder requires a salt.
testCostsCanBeRetrievedWhenCostsAreSet(ilBcryptPasswordEncoder $encoder)
skipIfvfsStreamNotSupported()
getInstanceWithConfiguredDataDirectory()
testClientSaltIsGeneratedWhenNoClientSaltExistsYet()
encodePassword(string $raw, string $salt)
Encodes the raw password.
testEncoderDoesNotSupportReencoding(ilBcryptPasswordEncoder $encoder)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
const string PASSWORD_SALT
setTestDirectory(vfs\vfsStreamDirectory $testDirectory)
testPasswordShouldBeCorrectlyEncodedAndVerified(ilBcryptPasswordEncoder $encoder)
testInstanceCanBeCreatedAndInitializedWithClientSalt()
testExceptionIsRaisedIfSaltIsMissingIsOnEncoding()
vfs vfsStreamDirectory $testDirectory
testExceptionIsRaisedIfThePasswordExceedsTheSupportedLengthOnEncoding(ilBcryptPasswordEncoder $encoder)
requiresReencoding(string $encoded)
Returns whether the encoded password needs to be re-encoded.
testBackwardCompatibility()
testExceptionIsRaisedIfSaltIsMissingIsOnVerification()
testPasswordVerificationShouldFailIfTheRawPasswordExceedsTheSupportedLength(ilBcryptPasswordEncoder $encoder)
testBackwardCompatibilityCanBeRetrievedWhenBackwardCompatibilityIsSet()
testCostsCanBeSetInRange(string $costs, ilBcryptPasswordEncoder $encoder)
testInstanceCanBeCreated()
getName()
Returns a unique name/id of the concrete password encoder.
testExceptionIsRaisedWhenClientSaltCouldNotBeGeneratedInCaseNoClientSaltExistsYet()
testCostsCannotBeSetBelowRange(ilBcryptPasswordEncoder $encoder)
testNameShouldBeBcrypt(ilBcryptPasswordEncoder $encoder)
testEncoderReliesOnSalts(ilBcryptPasswordEncoder $encoder)
setTestDirectoryUrl(string $testDirectoryUrl)
isPasswordValid(string $encoded, string $raw, string $salt)
Checks a raw password against an encoded password.
testNoExceptionIfPasswordsContainA8BitCharacterAndBackwardCompatibilityIsEnabledWithIgnoredSecurityFlaw()