3 declare(strict_types=1);
22 require_once
'libs/composer/vendor/autoload.php';
23 require_once
'Services/User/classes/class.ilUserPasswordManager.php';
24 require_once
'Services/User/classes/class.ilUserPasswordEncoderFactory.php';
25 require_once
'Services/Password/classes/class.ilBasePasswordEncoder.php';
26 require_once
'Services/Utilities/classes/class.ilUtil.php';
27 require_once
'Services/User/classes/class.ilObjUser.php';
28 require_once
'Services/User/exceptions/class.ilUserException.php';
29 require_once
'Services/User/test/ilUserBaseTest.php';
64 protected function setUp(): void
66 vfs\vfsStream::setup();
67 $this->
setTestDirectory(vfs\vfsStream::newDirectory(
'tests')->at(vfs\vfsStreamWrapper::getRoot()));
89 'password_encoder' =>
'md5',
99 $this->expectException(TypeError::class);
100 $this->expectExceptionMessageMatches(
'/' . ilUserPasswordEncoderFactory::class .
'/');
103 'password_encoder' =>
'md5',
104 'encoder_factory' =>
'test',
115 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
116 $factory_mock->expects($this->exactly(2))->method(
'getSupportedEncoderNames')->will($this->onConsecutiveCalls(
127 'password_encoder' =>
'md5',
128 'encoder_factory' => $factory_mock,
131 $this->assertInstanceOf(
'ilUserPasswordManager', $password_manager);
132 $this->assertEquals(
'md5', $password_manager->getEncoderName());
133 $this->assertEquals($factory_mock, $password_manager->getEncoderFactory());
135 $this->assertTrue($password_manager->isEncodingTypeSupported(
'second_mockencoder'));
136 $this->assertFalse($password_manager->isEncodingTypeSupported(
'second_mockencoder'));
145 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
146 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
147 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
149 $user_mock->expects($this->once())->method(
'setPasswordSalt')->with($this->isType(
'string'));
150 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
151 $user_mock->expects($this->once())->method(
'setPasswordEncodingType')->with($this->equalTo(
'mockencoder'));
152 $user_mock->expects($this->once())->method(
'setPasswd')->with(
153 $this->equalTo(self::ENCODED_PASSWORD),
157 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
158 $encoder->expects($this->once())->method(
'requiresSalt')->willReturn(
true);
159 $encoder->expects($this->once())->method(
'encodePassword')
161 $this->equalTo(self::PASSWORD),
162 $this->isType(
'string')
163 )->willReturn(self::ENCODED_PASSWORD);
165 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
168 'password_encoder' =>
'mockencoder',
169 'encoder_factory' => $factory_mock,
173 $password_manager->encodePassword($user_mock, self::PASSWORD);
182 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
183 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
184 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
186 $user_mock->expects($this->once())->method(
'setPasswordSalt')->with($this->equalTo(null));
187 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(null);
188 $user_mock->expects($this->once())->method(
'setPasswordEncodingType')->with($this->equalTo(
'mockencoder'));
189 $user_mock->expects($this->once())->method(
'setPasswd')->with(
190 $this->equalTo(self::ENCODED_PASSWORD),
194 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
195 $encoder->expects($this->once())->method(
'requiresSalt')->willReturn(
false);
196 $encoder->expects($this->once())->method(
'encodePassword')->with(
197 $this->equalTo(self::PASSWORD),
199 )->willReturn(self::ENCODED_PASSWORD);
201 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
204 'password_encoder' =>
'mockencoder',
205 'encoder_factory' => $factory_mock,
209 $password_manager->encodePassword($user_mock, self::PASSWORD);
218 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
219 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
220 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
222 $user_mock->expects($this->atLeast(1))->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
223 $user_mock->expects($this->atLeast(1))->method(
'getPasswordEncodingType')->willReturn(
'mockencoder');
224 $user_mock->expects($this->atLeast(1))->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
225 $user_mock->expects($this->never())->method(
'resetPassword');
227 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
228 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
229 $this->equalTo(self::ENCODED_PASSWORD),
230 $this->equalTo(self::PASSWORD),
231 $this->isType(
'string')
233 $encoder->expects($this->once())->method(
'requiresReencoding')
234 ->with($this->equalTo(self::ENCODED_PASSWORD))
237 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
240 'password_encoder' =>
'mockencoder',
241 'encoder_factory' => $factory_mock,
245 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
254 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
255 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
256 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
258 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
259 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->willReturn(
'second_mockencoder');
260 $user_mock->expects($this->once())->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
261 $user_mock->expects($this->once())->method(
'resetPassword')->with(
262 $this->equalTo(self::PASSWORD),
263 $this->equalTo(self::PASSWORD)
266 $encoder->expects($this->once())->method(
'getName')->willReturn(
'second_mockencoder');
267 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
268 $this->equalTo(self::ENCODED_PASSWORD),
269 $this->equalTo(self::PASSWORD),
270 $this->isType(
'string')
272 $encoder->expects($this->never())->method(
'requiresReencoding')
273 ->with($this->equalTo(self::ENCODED_PASSWORD))
276 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
279 'password_encoder' =>
'mockencoder',
280 'encoder_factory' => $factory_mock,
284 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
293 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
294 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
295 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
297 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
298 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->willReturn(
'mockencoder');
299 $user_mock->expects($this->exactly(2))->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
300 $user_mock->expects($this->once())->method(
'resetPassword')->with(
301 $this->equalTo(self::PASSWORD),
302 $this->equalTo(self::PASSWORD)
305 $encoder->expects($this->once())->method(
'getName')->willReturn(
'mockencoder');
306 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
307 $this->equalTo(self::ENCODED_PASSWORD),
308 $this->equalTo(self::PASSWORD),
309 $this->isType(
'string')
311 $encoder->expects($this->once())->method(
'requiresReencoding')
312 ->with($this->equalTo(self::ENCODED_PASSWORD))
315 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
318 'password_encoder' =>
'mockencoder',
319 'encoder_factory' => $factory_mock,
323 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
332 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
333 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
334 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
336 $user_mock->expects($this->once())->method(
'getPasswordSalt')->willReturn(
'asuperrandomsalt');
337 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->willReturn(
'second_mockencoder');
338 $user_mock->expects($this->once())->method(
'getPasswd')->willReturn(self::ENCODED_PASSWORD);
339 $user_mock->expects($this->never())->method(
'resetPassword');
341 $encoder->expects($this->once())->method(
'getName')->willReturn(
'second_mockencoder');
342 $encoder->expects($this->never())->method(
'requiresReencoding');
343 $encoder->expects($this->once())->method(
'isPasswordValid')
345 $this->equalTo(self::ENCODED_PASSWORD),
346 $this->equalTo(self::PASSWORD),
347 $this->isType(
'string')
348 )->willReturn(
false);
350 $factory_mock->expects($this->once())->method(
'getEncoderByName')->willReturn($encoder);
353 'password_encoder' =>
'mockencoder',
354 'encoder_factory' => $factory_mock,
358 $this->assertFalse($password_manager->verifyPassword($user_mock, self::PASSWORD));
369 $this->assertInstanceOf(
'ilUserPasswordEncoderFactory',
$factory);
380 'default_password_encoder' =>
'md5',
383 $this->assertEquals(
'md5',
$factory->getDefaultEncoder());
385 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
386 $encoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'mockencoder');
388 $second_mockencoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
389 $second_mockencoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'second_mockencoder');
391 $factory->setEncoders([$encoder, $second_mockencoder]);
392 $this->assertCount(2,
$factory->getEncoders());
393 $this->assertCount(2,
$factory->getSupportedEncoderNames());
396 array_diff([
'mockencoder',
'second_mockencoder'],
$factory->getSupportedEncoderNames())
400 array_diff(
$factory->getSupportedEncoderNames(), [
'mockencoder',
'second_mockencoder'])
426 'default_password_encoder' =>
'md5',
429 $factory->getEncoderByName(
'phpunit');
442 $factory->getEncoderByName(
'phpunit',
true);
453 'default_password_encoder' =>
'phpunit',
456 $factory->getEncoderByName(
'phpunit',
true);
466 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
467 $encoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'mockencoder');
470 'default_password_encoder' => $encoder->getName(),
474 $this->assertEquals($encoder,
$factory->getEncoderByName(
'phpunit',
true));
484 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
485 $encoder->expects($this->atLeastOnce())->method(
'getName')->willReturn(
'mockencoder');
488 'default_password_encoder' => $encoder->getName(),
492 $this->assertEquals($encoder,
$factory->getEncoderByName(
'mockencoder',
true));
testPasswordManagerEncodesRawPasswordWithoutSalt()
testPasswordManagerNeverMigratesPasswordOnFailedVerificationWithVariantEncoders()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutValidFactory()
testFactoryReturnsTheDefaultEncoderIfAnUnsupportedEncoderIsRequestedAndASupportedDefaultEncoderWasSpecifiedInFallbackMode()
testExceptionIsRaisedIfAnUnsupportedEncoderIsRequestedFromFactory()
setTestDirectoryUrl(string $testDirectoryUrl)
testPasswordManagerVerifiesPassword()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutEncoderInformation()
assertException(string $exception_class)
vfs vfsStreamDirectory $testDirectory
setTestDirectory(vfs\vfsStreamDirectory $testDirectory)
testInstanceCanBeCreated()
testPasswordManagerEncodesRawPasswordWithSalt()
testFactoryReturnsCorrectEncoderIfAMatchingEncoderWasFound()
testFactoryCanBeCreated()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndNoDefaultEncoderWasSpecifiedInFallbackMode()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndTheDefaultEncoderDoesNotMatchOneOfTheSupportedEncodersInFallbackMode()
testPasswordManagerMigratesPasswordOnVerificationWithVariantEncoders()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutFactory()
testPasswordManagerReencodesPasswordIfReencodingIsNecessary()
testGettersOfFactoryShouldReturnWhatWasSetBySetters()