Skip to content

Commit

Permalink
Merge branch '5.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamCampbell committed Sep 23, 2017
2 parents 91212df + 4d34ac3 commit 7619e4f
Show file tree
Hide file tree
Showing 16 changed files with 205 additions and 15 deletions.
33 changes: 33 additions & 0 deletions CHANGELOG-5.5.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# Release Notes for 5.5.x

## v5.5.12 (2017-09-22)

### Added
- Added "software" as an uncountable word ([#21324](https://github.com/laravel/framework/pull/21324))

### Fixed
- Don't compare remember token if it's `null` ([#21328](https://github.com/laravel/framework/pull/21328))


## v5.5.11 (2017-09-21)

### Fixed
- Fixed bug in `EloquentUserProvider` introduced in [#21320](https://github.com/laravel/framework/pull/21320) ([#21323](https://github.com/laravel/framework/pull/21323))


## v5.5.10 (2017-09-21)

### Added
- Added `Route::respondWithRoute($name)` method ([#21299](https://github.com/laravel/framework/pull/21299), [66c5e46](https://github.com/laravel/framework/commit/66c5e462dbdb9d0c9d23114da3a3dc1b6e9fa0a1))
- Added `$strict` parameter to `TestResponse::assertJson()` ([#21301](https://github.com/laravel/framework/pull/21301))

### Changed
- Added "firmware" as an uncountable word ([#21306](https://github.com/laravel/framework/pull/21306))
- Allow `MorphTo::associate()` accept `null` ([#21318](https://github.com/laravel/framework/pull/21318))
- Changed `__()` signature to match `Translation::trans()` ([10c013c](https://github.com/laravel/framework/commit/10c013c564b7e518640e42e97d9178f9e05ec7d9))

### Fixed
- Add missing `driver` parameter to doctrine connection ([#21297](https://github.com/laravel/framework/pull/21297))

### Security
- Perform constant-time token comparison in `DatabaseUserProvider` ([#21320](https://github.com/laravel/framework/pull/21320))


## v5.5.9 (2017-09-20)

### Changed
Expand Down
10 changes: 5 additions & 5 deletions src/Illuminate/Auth/DatabaseUserProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ public function retrieveById($identifier)
*/
public function retrieveByToken($identifier, $token)
{
$user = $this->conn->table($this->table)
->where('id', $identifier)
->where('remember_token', $token)
->first();
$user = $this->conn->table($this->table)->find($identifier);

return $this->getGenericUser($user);
$rememberToken = $user->remember_token;

return $user && $rememberToken && hash_equals($rememberToken, $token)
? $this->getGenericUser($user) : null;
}

/**
Expand Down
9 changes: 5 additions & 4 deletions src/Illuminate/Auth/EloquentUserProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ public function retrieveByToken($identifier, $token)
{
$model = $this->createModel();

return $model->newQuery()
->where($model->getAuthIdentifierName(), $identifier)
->where($model->getRememberTokenName(), $token)
->first();
$model = $model->where($model->getAuthIdentifierName(), $identifier)->first();

$rememberToken = $model->getRememberToken();

return $model && $rememberToken && hash_equals($rememberToken, $token) ? $model : null;
}

/**
Expand Down
12 changes: 12 additions & 0 deletions src/Illuminate/Database/Eloquent/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,18 @@ public function flip()
return $this->toBase()->flip();
}

/**
* Pad collection to the specified length with a value.
*
* @param int $size
* @param mixed $value
* @return \Illuminate\Support\Collection
*/
public function pad($size, $value)
{
return $this->toBase()->pad($size, $value);
}

/**
* Get the type of the entities being queued.
*
Expand Down
6 changes: 6 additions & 0 deletions src/Illuminate/Foundation/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,12 @@ protected function whoopsHandler()

$handler->handleUnconditionally(true);

foreach (config('app.debug_blacklist', []) as $key => $secrets) {
foreach ($secrets as $secret) {
$handler->blacklist($key, $secret);
}
}

$handler->setApplicationPaths(
array_flip(Arr::except(
array_flip($files->directories(base_path())), [base_path('vendor')]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ protected function transformHeadersToServerVars(array $headers)
*/
protected function formatServerHeaderKey($name)
{
if (! Str::startsWith($name, 'HTTP_') && $name !== 'CONTENT_TYPE') {
if (! Str::startsWith($name, 'HTTP_') && $name != 'CONTENT_TYPE' && $name != 'REMOTE_ADDR') {
return 'HTTP_'.$name;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Illuminate/Support/Arr.php
Original file line number Diff line number Diff line change
Expand Up @@ -550,10 +550,10 @@ public static function shuffle($array)
* Sort the array using the given callback or "dot" notation.
*
* @param array $array
* @param callable|string $callback
* @param callable|string|null $callback
* @return array
*/
public static function sort($array, $callback)
public static function sort($array, $callback = null)
{
return Collection::make($array)->sortBy($callback)->all();
}
Expand Down
12 changes: 12 additions & 0 deletions src/Illuminate/Support/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,18 @@ public function zip($items)
return new static(call_user_func_array('array_map', $params));
}

/**
* Pad collection to the specified length with a value.
*
* @param int $size
* @param mixed $value
* @return static
*/
public function pad($size, $value)
{
return new static(array_pad($this->items, $size, $value));
}

/**
* Get the collection of items as a plain array.
*
Expand Down
2 changes: 2 additions & 0 deletions src/Illuminate/Support/Facades/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
* @method \Illuminate\Support\Facades\Route name(string $value)
* @method \Illuminate\Support\Facades\Route namespace(string $value)
* @method \Illuminate\Routing\Route group(string $value)
* @method \Illuminate\Support\Facades\Route redirect(string $uri, string $destination, int $status = 301)
* @method \Illuminate\Support\Facades\Route view(string $uri, string $view, array $data = [])
*
* @see \Illuminate\Routing\Router
*/
Expand Down
1 change: 1 addition & 0 deletions src/Illuminate/Support/Pluralizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Pluralizer
'rice',
'series',
'sheep',
'software',
'species',
'swine',
'traffic',
Expand Down
4 changes: 2 additions & 2 deletions src/Illuminate/Support/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,10 @@ function array_set(&$array, $key, $value)
* Sort the array by the given callback or attribute name.
*
* @param array $array
* @param callable|string $callback
* @param callable|string|null $callback
* @return array
*/
function array_sort($array, $callback)
function array_sort($array, $callback = null)
{
return Arr::sort($array, $callback);
}
Expand Down
31 changes: 31 additions & 0 deletions tests/Auth/AuthDatabaseUserProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Mockery as m;
use PHPUnit\Framework\TestCase;
use Illuminate\Auth\GenericUser;
use Illuminate\Auth\DatabaseUserProvider;

class AuthDatabaseUserProviderTest extends TestCase
Expand Down Expand Up @@ -39,6 +40,36 @@ public function testRetrieveByIDReturnsNullWhenUserIsNotFound()
$this->assertNull($user);
}

public function testRetrieveByTokenReturnsUser()
{
$mockUser = new \stdClass();
$mockUser->remember_token = 'a';

$conn = m::mock('Illuminate\Database\Connection');
$conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);
$conn->shouldReceive('find')->once()->with(1)->andReturn($mockUser);
$hasher = m::mock('Illuminate\Contracts\Hashing\Hasher');
$provider = new DatabaseUserProvider($conn, $hasher, 'foo');
$user = $provider->retrieveByToken(1, 'a');

$this->assertEquals(new GenericUser((array) $mockUser), $user);
}

public function testRetrieveByBadTokenReturnsNull()
{
$mockUser = new \stdClass();
$mockUser->remember_token = null;

$conn = m::mock('Illuminate\Database\Connection');
$conn->shouldReceive('table')->once()->with('foo')->andReturn($conn);
$conn->shouldReceive('find')->once()->with(1)->andReturn($mockUser);
$hasher = m::mock('Illuminate\Contracts\Hashing\Hasher');
$provider = new DatabaseUserProvider($conn, $hasher, 'foo');
$user = $provider->retrieveByToken(1, 'a');

$this->assertNull($user);
}

public function testRetrieveByCredentialsReturnsUserWhenUserIsFound()
{
$conn = m::mock('Illuminate\Database\Connection');
Expand Down
32 changes: 32 additions & 0 deletions tests/Auth/AuthEloquentUserProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,38 @@ public function testRetrieveByIDReturnsUser()
$this->assertEquals('bar', $user);
}

public function testRetrieveByTokenReturnsUser()
{
$mockUser = m::mock('stdClass');
$mockUser->shouldReceive('getRememberToken')->once()->andReturn('a');

$provider = $this->getProviderMock();
$mock = m::mock('stdClass');
$mock->shouldReceive('getAuthIdentifierName')->once()->andReturn('id');
$mock->shouldReceive('where')->once()->with('id', 1)->andReturn($mock);
$mock->shouldReceive('first')->once()->andReturn($mockUser);
$provider->expects($this->once())->method('createModel')->will($this->returnValue($mock));
$user = $provider->retrieveByToken(1, 'a');

$this->assertEquals($mockUser, $user);
}

public function testRetrieveByBadTokenReturnsNull()
{
$mockUser = m::mock('stdClass');
$mockUser->shouldReceive('getRememberToken')->once()->andReturn(null);

$provider = $this->getProviderMock();
$mock = m::mock('stdClass');
$mock->shouldReceive('getAuthIdentifierName')->once()->andReturn('id');
$mock->shouldReceive('where')->once()->with('id', 1)->andReturn($mock);
$mock->shouldReceive('first')->once()->andReturn($mockUser);
$provider->expects($this->once())->method('createModel')->will($this->returnValue($mock));
$user = $provider->retrieveByToken(1, 'a');

$this->assertNull($user);
}

public function testRetrieveByCredentialsReturnsUser()
{
$provider = $this->getProviderMock();
Expand Down
48 changes: 47 additions & 1 deletion tests/Integration/Auth/AuthenticationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Orchestra\Testbench\TestCase;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Schema;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Foundation\Auth\User as Authenticatable;

/**
Expand Down Expand Up @@ -34,7 +35,7 @@ public function setUp()
$table->string('email');
$table->string('username');
$table->string('password');
$table->string('remember_token')->default('');
$table->string('remember_token')->default(null)->nullable();
$table->tinyInteger('is_active')->default(0);
});

Expand Down Expand Up @@ -157,6 +158,51 @@ public function test_logging_out()
$this->assertNull($this->app['auth']->user());
Event::assertDispatched(\Illuminate\Auth\Events\Logout::class);
}

/**
* @test
*/
public function logging_in_out_via_attempt_remembering()
{
$this->assertTrue(
$this->app['auth']->attempt(['email' => 'email', 'password' => 'password'], true)
);
$this->assertInstanceOf(AuthenticationTestUser::class, $this->app['auth']->user());
$this->assertTrue($this->app['auth']->check());
$this->assertNotNull($this->app['auth']->user()->getRememberToken());

$oldToken = $this->app['auth']->user()->getRememberToken();
$user = $this->app['auth']->user();

$this->app['auth']->logout();

$this->assertNotNull($user->getRememberToken());
$this->assertNotEquals($oldToken, $user->getRememberToken());
}

/**
* @test
*/
public function auth_via_attempt_remembering()
{
$provider = new EloquentUserProvider(app('hash'), AuthenticationTestUser::class);

$user = AuthenticationTestUser::create([
'username' => 'username2',
'email' => 'email2',
'password' => bcrypt('password'),
'remember_token' => $token = str_random(),
'is_active' => false,
]);

$this->assertEquals($user->id, $provider->retrieveByToken($user->id, $token)->id);

$user->update([
'remember_token' => null,
]);

$this->assertNull($provider->retrieveByToken($user->id, $token));
}
}

class AuthenticationTestUser extends Authenticatable
Expand Down
3 changes: 3 additions & 0 deletions tests/Support/SupportArrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,9 @@ public function testSort()
['name' => 'Desk'],
];

$sorted = array_values(Arr::sort($unsorted));
$this->assertEquals($expected, $sorted);

// sort with closure
$sortedWithClosure = array_values(Arr::sort($unsorted, function ($value) {
return $value['name'];
Expand Down
11 changes: 11 additions & 0 deletions tests/Support/SupportCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,17 @@ public function testZip()
$this->assertEquals([3, 6, null], $c[2]->all());
}

public function testPadPadsArrayWithValue()
{
$c = new Collection([1, 2, 3]);
$c = $c->pad(4, 0);
$this->assertEquals([1, 2, 3, 0], $c->all());

$c = new Collection([1, 2, 3, 4, 5]);
$c = $c->pad(4, 0);
$this->assertEquals([1, 2, 3, 4, 5], $c->all());
}

public function testGettingMaxItemsFromCollection()
{
$c = new Collection([(object) ['foo' => 10], (object) ['foo' => 20]]);
Expand Down

0 comments on commit 7619e4f

Please sign in to comment.