ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
ilObjUserPasswordTest.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2014 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
5 
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';
14 
21 {
23  const PASSWORD = 'password';
24 
26  const ENCODED_PASSWORD = 'encoded';
27 
29  protected $testDirectory;
30 
32  protected $testDirectoryUrl;
33 
37  public function getTestDirectory() : vfs\vfsStreamDirectory
38  {
39  return $this->testDirectory;
40  }
41 
45  public function setTestDirectory(vfs\vfsStreamDirectory $testDirectory) : void
46  {
47  $this->testDirectory = $testDirectory;
48  }
49 
53  public function getTestDirectoryUrl() : string
54  {
56  }
57 
61  public function setTestDirectoryUrl(string $testDirectoryUrl) : void
62  {
63  $this->testDirectoryUrl = $testDirectoryUrl;
64  }
65 
69  protected function setUp() : void
70  {
71  vfs\vfsStream::setup();
72  $this->setTestDirectory(vfs\vfsStream::newDirectory('tests')->at(vfs\vfsStreamWrapper::getRoot()));
73  $this->setTestDirectoryUrl(vfs\vfsStream::url('root/tests'));
74 
75  parent::setUp();
76  }
77 
82  {
83  $this->assertException(ilUserException::class);
84  new ilUserPasswordManager(array('data_directory' => $this->getTestDirectoryUrl()));
85  }
86 
91  {
92  $this->assertException(ilUserException::class);
94  array(
95  'password_encoder' => 'md5',
96  'data_directory' => $this->getTestDirectoryUrl()
97  )
98  );
99  }
100 
105  {
106  $this->assertException(PHPUnit\Framework\Error\Error::class);
107  try {
109  array(
110  'password_encoder' => 'md5',
111  'encoder_factory' => 'test',
112  'data_directory' => $this->getTestDirectoryUrl()
113  )
114  );
115  } catch (TypeError $e) {
116  throw new PHPUnit\Framework\Error\Error($e->getMessage(), $e->getCode(), $e->getFile(), $e->getLine());
117  }
118  }
119 
124  public function testInstanceCanBeCreated() : void
125  {
126  $factory_mock = $this->getMockBuilder('ilUserPasswordEncoderFactory')->disableOriginalConstructor()->getMock();
127  $factory_mock->expects($this->exactly(2))->method('getSupportedEncoderNames')->will($this->onConsecutiveCalls(
128  array(
129  'mockencoder',
130  'second_mockencoder'
131  ),
132  array(
133  'mockencoder'
134  )
135  ));
136 
137  $password_manager = new ilUserPasswordManager(
138  array(
139  'password_encoder' => 'md5',
140  'encoder_factory' => $factory_mock,
141  'data_directory' => $this->getTestDirectoryUrl()
142  )
143  );
144  $this->assertInstanceOf('ilUserPasswordManager', $password_manager);
145  $this->assertEquals('md5', $password_manager->getEncoderName());
146  $this->assertEquals($factory_mock, $password_manager->getEncoderFactory());
147 
148  $this->assertTrue($password_manager->isEncodingTypeSupported('second_mockencoder'));
149  $this->assertFalse($password_manager->isEncodingTypeSupported('second_mockencoder'));
150  }
151 
157  {
158  $user_mock = $this->getMockBuilder('ilObjUser')->disableOriginalConstructor()->getMock();
159  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
160  $factory_mock = $this->getMockBuilder('ilUserPasswordEncoderFactory')->disableOriginalConstructor()->getMock();
161 
162  $user_mock->expects($this->once())->method('setPasswordSalt')->with($this->isType('string'));
163  $user_mock->expects($this->once())->method('getPasswordSalt')->will($this->returnValue('asuperrandomsalt'));
164  $user_mock->expects($this->once())->method('setPasswordEncodingType')->with($this->equalTo('mockencoder'));
165  $user_mock->expects($this->once())->method('setPasswd')->with(
166  $this->equalTo(self::ENCODED_PASSWORD),
167  $this->equalTo(IL_PASSWD_CRYPTED)
168  );
169 
170  $encoder->expects($this->once())->method('getName')->will($this->returnValue('mockencoder'));
171  $encoder->expects($this->once())->method('requiresSalt')->will($this->returnValue(true));
172  $encoder->expects($this->once())->method('encodePassword')
173  ->with(
174  $this->equalTo(self::PASSWORD),
175  $this->isType('string')
176  )->will($this->returnValue(self::ENCODED_PASSWORD));
177 
178  $factory_mock->expects($this->once())->method('getEncoderByName')->will($this->returnValue($encoder));
179 
180  $password_manager = new ilUserPasswordManager(
181  array(
182  'password_encoder' => 'mockencoder',
183  'encoder_factory' => $factory_mock,
184  'data_directory' => $this->getTestDirectoryUrl()
185  )
186  );
187 
188  $password_manager->encodePassword($user_mock, self::PASSWORD);
189  }
190 
196  {
197  $user_mock = $this->getMockBuilder('ilObjUser')->disableOriginalConstructor()->getMock();
198  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
199  $factory_mock = $this->getMockBuilder('ilUserPasswordEncoderFactory')->disableOriginalConstructor()->getMock();
200 
201  $user_mock->expects($this->once())->method('setPasswordSalt')->with($this->equalTo(null));
202  $user_mock->expects($this->once())->method('getPasswordSalt')->will($this->returnValue(null));
203  $user_mock->expects($this->once())->method('setPasswordEncodingType')->with($this->equalTo('mockencoder'));
204  $user_mock->expects($this->once())->method('setPasswd')->with(
205  $this->equalTo(self::ENCODED_PASSWORD),
206  $this->equalTo(IL_PASSWD_CRYPTED)
207  );
208 
209  $encoder->expects($this->once())->method('getName')->will($this->returnValue('mockencoder'));
210  $encoder->expects($this->once())->method('requiresSalt')->will($this->returnValue(false));
211  $encoder->expects($this->once())->method('encodePassword')->with(
212  $this->equalTo(self::PASSWORD),
213  $this->equalTo(null)
214  )->will($this->returnValue(self::ENCODED_PASSWORD));
215 
216  $factory_mock->expects($this->once())->method('getEncoderByName')->will($this->returnValue($encoder));
217 
218  $password_manager = new ilUserPasswordManager(
219  array(
220  'password_encoder' => 'mockencoder',
221  'encoder_factory' => $factory_mock,
222  'data_directory' => $this->getTestDirectoryUrl()
223  )
224  );
225 
226  $password_manager->encodePassword($user_mock, self::PASSWORD);
227  }
228 
233  public function testPasswordManagerVerifiesPassword() : void
234  {
235  $user_mock = $this->getMockBuilder('ilObjUser')->disableOriginalConstructor()->getMock();
236  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
237  $factory_mock = $this->getMockBuilder('ilUserPasswordEncoderFactory')->disableOriginalConstructor()->getMock();
238 
239  $user_mock->expects($this->atLeast(1))->method('getPasswordSalt')->will($this->returnValue('asuperrandomsalt'));
240  $user_mock->expects($this->atLeast(1))->method('getPasswordEncodingType')->will($this->returnValue('mockencoder'));
241  $user_mock->expects($this->atLeast(1))->method('getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
242  $user_mock->expects($this->never())->method('resetPassword');
243 
244  $encoder->expects($this->once())->method('getName')->will($this->returnValue('mockencoder'));
245  $encoder->expects($this->once())->method('isPasswordValid')->with(
246  $this->equalTo(self::ENCODED_PASSWORD),
247  $this->equalTo(self::PASSWORD),
248  $this->isType('string')
249  )->will($this->returnValue(true));
250  $encoder->expects($this->once())->method('requiresReencoding')
251  ->with($this->equalTo(self::ENCODED_PASSWORD))
252  ->will($this->returnValue(false));
253 
254  $factory_mock->expects($this->once())->method('getEncoderByName')->will($this->returnValue($encoder));
255 
256  $password_manager = new ilUserPasswordManager(
257  array(
258  'password_encoder' => 'mockencoder',
259  'encoder_factory' => $factory_mock,
260  'data_directory' => $this->getTestDirectoryUrl()
261  )
262  );
263 
264  $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
265  }
266 
272  {
273  $user_mock = $this->getMockBuilder('ilObjUser')->disableOriginalConstructor()->getMock();
274  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
275  $factory_mock = $this->getMockBuilder('ilUserPasswordEncoderFactory')->disableOriginalConstructor()->getMock();
276 
277  $user_mock->expects($this->once())->method('getPasswordSalt')->will($this->returnValue('asuperrandomsalt'));
278  $user_mock->expects($this->once())->method('getPasswordEncodingType')->will($this->returnValue('second_mockencoder'));
279  $user_mock->expects($this->once())->method('getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
280  $user_mock->expects($this->once())->method('resetPassword')->with(
281  $this->equalTo(self::PASSWORD),
282  $this->equalTo(self::PASSWORD)
283  );
284 
285  $encoder->expects($this->once())->method('getName')->will($this->returnValue('second_mockencoder'));
286  $encoder->expects($this->once())->method('isPasswordValid')->with(
287  $this->equalTo(self::ENCODED_PASSWORD),
288  $this->equalTo(self::PASSWORD),
289  $this->isType('string')
290  )->will($this->returnValue(true));
291  $encoder->expects($this->never())->method('requiresReencoding')
292  ->with($this->equalTo(self::ENCODED_PASSWORD))
293  ->will($this->returnValue(false));
294 
295  $factory_mock->expects($this->once())->method('getEncoderByName')->will($this->returnValue($encoder));
296 
297  $password_manager = new ilUserPasswordManager(
298  array(
299  'password_encoder' => 'mockencoder',
300  'encoder_factory' => $factory_mock,
301  'data_directory' => $this->getTestDirectoryUrl()
302  )
303  );
304 
305  $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
306  }
307 
313  {
314  $user_mock = $this->getMockBuilder('ilObjUser')->disableOriginalConstructor()->getMock();
315  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
316  $factory_mock = $this->getMockBuilder('ilUserPasswordEncoderFactory')->disableOriginalConstructor()->getMock();
317 
318  $user_mock->expects($this->once())->method('getPasswordSalt')->will($this->returnValue('asuperrandomsalt'));
319  $user_mock->expects($this->once())->method('getPasswordEncodingType')->will($this->returnValue('mockencoder'));
320  $user_mock->expects($this->exactly(2))->method('getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
321  $user_mock->expects($this->once())->method('resetPassword')->with(
322  $this->equalTo(self::PASSWORD),
323  $this->equalTo(self::PASSWORD)
324  );
325 
326  $encoder->expects($this->once())->method('getName')->will($this->returnValue('mockencoder'));
327  $encoder->expects($this->once())->method('isPasswordValid')->with(
328  $this->equalTo(self::ENCODED_PASSWORD),
329  $this->equalTo(self::PASSWORD),
330  $this->isType('string')
331  )->will($this->returnValue(true));
332  $encoder->expects($this->once())->method('requiresReencoding')
333  ->with($this->equalTo(self::ENCODED_PASSWORD))
334  ->will($this->returnValue(true));
335 
336  $factory_mock->expects($this->once())->method('getEncoderByName')->will($this->returnValue($encoder));
337 
338  $password_manager = new ilUserPasswordManager(
339  array(
340  'password_encoder' => 'mockencoder',
341  'encoder_factory' => $factory_mock,
342  'data_directory' => $this->getTestDirectoryUrl()
343  )
344  );
345 
346  $this->assertTrue($password_manager->verifyPassword($user_mock, self::PASSWORD));
347  }
348 
354  {
355  $user_mock = $this->getMockBuilder('ilObjUser')->disableOriginalConstructor()->getMock();
356  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
357  $factory_mock = $this->getMockBuilder('ilUserPasswordEncoderFactory')->disableOriginalConstructor()->getMock();
358 
359  $user_mock->expects($this->once())->method('getPasswordSalt')->will($this->returnValue('asuperrandomsalt'));
360  $user_mock->expects($this->once())->method('getPasswordEncodingType')->will($this->returnValue('second_mockencoder'));
361  $user_mock->expects($this->once())->method('getPasswd')->will($this->returnValue(self::ENCODED_PASSWORD));
362  $user_mock->expects($this->never())->method('resetPassword');
363 
364  $encoder->expects($this->once())->method('getName')->will($this->returnValue('second_mockencoder'));
365  $encoder->expects($this->never())->method('requiresReencoding');
366  $encoder->expects($this->once())->method('isPasswordValid')
367  ->with(
368  $this->equalTo(self::ENCODED_PASSWORD),
369  $this->equalTo(self::PASSWORD),
370  $this->isType('string')
371  )->will($this->returnValue(false));
372 
373  $factory_mock->expects($this->once())->method('getEncoderByName')->will($this->returnValue($encoder));
374 
375  $password_manager = new ilUserPasswordManager(
376  array(
377  'password_encoder' => 'mockencoder',
378  'encoder_factory' => $factory_mock,
379  'data_directory' => $this->getTestDirectoryUrl()
380  )
381  );
382 
383  $this->assertFalse($password_manager->verifyPassword($user_mock, self::PASSWORD));
384  }
385 
389  public function testFactoryCanBeCreated() : void
390  {
392  'data_directory' => $this->getTestDirectoryUrl()
393  ]);
394  $this->assertInstanceOf('ilUserPasswordEncoderFactory', $factory);
395  }
396 
403  {
405  'default_password_encoder' => 'md5',
406  'data_directory' => $this->getTestDirectoryUrl()
407  ));
408  $this->assertEquals('md5', $factory->getDefaultEncoder());
409 
410  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
411  $encoder->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('mockencoder'));
412 
413  $second_mockencoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
414  $second_mockencoder->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('second_mockencoder'));
415 
416  $factory->setEncoders(array($encoder, $second_mockencoder));
417  $this->assertCount(2, $factory->getEncoders());
418  $this->assertCount(2, $factory->getSupportedEncoderNames());
419  $this->assertCount(
420  0,
421  array_diff(array('mockencoder', 'second_mockencoder'), $factory->getSupportedEncoderNames())
422  );
423  $this->assertCount(
424  0,
425  array_diff($factory->getSupportedEncoderNames(), array('mockencoder', 'second_mockencoder'))
426  );
427  }
428 
434  {
435  $this->assertException(ilUserException::class);
437  'data_directory' => $this->getTestDirectoryUrl()
438  ));
439  $factory->setEncoders(array('phpunit'));
440  }
441 
447  {
448  $this->assertException(ilUserException::class);
450  'default_password_encoder' => 'md5',
451  'data_directory' => $this->getTestDirectoryUrl()
452  ));
453  $factory->getEncoderByName('phpunit');
454  }
455 
461  {
462  $this->assertException(ilUserException::class);
464  'data_directory' => $this->getTestDirectoryUrl()
465  ));
466  $factory->getEncoderByName('phpunit', true);
467  }
468 
474  {
475  $this->assertException(ilUserException::class);
477  'default_password_encoder' => 'phpunit',
478  'data_directory' => $this->getTestDirectoryUrl()
479  ));
480  $factory->getEncoderByName('phpunit', true);
481  }
482 
489  {
490  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
491  $encoder->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('mockencoder'));
492 
494  'default_password_encoder' => $encoder->getName(),
495  'data_directory' => $this->getTestDirectoryUrl()
496  ));
497  $factory->setEncoders(array($encoder));
498  $this->assertEquals($encoder, $factory->getEncoderByName('phpunit', true));
499  }
500 
507  {
508  $encoder = $this->getMockBuilder('ilBasePasswordEncoder')->disableOriginalConstructor()->getMock();
509  $encoder->expects($this->atLeastOnce())->method('getName')->will($this->returnValue('mockencoder'));
510 
512  'default_password_encoder' => $encoder->getName(),
513  'data_directory' => $this->getTestDirectoryUrl()
514  ));
515  $factory->setEncoders(array($encoder));
516  $this->assertEquals($encoder, $factory->getEncoderByName('mockencoder', true));
517  }
518 }
testPasswordManagerNeverMigratesPasswordOnFailedVerificationWithVariantEncoders()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutValidFactory()
testFactoryReturnsTheDefaultEncoderIfAnUnsupportedEncoderIsRequestedAndASupportedDefaultEncoderWasSpecifiedInFallbackMode()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderWasInjected()
testExceptionIsRaisedIfAnUnsupportedEncoderIsRequestedFromFactory()
assertException($exception_class)
const IL_PASSWD_CRYPTED
setTestDirectoryUrl(string $testDirectoryUrl)
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutEncoderInformation()
setTestDirectory(vfs\vfsStreamDirectory $testDirectory)
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndNoDefaultEncoderWasSpecifiedInFallbackMode()
testFactoryRaisesAnExceptionIfAnUnsupportedEncoderIsRequestedAndTheDefaultEncoderDoesNotMatchOneOfTheSupportedEncodersInFallbackMode()
testPasswordManagerMigratesPasswordOnVerificationWithVariantEncoders()
testExceptionIsRaisedIfPasswordManagerIsCreatedWithoutFactory()
$factory
Definition: metadata.php:58