ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
ilBcryptPasswordEncoderTest.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2014 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once 'Services/Password/classes/encoders/class.ilBcryptPasswordEncoder.php';
5 
12 {
16  const VALID_COSTS = '08';
17 
21  const PASSWORD = 'password';
22 
26  const WRONG_PASSWORD = 'wrong_password';
27 
31  const CLIENT_SALT = 'homer!12345_/';
32 
36  const PASSWORD_SALT = 'salt';
37 
41  protected $test_directory;
42 
46  public function getTestDirectory()
47  {
48  return $this->test_directory;
49  }
50 
55  {
56  $this->test_directory = $test_directory;
57  }
58 
62  private function isVsfStreamInstalled()
63  {
64  return @include_once('vfsStream.php');
65  }
66 
70  protected function setUp()
71  {
72  if($this->isVsfStreamInstalled())
73  {
74  vfsStream::setup();
75  $this->setTestDirectory(vfsStream::newDirectory('tests')->at(vfsStreamWrapper::getRoot()));
76  define('CLIENT_DATA_DIR', vfsStream::url('root/tests'));
77  }
78  parent::setUp();
79  }
80 
84  public function testInstanceCanBeCreated()
85  {
86  $security_flaw_ignoring_encoder = new ilBcryptPasswordEncoder(array(
87  'ignore_security_flaw' => true
88  ));
89  $this->assertTrue($security_flaw_ignoring_encoder->isSecurityFlawIgnored());
90 
91  $security_flaw_respecting_encoder = new ilBcryptPasswordEncoder(array(
92  'ignore_security_flaw' => false
93  ));
94  $this->assertFalse($security_flaw_respecting_encoder->isSecurityFlawIgnored());
95 
96  $encoder = new ilBcryptPasswordEncoder(array(
97  'cost' => self::VALID_COSTS
98  ));
99  $this->assertInstanceOf('ilBcryptPasswordEncoder', $encoder);
100  $this->assertEquals(self::VALID_COSTS, $encoder->getCosts());
101  $this->assertFalse($encoder->isSecurityFlawIgnored());
102  $encoder->setClientSalt(self::CLIENT_SALT);
103  return $encoder;
104  }
105 
110  {
111  $encoder->setCosts(4);
112  $this->assertEquals(4, $encoder->getCosts());
113  }
114 
120  {
121  $encoder->setCosts(32);
122  }
123 
129  {
130  $encoder->setCosts(3);
131  }
132 
137  public function testCostsCanBeSetInRange($costs, ilBcryptPasswordEncoder $encoder)
138  {
139  $encoder->setCosts($costs);
140  }
141 
145  public function costsProvider()
146  {
147  $data = array();
148  for($i = 4; $i <= 31; $i++)
149  {
150  $data[] = array($i);
151  }
152  return $data;
153  }
154 
159  {
160  $encoder->setCosts(self::VALID_COSTS);
161  $encoded_password = $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
162  $this->assertTrue($encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
163  $this->assertFalse($encoder->isPasswordValid($encoded_password, self::WRONG_PASSWORD, self::PASSWORD_SALT));
164  return $encoder;
165  }
166 
172  {
173  $encoder->setCosts(self::VALID_COSTS);
174  $encoder->encodePassword(str_repeat('a', 5000), self::PASSWORD_SALT);
175  }
176 
181  {
182  $encoder->setCosts(self::VALID_COSTS);
183  $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), self::PASSWORD_SALT));
184  }
185 
190  {
191  $encoder = new ilBcryptPasswordEncoder();
192  $encoder->setClientSalt(null);
193  $encoder->setCosts(self::VALID_COSTS);
194  $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
195  }
196 
201  {
202  $encoder = new ilBcryptPasswordEncoder();
203  $encoder->setClientSalt(null);
204  $encoder->setCosts(self::VALID_COSTS);
205  $encoder->isPasswordValid('12121212', self::PASSWORD, self::PASSWORD_SALT);
206  }
207 
212  {
214 
215  $encoder = new ilBcryptPasswordEncoder();
216  $this->assertNull($encoder->getClientSalt());
217 
218  try
219  {
220  $this->getTestDirectory()->chmod(0000);
221  $encoder->onSelection();
222  $this->fail('An expected exception has not been raised.');
223  }
224  catch(Exception $e)
225  {
226  $this->assertNull($encoder->getClientSalt());
227  $this->assertFileNotExists(vfsStream::url('root/tests/' . ilBcryptPasswordEncoder::SALT_STORAGE_FILENAME));
228  }
229  }
230 
235  {
237 
238  $this->getTestDirectory()->chmod(0777);
239 
240  $encoder = new ilBcryptPasswordEncoder();
241  $this->assertNull($encoder->getClientSalt());
242 
243  $encoder->onSelection();
244 
245  $this->assertNotNull($encoder->getClientSalt());
246  $this->assertFileExists(vfsStream::url('root/tests/' . ilBcryptPasswordEncoder::SALT_STORAGE_FILENAME));
247  }
248 
253  {
255 
256  $this->getTestDirectory()->chmod(0777);
257  vfsStream::newFile(ilBcryptPasswordEncoder::SALT_STORAGE_FILENAME)->withContent(self::CLIENT_SALT)->at($this->getTestDirectory());
258 
259  $encoder = new ilBcryptPasswordEncoder();
260  $this->assertEquals(self::CLIENT_SALT, $encoder->getClientSalt());
261  }
262 
267  {
268  $encoder = new ilBcryptPasswordEncoder();
269  $encoder->setBackwardCompatibility(true);
270  $this->assertTrue($encoder->isBackwardCompatibilityEnabled());
271  $encoder->setBackwardCompatibility(false);
272  $this->assertFalse($encoder->isBackwardCompatibilityEnabled());
273  }
274 
278  public function testBackwardCompatibility()
279  {
281 
282  $encoder = new ilBcryptPasswordEncoder();
283  $encoder->setClientSalt(self::CLIENT_SALT);
284  $encoder->setBackwardCompatibility(true);
285  $encoded_password = $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
286  $this->assertTrue($encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
287  $this->assertEquals('$2a$', substr($encoded_password, 0, 4));
288 
289  $another_encoder = new ilBcryptPasswordEncoder();
290  $another_encoder->setClientSalt(self::CLIENT_SALT);
291  $another_encoder->setBackwardCompatibility(false);
292  $another_encoded_password = $another_encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
293  $this->assertEquals('$2y$', substr($another_encoded_password, 0, 4));
294  $this->assertTrue($another_encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
295  }
296 
301  {
302  if(version_compare(phpversion(), '5.3.7', '<'))
303  {
304  $this->markTestSkipped('Requires PHP >= 5.3.7');
305  }
306  }
307 
311  private function skipIfvfsStreamNotSupported()
312  {
313  if(!$this->isVsfStreamInstalled())
314  {
315  $this->markTestSkipped('Requires vfsStream (http://vfs.bovigo.org)');
316  }
317  }
318 
323  {
324  $encoder = new ilBcryptPasswordEncoder();
325  $encoder->setClientSalt(self::CLIENT_SALT);
326  $encoder->setBackwardCompatibility(true);
327  $encoder->encodePassword(self::PASSWORD . chr(195), self::PASSWORD_SALT);
328  }
329 
334  {
335  $encoder = new ilBcryptPasswordEncoder();
336  $encoder->setClientSalt(self::CLIENT_SALT);
337  $encoder->setBackwardCompatibility(true);
338  $encoder->setIsSecurityFlawIgnored(true);
339  $encoder->encodePassword(self::PASSWORD . chr(195), self::PASSWORD_SALT);
340  }
341 
345  public function testNameShouldBeBcrypt()
346  {
347  $encoder = new ilBcryptPasswordEncoder();
348  $this->assertEquals('bcrypt', $encoder->getName());
349  }
350 }