diff --git a/src/Illuminate/Auth/DatabaseUserProvider.php b/src/Illuminate/Auth/DatabaseUserProvider.php index 8aa563d82023..111e5522563a 100755 --- a/src/Illuminate/Auth/DatabaseUserProvider.php +++ b/src/Illuminate/Auth/DatabaseUserProvider.php @@ -2,6 +2,7 @@ namespace Illuminate\Auth; +use Closure; use Illuminate\Contracts\Auth\Authenticatable as UserContract; use Illuminate\Contracts\Auth\UserProvider; use Illuminate\Contracts\Hashing\Hasher as HasherContract; @@ -117,6 +118,8 @@ public function retrieveByCredentials(array $credentials) if (is_array($value) || $value instanceof Arrayable) { $query->whereIn($key, $value); + } elseif ($value instanceof Closure) { + $value($query); } else { $query->where($key, $value); } diff --git a/src/Illuminate/Auth/EloquentUserProvider.php b/src/Illuminate/Auth/EloquentUserProvider.php index f175298ce07a..54dff6b87f2c 100755 --- a/src/Illuminate/Auth/EloquentUserProvider.php +++ b/src/Illuminate/Auth/EloquentUserProvider.php @@ -2,6 +2,7 @@ namespace Illuminate\Auth; +use Closure; use Illuminate\Contracts\Auth\Authenticatable as UserContract; use Illuminate\Contracts\Auth\UserProvider; use Illuminate\Contracts\Hashing\Hasher as HasherContract; @@ -123,6 +124,8 @@ public function retrieveByCredentials(array $credentials) if (is_array($value) || $value instanceof Arrayable) { $query->whereIn($key, $value); + } elseif ($value instanceof Closure) { + $value($query); } else { $query->where($key, $value); } diff --git a/tests/Auth/AuthDatabaseUserProviderTest.php b/tests/Auth/AuthDatabaseUserProviderTest.php index e75cef6d6197..fd6b5be98305 100755 --- a/tests/Auth/AuthDatabaseUserProviderTest.php +++ b/tests/Auth/AuthDatabaseUserProviderTest.php @@ -102,6 +102,26 @@ public function testRetrieveByCredentialsReturnsUserWhenUserIsFound() $this->assertSame('taylor', $user->name); } + public function testRetrieveByCredentialsAcceptsCallback() + { + $conn = m::mock(Connection::class); + $conn->shouldReceive('table')->once()->with('foo')->andReturn($conn); + $conn->shouldReceive('where')->once()->with('username', 'dayle'); + $conn->shouldReceive('whereIn')->once()->with('group', ['one', 'two']); + $conn->shouldReceive('first')->once()->andReturn(['id' => 1, 'name' => 'taylor']); + $hasher = m::mock(Hasher::class); + $provider = new DatabaseUserProvider($conn, $hasher, 'foo'); + + $user = $provider->retrieveByCredentials([function ($builder) { + $builder->where('username', 'dayle'); + $builder->whereIn('group', ['one', 'two']); + }]); + + $this->assertInstanceOf(GenericUser::class, $user); + $this->assertSame(1, $user->getAuthIdentifier()); + $this->assertSame('taylor', $user->name); + } + public function testRetrieveByCredentialsReturnsNullWhenUserIsFound() { $conn = m::mock(Connection::class); diff --git a/tests/Auth/AuthEloquentUserProviderTest.php b/tests/Auth/AuthEloquentUserProviderTest.php index ca9a08029b0e..ae34a1b4a074 100755 --- a/tests/Auth/AuthEloquentUserProviderTest.php +++ b/tests/Auth/AuthEloquentUserProviderTest.php @@ -100,6 +100,23 @@ public function testRetrieveByCredentialsReturnsUser() $this->assertSame('bar', $user); } + public function testRetrieveByCredentialsAcceptsCallback() + { + $provider = $this->getProviderMock(); + $mock = m::mock(stdClass::class); + $mock->shouldReceive('newQuery')->once()->andReturn($mock); + $mock->shouldReceive('where')->once()->with('username', 'dayle'); + $mock->shouldReceive('whereIn')->once()->with('group', ['one', 'two']); + $mock->shouldReceive('first')->once()->andReturn('bar'); + $provider->expects($this->once())->method('createModel')->willReturn($mock); + $user = $provider->retrieveByCredentials([function ($builder) { + $builder->where('username', 'dayle'); + $builder->whereIn('group', ['one', 'two']); + }]); + + $this->assertSame('bar', $user); + } + public function testCredentialValidation() { $hasher = m::mock(Hasher::class);