Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Hash::needsRehash in HasAttributes::castAttributeAsHashedString instead of Hash::isHashed #1

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Illuminate/Contracts/Hashing/Hasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ public function check($value, $hashedValue, array $options = []);
* @return bool
*/
public function needsRehash($hashedValue, array $options = []);

/**
* Check if the given hash is acceptable for the hasher.
*
* @param string $hashedValue
* @return bool
*/
public function isAcceptable($hashedValue);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ public static function encryptUsing($encrypter)
*/
protected function castAttributeAsHashedString($key, $value)
{
return $value !== null && ! Hash::isHashed($value) ? Hash::make($value) : $value;
return $value !== null && ! Hash::isAcceptable($value) ? Hash::make($value) : $value;
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/Illuminate/Hashing/AbstractHasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,15 @@ public function check($value, $hashedValue, array $options = [])

return password_verify($value, $hashedValue);
}

/**
* Check if the given hash is acceptable for the hasher.
*
* @param string $hashedValue
* @return bool
*/
public function isAcceptable($hashedValue)
{
return method_exists($this, 'needsRehash') && ! $this->needsRehash($hashedValue);
}
}
15 changes: 15 additions & 0 deletions src/Illuminate/Hashing/ArgonHasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ public function setTime(int $time)
return $this;
}

/**
* Check if the given hash is acceptable for the hasher.
*
* @param string $hashedValue
* @return bool
*/
public function isAcceptable($hashedValue)
{
$info = $this->info($hashedValue);

return $info['algoName'] === $this->algorithm()
&& $info['options']['memory_cost'] / $info['options']['threads'] <= 4 * 65536
&& $info['options']['threads'] <= 16;
}

/**
* Set the default password threads factor.
*
Expand Down
13 changes: 13 additions & 0 deletions src/Illuminate/Hashing/BcryptHasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ public function needsRehash($hashedValue, array $options = [])
]);
}

/**
* Check if the given hash is acceptable for the hasher.
*
* @param string $hashedValue
* @return bool
*/
public function isAcceptable($hashedValue)
{
$info = $this->info($hashedValue);

return $info['algoName'] === 'bcrypt' && $info['options']['cost'] <= 16;
}

/**
* Set the default password work factor.
*
Expand Down
11 changes: 11 additions & 0 deletions src/Illuminate/Hashing/HashManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ public function needsRehash($hashedValue, array $options = [])
return $this->driver()->needsRehash($hashedValue, $options);
}

/**
* Check if the given hash is acceptable for the hasher.
*
* @param string $hashedValue
* @return bool
*/
public function isAcceptable($hashedValue)
{
return $this->driver()->isAcceptable($hashedValue);
}

/**
* Determine if a given string is already hashed.
*
Expand Down
1 change: 1 addition & 0 deletions src/Illuminate/Support/Facades/Hash.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* @method static string make(string $value, array $options = [])
* @method static bool check(string $value, string $hashedValue, array $options = [])
* @method static bool needsRehash(string $hashedValue, array $options = [])
* @method static bool isAcceptable(string $hashedValue)
* @method static bool isHashed(string $value)
* @method static string getDefaultDriver()
* @method static mixed driver(string|null $driver = null)
Expand Down
16 changes: 16 additions & 0 deletions tests/Hashing/HasherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public function testBasicBcryptHashing()
$this->assertSame('bcrypt', password_get_info($value)['algoName']);
$this->assertGreaterThanOrEqual(12, password_get_info($value)['options']['cost']);
$this->assertTrue($this->hashManager->isHashed($value));
$this->assertTrue($hasher->isAcceptable($value));
$this->assertFalse($hasher->isAcceptable('password'));
$this->assertFalse($hasher->isAcceptable('$2y$17$1iPpw8cxiw6.ijzD2Ry1mOvBMM2kPu6wayaIXWLMG5fhFX5ejCEa6'));
$this->assertFalse($hasher->isAcceptable('$argon2i$v=19$m=65536,t=4,p=1$eE4vbkhJTm54M0k4OU1LTw$C9JCrLeNkNHI1jWx3pBqpK2bTgFrtcVcIfARjCN0218'));
}

public function testBasicArgon2iHashing()
Expand All @@ -68,6 +72,12 @@ public function testBasicArgon2iHashing()
$this->assertTrue($hasher->needsRehash($value, ['threads' => 1]));
$this->assertSame('argon2i', password_get_info($value)['algoName']);
$this->assertTrue($this->hashManager->isHashed($value));
$this->assertTrue($hasher->isAcceptable($value));
$this->assertTrue($hasher->isAcceptable('$argon2i$v=19$m=4194304,t=4,p=16$c01ieWxxZWozSmtHTzd5Vw$y9hJhd9Ip28ZFbh4BEVpPYSA6n017UIBdPcuTVna4hw'));
$this->assertFalse($hasher->isAcceptable('password'));
$this->assertFalse($hasher->isAcceptable('$argon2i$v=19$m=4194304,t=4,p=8$Ri5lRGt5VFMvMEtiLkYxQg$sPuFc8V0SKB1gmOJXmqcXscTZ8Awdkihf7m0Y/bskSg'));
$this->assertFalse($hasher->isAcceptable('$argon2i$v=19$m=8388608,t=4,p=32$Z0JUVVFTMTBVRnZlRHhldQ$sQrSwO1zcTFOseS56GZOd27SR9c05YUXPK7Np+gJpv4'));
$this->assertFalse($hasher->isAcceptable('$2y$10$PCXl4nmz2z8vckcBFi2AQObDvYOIlNa99REfp0dQN/Hq7Lc1wA5qC'));
}

public function testBasicArgon2idHashing()
Expand All @@ -80,6 +90,12 @@ public function testBasicArgon2idHashing()
$this->assertTrue($hasher->needsRehash($value, ['threads' => 1]));
$this->assertSame('argon2id', password_get_info($value)['algoName']);
$this->assertTrue($this->hashManager->isHashed($value));
$this->assertTrue($hasher->isAcceptable($value));
$this->assertTrue($hasher->isAcceptable('$argon2id$v=19$m=4194304,t=4,p=16$WmJySGpROWJuMUJxZXQ5Rw$u96pRIoI4xsj+OfFoluc+iEng3jkDfuTFDIJOYbRml0'));
$this->assertFalse($hasher->isAcceptable('password'));
$this->assertFalse($hasher->isAcceptable('$argon2id$v=19$m=4194304,t=4,p=8$VmZWVE5Uc2xDbklQVlhBWA$59KcqVqTfDt4WjoFIQkFIuXQEZBuRN7+G/YR7BDb9i8'));
$this->assertFalse($hasher->isAcceptable('$argon2id$v=19$m=8388608,t=4,p=32$dVFMcDB4WWkvRU41bGtDMQ$q4Y/26s5RVLn3tInzMgh/jUKeoOj/BXINARKQsvvhC4'));
$this->assertFalse($hasher->isAcceptable('$2y$10$PCXl4nmz2z8vckcBFi2AQObDvYOIlNa99REfp0dQN/Hq7Lc1wA5qC'));
}

/**
Expand Down
6 changes: 3 additions & 3 deletions tests/Integration/Database/EloquentModelHashedCastingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected function defineDatabaseMigrationsAfterDatabaseRefreshed()

public function testHashed()
{
$this->hasher->expects('isHashed')
$this->hasher->expects('isAcceptable')
->with('this is a password')
->andReturnFalse();

Expand All @@ -49,9 +49,9 @@ public function testHashed()
]);
}

public function testNotHashedIfAlreadyHashed()
public function testNotHashedIfAlreadyCorrectlyHashed()
{
$this->hasher->expects('isHashed')
$this->hasher->expects('isAcceptable')
->with('already-hashed-password')
->andReturnTrue();

Expand Down