Skip to content

Commit

Permalink
[5.2] Fix missing middleware parameters when using authorizeResource() (
Browse files Browse the repository at this point in the history
#14592)

* Fix missing middleware parameters when using authorizeResource()

Previously, the middleware would not be applied to the create and edit methods since calling middleware() overwrites any previous definitions with a matching name.

* Simulate requests in AuthorizesResourcesTest to verify that the middleware was applied properly
  • Loading branch information
misenhower authored and taylorotwell committed Aug 4, 2016
1 parent 7a0304e commit bf1b486
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ public function authorizeResource($model, $parameter = null, array $options = []
{
$parameter = $parameter ?: strtolower(class_basename($model));

$middleware = [];

foreach ($this->resourceAbilityMap() as $method => $ability) {
$modelName = in_array($method, ['index', 'create', 'store']) ? $model : $parameter;

$this->middleware("can:{$ability},{$modelName}", $options)->only($method);
$middleware["can:{$ability},{$modelName}"][] = $method;
}

foreach ($middleware as $middlewareName => $methods) {
$this->middleware($middlewareName, $options)->only($methods);
}
}

Expand Down
107 changes: 70 additions & 37 deletions tests/Auth/AuthorizesResourcesTest.php
Original file line number Diff line number Diff line change
@@ -1,100 +1,133 @@
<?php

use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Routing\Router;
use Illuminate\Routing\Controller;
use Illuminate\Foundation\Auth\Access\AuthorizesResources;

class AuthorizesResourcesTest extends PHPUnit_Framework_TestCase
{
public function testIndexMethod()
{
$controller = new AuthorizesResourcesController($this->request('index'));
$controller = new AuthorizesResourcesController();

$this->assertHasMiddleware($controller, 'can:view,App\User');
$this->assertHasMiddleware($controller, 'index', 'can:view,App\User');
}

public function testCreateMethod()
{
$controller = new AuthorizesResourcesController($this->request('create'));
$controller = new AuthorizesResourcesController();

$this->assertHasMiddleware($controller, 'can:create,App\User');
$this->assertHasMiddleware($controller, 'create', 'can:create,App\User');
}

public function testStoreMethod()
{
$controller = new AuthorizesResourcesController($this->request('store'));
$controller = new AuthorizesResourcesController();

$this->assertHasMiddleware($controller, 'can:create,App\User');
$this->assertHasMiddleware($controller, 'store', 'can:create,App\User');
}

public function testShowMethod()
{
$controller = new AuthorizesResourcesController($this->request('show'));
$controller = new AuthorizesResourcesController();

$this->assertHasMiddleware($controller, 'can:view,user');
$this->assertHasMiddleware($controller, 'show', 'can:view,user');
}

public function testEditMethod()
{
$controller = new AuthorizesResourcesController($this->request('edit'));
$controller = new AuthorizesResourcesController();

$this->assertHasMiddleware($controller, 'can:update,user');
$this->assertHasMiddleware($controller, 'edit', 'can:update,user');
}

public function testUpdateMethod()
{
$controller = new AuthorizesResourcesController($this->request('update'));
$controller = new AuthorizesResourcesController();

$this->assertHasMiddleware($controller, 'can:update,user');
$this->assertHasMiddleware($controller, 'update', 'can:update,user');
}

public function testDestroyMethod()
{
$controller = new AuthorizesResourcesController($this->request('destroy'));
$controller = new AuthorizesResourcesController();

$this->assertHasMiddleware($controller, 'can:delete,user');
$this->assertHasMiddleware($controller, 'destroy', 'can:delete,user');
}

/**
* Assert that the given middleware has been registered on the given controller.
* Assert that the given middleware has been registered on the given controller for the given method.
*
* @param \Illuminate\Routing\Controller $controller
* @param string $method
* @param string $middleware
* @return void
*/
protected function assertHasMiddleware($controller, $middleware)
protected function assertHasMiddleware($controller, $method, $middleware)
{
$this->assertTrue(
in_array($middleware, array_keys($controller->getMiddleware())),
"The [{$middleware}] middleware was not registered"
$router = new Router(new Illuminate\Events\Dispatcher);

$router->middleware('can', 'AuthorizesResourcesMiddleware');
$router->get($method)->uses('AuthorizesResourcesController@'.$method);

$this->assertEquals(
'caught '.$middleware,
$router->dispatch(Request::create($method, 'GET'))->getContent(),
"The [{$middleware}] middleware was not registered for method [{$method}]"
);
}
}

/**
* Get a request object, with the route pointing to the given method on the controller.
*
* @param string $method
* @return \Illuminate\Http\Request
*/
protected function request($method)
class AuthorizesResourcesController extends Controller
{
use AuthorizesResources;

public function __construct()
{
$this->authorizeResource('App\User', 'user');
}

public function index()
{
//
}

public function create()
{
return Request::create('foo', 'GET')->setRouteResolver(function () use ($method) {
$action = ['uses' => 'AuthorizesResourcesController@'.$method];
//
}

$action['controller'] = $action['uses'];
public function store()
{
//
}

return new Route('GET', 'foo', $action);
});
public function show()
{
//
}

public function edit()
{
//
}

public function update()
{
//
}

public function destroy()
{
//
}
}

class AuthorizesResourcesController extends Controller
class AuthorizesResourcesMiddleware
{
use AuthorizesResources;

public function __construct(Request $request)
public function handle($request, Closure $next, $method, $parameter)
{
$this->authorizeResource('App\User', 'user', [], $request);
return "caught can:{$method},{$parameter}";
}
}

0 comments on commit bf1b486

Please sign in to comment.