19 declare(strict_types=1);
53 protected function setUp(): void
55 vfs\vfsStream::setup();
56 $this->
setTestDirectory(vfs\vfsStream::newDirectory(
'tests')->at(vfs\vfsStreamWrapper::getRoot()));
67 $this->expectException(ilUserException::class);
76 $this->expectException(ilUserException::class);
78 'password_encoder' =>
'md5',
88 $this->expectException(TypeError::class);
89 $this->expectExceptionMessageMatches(
'/' . preg_quote(LocalUserPasswordManager::class,
'/') .
'/');
92 'password_encoder' =>
'md5',
93 'encoder_factory' =>
'test',
104 $factory_mock = $this->getMockBuilder(LocalUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
105 $factory_mock->expects($this->exactly(2))->method(
'getSupportedEncoderNames')->will($this->onConsecutiveCalls(
116 'password_encoder' =>
'md5',
117 'encoder_factory' => $factory_mock,
120 $this->assertInstanceOf(LocalUserPasswordManager::class, $password_manager);
121 $this->assertEquals(
'md5', $password_manager->getEncoderName());
122 $this->assertEquals($factory_mock, $password_manager->getEncoderFactory());
124 $this->assertTrue($password_manager->isEncodingTypeSupported(
'second_mockencoder'));
125 $this->assertFalse($password_manager->isEncodingTypeSupported(
'second_mockencoder'));
134 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
135 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
136 $factory_mock = $this->getMockBuilder(LocalUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
138 $user_mock->expects($this->once())->method(
'setPasswordSalt')->with($this->isType(
'string'));
139 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
140 $user_mock->expects($this->once())->method(
'setPasswordEncodingType')->with($this->equalTo(
'mockencoder'));
141 $user_mock->expects($this->once())->method(
'setPasswd')->with(
142 $this->equalTo(self::ENCODED_PASSWORD),
146 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
147 $encoder->expects($this->once())->method(
'requiresSalt')->willReturn(
true);
148 $encoder->expects($this->once())->method(
'encodePassword')
150 $this->equalTo(self::PASSWORD),
151 $this->isType(
'string')
152 )->willReturn(self::ENCODED_PASSWORD)
155 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
158 'password_encoder' =>
'mockencoder',
159 'encoder_factory' => $factory_mock,
163 $password_manager->encodePassword($user_mock, self::PASSWORD);
172 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
173 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
174 $factory_mock = $this->getMockBuilder(LocalUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
176 $user_mock->expects($this->once())->method(
'setPasswordSalt')->with($this->equalTo(
null));
177 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
null);
178 $user_mock->expects($this->once())->method(
'setPasswordEncodingType')->with($this->equalTo(
'mockencoder'));
179 $user_mock->expects($this->once())->method(
'setPasswd')->with(
180 $this->equalTo(self::ENCODED_PASSWORD),
184 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
185 $encoder->expects($this->once())->method(
'requiresSalt')->willReturn(
false);
186 $encoder->expects($this->once())->method(
'encodePassword')->with(
187 $this->equalTo(self::PASSWORD),
189 )->willReturn(self::ENCODED_PASSWORD);
191 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
194 'password_encoder' =>
'mockencoder',
195 'encoder_factory' => $factory_mock,
199 $password_manager->encodePassword($user_mock, self::PASSWORD);
208 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
209 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
210 $factory_mock = $this->getMockBuilder(LocalUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
212 $user_mock->expects($this->atLeast(1))->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
213 $user_mock->expects($this->atLeast(1))->method(
'getPasswordEncodingType')->willReturn(
'mockencoder');
214 $user_mock->expects($this->atLeast(1))->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
215 $user_mock->expects($this->never())->method(
'resetPassword');
217 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
218 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
219 $this->equalTo(self::ENCODED_PASSWORD),
220 $this->equalTo(self::PASSWORD),
221 $this->isType(
'string')
223 $encoder->expects($this->once())->method(
'requiresReencoding')
224 ->with($this->equalTo(self::ENCODED_PASSWORD))
228 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
231 'password_encoder' =>
'mockencoder',
232 'encoder_factory' => $factory_mock,
236 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
245 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
246 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
247 $factory_mock = $this->getMockBuilder(LocalUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
249 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
250 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->willReturn(
'second_mockencoder');
251 $user_mock->expects($this->once())->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
252 $user_mock->expects($this->once())->method(
'resetPassword')->with(
253 $this->equalTo(self::PASSWORD),
254 $this->equalTo(self::PASSWORD)
257 $encoder->expects($this->once())->method(
'getName')->willReturn(
'second_mockencoder');
258 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
259 $this->equalTo(self::ENCODED_PASSWORD),
260 $this->equalTo(self::PASSWORD),
261 $this->isType(
'string')
263 $encoder->expects($this->never())->method(
'requiresReencoding')
264 ->with($this->equalTo(self::ENCODED_PASSWORD))
268 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
271 'password_encoder' =>
'mockencoder',
272 'encoder_factory' => $factory_mock,
276 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
285 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
286 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
287 $factory_mock = $this->getMockBuilder(LocalUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
289 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
290 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->willReturn(
'mockencoder');
291 $user_mock->expects($this->exactly(2))->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
292 $user_mock->expects($this->once())->method(
'resetPassword')->with(
293 $this->equalTo(self::PASSWORD),
294 $this->equalTo(self::PASSWORD)
297 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
298 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
299 $this->equalTo(self::ENCODED_PASSWORD),
300 $this->equalTo(self::PASSWORD),
301 $this->isType(
'string')
303 $encoder->expects($this->once())->method(
'requiresReencoding')
304 ->with($this->equalTo(self::ENCODED_PASSWORD))
308 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
311 'password_encoder' =>
'mockencoder',
312 'encoder_factory' => $factory_mock,
316 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
325 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
326 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
327 $factory_mock = $this->getMockBuilder(LocalUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
329 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
330 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->willReturn(
'second_mockencoder');
331 $user_mock->expects($this->once())->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
332 $user_mock->expects($this->never())->method(
'resetPassword');
334 $encoder->expects($this->once())->method(
'getName')->willReturn(
'second_mockencoder');
335 $encoder->expects($this->never())->method(
'requiresReencoding');
336 $encoder->expects($this->once())->method(
'isPasswordValid')
338 $this->equalTo(self::ENCODED_PASSWORD),
339 $this->equalTo(self::PASSWORD),
340 $this->isType(
'string')
344 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
347 'password_encoder' =>
'mockencoder',
348 'encoder_factory' => $factory_mock,
352 $this->assertFalse($password_manager->verifyPassword($user_mock, self::PASSWORD));
363 $this->assertInstanceOf(LocalUserPasswordEncoderFactory::class, $factory);
374 'default_password_encoder' =>
'md5',
377 $this->assertEquals(
'md5', $factory->getDefaultEncoder());
379 $encoder = $this->createMock(ilPasswordEncoder::class);
380 $encoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'mockencoder');
381 $encoder->expects($this->atLeastOnce())->method(
'isSupportedByRuntime')->willReturn(
true);
383 $second_mockencoder = $this->createMock(ilPasswordEncoder::class);
384 $second_mockencoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'second_mockencoder');
385 $second_mockencoder->expects($this->atLeastOnce())->method(
'isSupportedByRuntime')->willReturn(
true);
387 $factory->setSupportedEncoders([$encoder, $second_mockencoder]);
388 $this->assertCount(2, $factory->getSupportedEncoders());
389 $this->assertCount(2, $factory->getSupportedEncoderNames());
392 array_diff([
'mockencoder',
'second_mockencoder'], $factory->getSupportedEncoderNames())
396 array_diff($factory->getSupportedEncoderNames(), [
'mockencoder',
'second_mockencoder'])
406 $this->expectException(ilUserException::class);
410 $factory->setSupportedEncoders([
'phpunit']);
419 $this->expectException(ilUserException::class);
423 $factory->getEncoderByName(
'phpunit');
432 $this->expectException(ilUserException::class);
434 'default_password_encoder' =>
'phpunit',
437 $factory->getEncoderByName(
'phpunit');
447 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
448 $encoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'mockencoder');
449 $encoder->expects($this->atLeastOnce())->method(
'isSupportedByRuntime')->willReturn(
true);
452 'default_password_encoder' => $encoder->getName(),
456 $this->assertEquals($encoder, $factory->getEncoderByName(
'phpunit'));
466 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
467 $encoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'mockencoder');
468 $encoder->expects($this->atLeastOnce())->method(
'isSupportedByRuntime')->willReturn(
true);
471 'default_password_encoder' => $encoder->getName(),
475 $this->assertEquals($encoder, $factory->getEncoderByName(
'mockencoder'));
testFactoryCanBeCreated()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutFactory()
testPasswordManagerEncodesRawPasswordWithSalt()
testGettersOfFactoryShouldReturnWhatWasSetBySetters()
testPasswordManagerMigratesPasswordOnVerificationWithVariantEncoders()
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
vfs vfsStreamDirectory $testDirectory
testFactoryReturnsTheDefaultEncoderIfAnUnsupportedEncoderIsRequestedAndASupportedDefaultEncoderWasSpecifiedInFallbackMode()
testInstanceCanBeCreated()
setTestDirectory(vfs\vfsStreamDirectory $testDirectory)
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndNoDefaultEncoderWasSpecifiedInFallbackMode()
testPasswordManagerVerifiesPassword()
setTestDirectoryUrl(string $testDirectoryUrl)
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutValidFactory()
testPasswordManagerNeverMigratesPasswordOnFailedVerificationWithVariantEncoders()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutEncoderInformation()
testFactoryReturnsCorrectEncoderIfAMatchingEncoderWasFound()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderWasInjected()
testPasswordManagerEncodesRawPasswordWithoutSalt()
testPasswordManagerReencodesPasswordIfReencodingIsNecessary()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndTheDefaultEncoderDoesNotMatchOneOfTheSupportedEncodersInFallbackMode()
setSupportedEncoders(array $supported_encoders)