From c454c87f75c179043a956071a8572af538c926a9 Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 02:03:55 +0100 Subject: [PATCH 1/8] Update DatabaseTokenRepository.php --- .../Passwords/DatabaseTokenRepository.php | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php index 2bffaa9c3470..7e4adcb56a9b 100755 --- a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php +++ b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php @@ -5,6 +5,7 @@ use Carbon\Carbon; use Illuminate\Support\Str; use Illuminate\Database\ConnectionInterface; +use Illuminate\Contracts\Hashing\Hasher as HasherContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; class DatabaseTokenRepository implements TokenRepositoryInterface @@ -36,7 +37,14 @@ class DatabaseTokenRepository implements TokenRepositoryInterface * @var int */ protected $expires; - + + /** + * The hasher implementation. + * + * @var \Illuminate\Contracts\Hashing\Hasher + */ + protected $hasher; + /** * Create a new token repository instance. * @@ -46,12 +54,13 @@ class DatabaseTokenRepository implements TokenRepositoryInterface * @param int $expires * @return void */ - public function __construct(ConnectionInterface $connection, $table, $hashKey, $expires = 60) + public function __construct(ConnectionInterface $connection, HasherContract $hasher, $table, $hashKey, $expires = 60) { $this->table = $table; $this->hashKey = $hashKey; $this->expires = $expires * 60; $this->connection = $connection; + $this->hasher = $hasher; } /** @@ -96,7 +105,7 @@ protected function deleteExisting(CanResetPasswordContract $user) */ protected function getPayload($email, $token) { - return ['email' => $email, 'token' => $token, 'created_at' => new Carbon]; + return ['email' => $email, 'token' => $this->hasher->make($token), 'created_at' => new Carbon]; } /** @@ -106,13 +115,13 @@ protected function getPayload($email, $token) * @param string $token * @return bool */ - public function exists(CanResetPasswordContract $user, $token) + public function exists(CanResetPasswordContract $user, $userToken) { $email = $user->getEmailForPasswordReset(); - $token = (array) $this->getTable()->where('email', $email)->where('token', $token)->first(); + $token = (array) $this->getTable()->where('email', $email)->first(); - return $token && ! $this->tokenExpired($token); + return $token && ! $this->tokenExpired($token) && $this->hasher->check($userToken, $token['token']); } /** From b4e45e0bc92e8ae57bf6bbe3cbe1ceb637cffdb6 Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 02:05:14 +0100 Subject: [PATCH 2/8] Update AuthDatabaseTokenRepositoryTest.php --- tests/Auth/AuthDatabaseTokenRepositoryTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/Auth/AuthDatabaseTokenRepositoryTest.php b/tests/Auth/AuthDatabaseTokenRepositoryTest.php index 2a6aa283e7ec..58f39fe84849 100755 --- a/tests/Auth/AuthDatabaseTokenRepositoryTest.php +++ b/tests/Auth/AuthDatabaseTokenRepositoryTest.php @@ -88,6 +88,9 @@ public function testDeleteExpiredMethodDeletesExpiredTokens() protected function getRepo() { - return new Illuminate\Auth\Passwords\DatabaseTokenRepository(m::mock('Illuminate\Database\Connection'), 'table', 'key'); + return new Illuminate\Auth\Passwords\DatabaseTokenRepository( + m::mock('Illuminate\Database\Connection'), + m::mock('Illuminate\Contracts\Hashing\Hasher'), + 'table', 'key'); } } From babaca52349cd9153f9bc3b1a9751f3dc5648741 Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 02:05:49 +0100 Subject: [PATCH 3/8] Update PasswordBrokerManager.php --- src/Illuminate/Auth/Passwords/PasswordBrokerManager.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php b/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php index f2bb498004f3..0f3f26283bfc 100644 --- a/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php +++ b/src/Illuminate/Auth/Passwords/PasswordBrokerManager.php @@ -91,6 +91,7 @@ protected function createTokenRepository(array $config) return new DatabaseTokenRepository( $this->app['db']->connection($connection), + $this->app['hash'], $config['table'], $key, $config['expire'] From ee893b142b5a61bb8ff2d79b0f2870fe3528f14d Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 03:03:14 +0100 Subject: [PATCH 4/8] Should fix the Travis complaint.. --- tests/Auth/AuthDatabaseTokenRepositoryTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Auth/AuthDatabaseTokenRepositoryTest.php b/tests/Auth/AuthDatabaseTokenRepositoryTest.php index 58f39fe84849..bfd869726010 100755 --- a/tests/Auth/AuthDatabaseTokenRepositoryTest.php +++ b/tests/Auth/AuthDatabaseTokenRepositoryTest.php @@ -55,11 +55,12 @@ public function testExistReturnsFalseIfRecordIsExpired() public function testExistReturnsTrueIfValidRecordExists() { $repo = $this->getRepo(); + $hasher = m::mock('Illuminate\Contracts\Hashing\Hasher'); + $tokenHash = $hasher->make('token'); $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock('StdClass')); $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query); - $query->shouldReceive('where')->once()->with('token', 'token')->andReturn($query); $date = date('Y-m-d H:i:s', time() - 600); - $query->shouldReceive('first')->andReturn((object) ['created_at' => $date]); + $query->shouldReceive('first')->andReturn((object) ['created_at' => $date, 'token' => $tokenHash]); $user = m::mock('Illuminate\Contracts\Auth\CanResetPassword'); $user->shouldReceive('getEmailForPasswordReset')->andReturn('email'); From ab88c6edf848b89bed6a4a3ec13dea2bb791697d Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 03:05:25 +0100 Subject: [PATCH 5/8] Should take some of the StyleCI complaints away... --- src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php index 7e4adcb56a9b..afe8b856dc1c 100755 --- a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php +++ b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php @@ -37,14 +37,14 @@ class DatabaseTokenRepository implements TokenRepositoryInterface * @var int */ protected $expires; - + /** * The hasher implementation. * * @var \Illuminate\Contracts\Hashing\Hasher */ protected $hasher; - + /** * Create a new token repository instance. * From 1da9577f9e38ee5cdeeea1ffe750dbd295b08f9a Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 03:05:56 +0100 Subject: [PATCH 6/8] StyleCI fixes. --- tests/Auth/AuthDatabaseTokenRepositoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Auth/AuthDatabaseTokenRepositoryTest.php b/tests/Auth/AuthDatabaseTokenRepositoryTest.php index bfd869726010..17e90bfeb80b 100755 --- a/tests/Auth/AuthDatabaseTokenRepositoryTest.php +++ b/tests/Auth/AuthDatabaseTokenRepositoryTest.php @@ -90,7 +90,7 @@ public function testDeleteExpiredMethodDeletesExpiredTokens() protected function getRepo() { return new Illuminate\Auth\Passwords\DatabaseTokenRepository( - m::mock('Illuminate\Database\Connection'), + m::mock('Illuminate\Database\Connection'), m::mock('Illuminate\Contracts\Hashing\Hasher'), 'table', 'key'); } From e50c5243efa1f53aad7366f497b5e42235c86ec9 Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 10:42:09 +0100 Subject: [PATCH 7/8] Fixed up unit tests by mocking the hash object and added a test to check that invalid hashes fail --- .../Passwords/DatabaseTokenRepository.php | 10 ++++++++ .../Auth/AuthDatabaseTokenRepositoryTest.php | 25 ++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php index afe8b856dc1c..25d6a03e38e0 100755 --- a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php +++ b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php @@ -189,4 +189,14 @@ public function getConnection() { return $this->connection; } + + /** + * Get the hasher instance. + * + * @return \Illuminate\Contracts\Hashing\Hasher + */ + public function getHasher() + { + return $this->hasher; + } } diff --git a/tests/Auth/AuthDatabaseTokenRepositoryTest.php b/tests/Auth/AuthDatabaseTokenRepositoryTest.php index 17e90bfeb80b..ac471e991c65 100755 --- a/tests/Auth/AuthDatabaseTokenRepositoryTest.php +++ b/tests/Auth/AuthDatabaseTokenRepositoryTest.php @@ -12,6 +12,7 @@ public function tearDown() public function testCreateInsertsNewRecordIntoTable() { $repo = $this->getRepo(); + $repo->getHasher()->shouldReceive('make')->andReturn('hashed-token'); $repo->getConnection()->shouldReceive('table')->with('table')->andReturn($query = m::mock('StdClass')); $query->shouldReceive('where')->with('email', 'email')->andReturn($query); $query->shouldReceive('delete')->once(); @@ -30,7 +31,6 @@ public function testExistReturnsFalseIfNoRowFoundForUser() $repo = $this->getRepo(); $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock('StdClass')); $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query); - $query->shouldReceive('where')->once()->with('token', 'token')->andReturn($query); $query->shouldReceive('first')->andReturn(null); $user = m::mock('Illuminate\Contracts\Auth\CanResetPassword'); $user->shouldReceive('getEmailForPasswordReset')->andReturn('email'); @@ -41,11 +41,11 @@ public function testExistReturnsFalseIfNoRowFoundForUser() public function testExistReturnsFalseIfRecordIsExpired() { $repo = $this->getRepo(); + $repo->getHasher()->shouldReceive('check')->with('token', 'hashed-token')->andReturn(true); $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock('StdClass')); $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query); - $query->shouldReceive('where')->once()->with('token', 'token')->andReturn($query); $date = date('Y-m-d H:i:s', time() - 300000); - $query->shouldReceive('first')->andReturn((object) ['created_at' => $date]); + $query->shouldReceive('first')->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']); $user = m::mock('Illuminate\Contracts\Auth\CanResetPassword'); $user->shouldReceive('getEmailForPasswordReset')->andReturn('email'); @@ -55,18 +55,31 @@ public function testExistReturnsFalseIfRecordIsExpired() public function testExistReturnsTrueIfValidRecordExists() { $repo = $this->getRepo(); - $hasher = m::mock('Illuminate\Contracts\Hashing\Hasher'); - $tokenHash = $hasher->make('token'); + $repo->getHasher()->shouldReceive('check')->with('token', 'hashed-token')->andReturn(true); $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock('StdClass')); $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query); $date = date('Y-m-d H:i:s', time() - 600); - $query->shouldReceive('first')->andReturn((object) ['created_at' => $date, 'token' => $tokenHash]); + $query->shouldReceive('first')->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']); $user = m::mock('Illuminate\Contracts\Auth\CanResetPassword'); $user->shouldReceive('getEmailForPasswordReset')->andReturn('email'); $this->assertTrue($repo->exists($user, 'token')); } + public function testExistReturnsFalseIfInvalidToken() + { + $repo = $this->getRepo(); + $repo->getHasher()->shouldReceive('check')->with('wrong-token', 'hashed-token')->andReturn(false); + $repo->getConnection()->shouldReceive('table')->once()->with('table')->andReturn($query = m::mock('StdClass')); + $query->shouldReceive('where')->once()->with('email', 'email')->andReturn($query); + $date = date('Y-m-d H:i:s', time() - 600); + $query->shouldReceive('first')->andReturn((object) ['created_at' => $date, 'token' => 'hashed-token']); + $user = m::mock('Illuminate\Contracts\Auth\CanResetPassword'); + $user->shouldReceive('getEmailForPasswordReset')->andReturn('email'); + + $this->assertFalse($repo->exists($user, 'wrong-token')); + } + public function testDeleteMethodDeletesByToken() { $repo = $this->getRepo(); From b35d3b57d987e33d66a72a2343fe2aa547d373c8 Mon Sep 17 00:00:00 2001 From: Henrik Sylvester Pedersen Date: Sun, 18 Dec 2016 10:43:18 +0100 Subject: [PATCH 8/8] Fixed styleCI issue once more... --- src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php index 25d6a03e38e0..7ad0d0fcee9e 100755 --- a/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php +++ b/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php @@ -193,7 +193,7 @@ public function getConnection() /** * Get the hasher instance. * - * @return \Illuminate\Contracts\Hashing\Hasher + * @return \Illuminate\Contracts\Hashing\Hasher */ public function getHasher() {