6 require_once
'libs/composer/vendor/autoload.php';
7 require_once
'Services/User/classes/class.ilUserPasswordManager.php';
8 require_once
'Services/User/classes/class.ilUserPasswordEncoderFactory.php';
9 require_once
'Services/Password/classes/class.ilBasePasswordEncoder.php';
10 require_once
'Services/Utilities/classes/class.ilUtil.php';
11 require_once
'Services/User/classes/class.ilObjUser.php';
12 require_once
'Services/User/exceptions/class.ilUserException.php';
13 require_once
'Services/User/test/ilUserBaseTest.php';
69 protected function setUp() : void
71 vfs\vfsStream::setup();
72 $this->
setTestDirectory(vfs\vfsStream::newDirectory(
'tests')->at(vfs\vfsStreamWrapper::getRoot()));
94 'password_encoder' =>
'md5',
104 if (version_compare(\PHPUnit\Runner\
Version::id(),
'9.0',
'>=')) {
105 $this->expectError(PHPUnit\Framework\Error\Error::class);
112 'password_encoder' =>
'md5',
113 'encoder_factory' =>
'test',
116 }
catch (TypeError
$e) {
117 throw new PHPUnit\Framework\Error\Error($e->getMessage(), $e->getCode(), $e->getFile(), $e->getLine());
127 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
128 $factory_mock->expects($this->exactly(2))->method(
'getSupportedEncoderNames')->will($this->onConsecutiveCalls(
139 'password_encoder' =>
'md5',
140 'encoder_factory' => $factory_mock,
143 $this->assertInstanceOf(
'ilUserPasswordManager', $password_manager);
144 $this->assertEquals(
'md5', $password_manager->getEncoderName());
145 $this->assertEquals($factory_mock, $password_manager->getEncoderFactory());
147 $this->assertTrue($password_manager->isEncodingTypeSupported(
'second_mockencoder'));
148 $this->assertFalse($password_manager->isEncodingTypeSupported(
'second_mockencoder'));
157 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
158 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
159 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
161 $user_mock->expects($this->once())->method(
'setPasswordSalt')->with($this->isType(
'string'));
162 $user_mock->expects($this->once())->method(
'getPasswordSalt')->will($this->returnValue(
'asuperrandomsalt'));
163 $user_mock->expects($this->once())->method(
'setPasswordEncodingType')->with($this->equalTo(
'mockencoder'));
164 $user_mock->expects($this->once())->method(
'setPasswd')->with(
165 $this->equalTo(self::ENCODED_PASSWORD),
169 $encoder->expects($this->once())->method(
'getName')->will($this->returnValue(
'mockencoder'));
170 $encoder->expects($this->once())->method(
'requiresSalt')->will($this->returnValue(
true));
171 $encoder->expects($this->once())->method(
'encodePassword')
173 $this->equalTo(self::PASSWORD),
174 $this->isType(
'string')
175 )->will($this->returnValue(self::ENCODED_PASSWORD));
177 $factory_mock->expects($this->once())->method(
'getEncoderByName')->will($this->returnValue($encoder));
180 'password_encoder' =>
'mockencoder',
181 'encoder_factory' => $factory_mock,
185 $password_manager->encodePassword($user_mock, self::PASSWORD);
194 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
195 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
196 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
198 $user_mock->expects($this->once())->method(
'setPasswordSalt')->with($this->equalTo(null));
199 $user_mock->expects($this->once())->method(
'getPasswordSalt')->will($this->returnValue(null));
200 $user_mock->expects($this->once())->method(
'setPasswordEncodingType')->with($this->equalTo(
'mockencoder'));
201 $user_mock->expects($this->once())->method(
'setPasswd')->with(
202 $this->equalTo(self::ENCODED_PASSWORD),
206 $encoder->expects($this->once())->method(
'getName')->will($this->returnValue(
'mockencoder'));
207 $encoder->expects($this->once())->method(
'requiresSalt')->will($this->returnValue(
false));
208 $encoder->expects($this->once())->method(
'encodePassword')->with(
209 $this->equalTo(self::PASSWORD),
211 )->will($this->returnValue(self::ENCODED_PASSWORD));
213 $factory_mock->expects($this->once())->method(
'getEncoderByName')->will($this->returnValue($encoder));
216 'password_encoder' =>
'mockencoder',
217 'encoder_factory' => $factory_mock,
221 $password_manager->encodePassword($user_mock, self::PASSWORD);
230 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
231 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
232 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
234 $user_mock->expects($this->atLeast(1))->method(
'getPasswordSalt')->will($this->returnValue(
'asuperrandomsalt'));
235 $user_mock->expects($this->atLeast(1))->method(
'getPasswordEncodingType')->will($this->returnValue(
'mockencoder'));
236 $user_mock->expects($this->atLeast(1))->method(
'getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
237 $user_mock->expects($this->never())->method(
'resetPassword');
239 $encoder->expects($this->once())->method(
'getName')->will($this->returnValue(
'mockencoder'));
240 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
241 $this->equalTo(self::ENCODED_PASSWORD),
242 $this->equalTo(self::PASSWORD),
243 $this->isType(
'string')
244 )->will($this->returnValue(
true));
245 $encoder->expects($this->once())->method(
'requiresReencoding')
246 ->with($this->equalTo(self::ENCODED_PASSWORD))
247 ->will($this->returnValue(
false));
249 $factory_mock->expects($this->once())->method(
'getEncoderByName')->will($this->returnValue($encoder));
252 'password_encoder' =>
'mockencoder',
253 'encoder_factory' => $factory_mock,
257 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
266 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
267 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
268 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
270 $user_mock->expects($this->once())->method(
'getPasswordSalt')->will($this->returnValue(
'asuperrandomsalt'));
271 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->will($this->returnValue(
'second_mockencoder'));
272 $user_mock->expects($this->once())->method(
'getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
273 $user_mock->expects($this->once())->method(
'resetPassword')->with(
274 $this->equalTo(self::PASSWORD),
275 $this->equalTo(self::PASSWORD)
278 $encoder->expects($this->once())->method(
'getName')->will($this->returnValue(
'second_mockencoder'));
279 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
280 $this->equalTo(self::ENCODED_PASSWORD),
281 $this->equalTo(self::PASSWORD),
282 $this->isType(
'string')
283 )->will($this->returnValue(
true));
284 $encoder->expects($this->never())->method(
'requiresReencoding')
285 ->with($this->equalTo(self::ENCODED_PASSWORD))
286 ->will($this->returnValue(
false));
288 $factory_mock->expects($this->once())->method(
'getEncoderByName')->will($this->returnValue($encoder));
291 'password_encoder' =>
'mockencoder',
292 'encoder_factory' => $factory_mock,
296 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
305 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
306 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
307 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
309 $user_mock->expects($this->once())->method(
'getPasswordSalt')->will($this->returnValue(
'asuperrandomsalt'));
310 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->will($this->returnValue(
'mockencoder'));
311 $user_mock->expects($this->exactly(2))->method(
'getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
312 $user_mock->expects($this->once())->method(
'resetPassword')->with(
313 $this->equalTo(self::PASSWORD),
314 $this->equalTo(self::PASSWORD)
317 $encoder->expects($this->once())->method(
'getName')->will($this->returnValue(
'mockencoder'));
318 $encoder->expects($this->once())->method(
'isPasswordValid')->with(
319 $this->equalTo(self::ENCODED_PASSWORD),
320 $this->equalTo(self::PASSWORD),
321 $this->isType(
'string')
322 )->will($this->returnValue(
true));
323 $encoder->expects($this->once())->method(
'requiresReencoding')
324 ->with($this->equalTo(self::ENCODED_PASSWORD))
325 ->will($this->returnValue(
true));
327 $factory_mock->expects($this->once())->method(
'getEncoderByName')->will($this->returnValue($encoder));
330 'password_encoder' =>
'mockencoder',
331 'encoder_factory' => $factory_mock,
335 $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
344 $user_mock = $this->getMockBuilder(ilObjUser::class)->disableOriginalConstructor()->getMock();
345 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
346 $factory_mock = $this->getMockBuilder(ilUserPasswordEncoderFactory::class)->disableOriginalConstructor()->getMock();
348 $user_mock->expects($this->once())->method(
'getPasswordSalt')->will($this->returnValue(
'asuperrandomsalt'));
349 $user_mock->expects($this->once())->method(
'getPasswordEncodingType')->will($this->returnValue(
'second_mockencoder'));
350 $user_mock->expects($this->once())->method(
'getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
351 $user_mock->expects($this->never())->method(
'resetPassword');
353 $encoder->expects($this->once())->method(
'getName')->will($this->returnValue(
'second_mockencoder'));
354 $encoder->expects($this->never())->method(
'requiresReencoding');
355 $encoder->expects($this->once())->method(
'isPasswordValid')
357 $this->equalTo(self::ENCODED_PASSWORD),
358 $this->equalTo(self::PASSWORD),
359 $this->isType(
'string')
360 )->will($this->returnValue(
false));
362 $factory_mock->expects($this->once())->method(
'getEncoderByName')->will($this->returnValue($encoder));
365 'password_encoder' =>
'mockencoder',
366 'encoder_factory' => $factory_mock,
370 $this->assertFalse($password_manager->verifyPassword($user_mock, self::PASSWORD));
381 $this->assertInstanceOf(
'ilUserPasswordEncoderFactory',
$factory);
392 'default_password_encoder' =>
'md5',
395 $this->assertEquals(
'md5',
$factory->getDefaultEncoder());
397 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
398 $encoder->expects($this->atLeastOnce())->method(
'getName')->will($this->returnValue(
'mockencoder'));
400 $second_mockencoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
401 $second_mockencoder->expects($this->atLeastOnce())->method(
'getName')->will($this->returnValue(
'second_mockencoder'));
403 $factory->setEncoders([$encoder, $second_mockencoder]);
404 $this->assertCount(2,
$factory->getEncoders());
405 $this->assertCount(2,
$factory->getSupportedEncoderNames());
408 array_diff([
'mockencoder',
'second_mockencoder'],
$factory->getSupportedEncoderNames())
412 array_diff(
$factory->getSupportedEncoderNames(), [
'mockencoder',
'second_mockencoder'])
437 'default_password_encoder' =>
'md5',
440 $factory->getEncoderByName(
'phpunit');
453 $factory->getEncoderByName(
'phpunit',
true);
464 'default_password_encoder' =>
'phpunit',
467 $factory->getEncoderByName(
'phpunit',
true);
477 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
478 $encoder->expects($this->atLeastOnce())->method(
'getName')->will($this->returnValue(
'mockencoder'));
481 'default_password_encoder' => $encoder->getName(),
485 $this->assertEquals($encoder,
$factory->getEncoderByName(
'phpunit',
true));
495 $encoder = $this->getMockBuilder(ilBasePasswordEncoder::class)->disableOriginalConstructor()->getMock();
496 $encoder->expects($this->atLeastOnce())->method(
'getName')->will($this->returnValue(
'mockencoder'));
499 'default_password_encoder' => $encoder->getName(),
503 $this->assertEquals($encoder,
$factory->getEncoderByName(
'mockencoder',
true));
testPasswordManagerEncodesRawPasswordWithoutSalt()
testPasswordManagerNeverMigratesPasswordOnFailedVerificationWithVariantEncoders()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutValidFactory()
testFactoryReturnsTheDefaultEncoderIfAnUnsupportedEncoderIsRequestedAndASupportedDefaultEncoderWasSpecifiedInFallbackMode()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderWasInjected()
testExceptionIsRaisedIfAnUnsupportedEncoderIsRequestedFromFactory()
assertException($exception_class)
setTestDirectoryUrl(string $testDirectoryUrl)
testPasswordManagerVerifiesPassword()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutEncoderInformation()
setTestDirectory(vfs\vfsStreamDirectory $testDirectory)
testInstanceCanBeCreated()
testPasswordManagerEncodesRawPasswordWithSalt()
testFactoryReturnsCorrectEncoderIfAMatchingEncoderWasFound()
testFactoryCanBeCreated()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndNoDefaultEncoderWasSpecifiedInFallbackMode()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndTheDefaultEncoderDoesNotMatchOneOfTheSupportedEncodersInFallbackMode()
testPasswordManagerMigratesPasswordOnVerificationWithVariantEncoders()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutFactory()
testPasswordManagerReencodesPasswordIfReencodingIsNecessary()
testGettersOfFactoryShouldReturnWhatWasSetBySetters()