Skip to content

Controller authorization example

Tortue Torche edited this page Mar 7, 2014 · 5 revisions

AuthorityController provides a convenient loadAndAuthorizeResource() method in the controller, but what exactly is this doing? It sets up a before filter for every action to handle the loading and authorization of the controller. Let's say we have a typical RESTful controller with that line at the top.

<?php
class ProductsController extends \BaseController
{
    public function __construct() 
    {
        $this->loadAndAuthorizeResource();
    }
}

It will add a before filter that has this behavior for the actions if they exist. This means you do not need to put code below in your controller.

<?php
class ProjectsController extends \BaseController
{
    /**
     * Project Repository
     *
     * @var Project
     */
    protected $projectModel;

    /**
     * current Project instance
     *
     * @var Project
     */
    protected $project;

    /**
     * Project collection records
     *
     * @var Illuminate\Database\Eloquent\Collection
     */
    protected $projects;

    // public function __construct(Project $projectModel = null)
    // {
        // $this->projectModel = $projectModel ?: App::make('Project');
        // $this->loadAndAuthorizeResource();
    // }

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $this->authorize('index', 'Project');
        $this->projects = $this->projectModel->get(); // is equivalent to Project::all()

        // return View::make('projects.index', compact_property($this, 'projects'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        $this->project = App::make('Project');// is equivalent to "new Project;"
        $this->project->fill($this->params['project']); // should be empty
        $this->authorize('create', $this->project);

        // return View::make('projects.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return Response
     */
    public function store()
    {
        $this->project = App::make('Project');
        $this->project->fill($this->params['project']); // $this->params['project'] is equivalent to Input::except('_method', '_token')
        $this->authorize('store', $this->project);

        // if ($this->project->save()) {
        //     return Redirect::route('projects.index');
        // } else {
        //     return Redirect::route('projects.create')
        //         ->withErrors($this->project->errors())
        //         ->with('message', 'There were validation errors.');
        // }
    }

    /**
     * Display the specified resource.
     *
     * @return Response
     */
    public function show()
    {
        $this->project = $this->projectModel->findOrFail($this->params['id']);
        $this->authorize('show', $this->project);

        // return View::make('projects.show', compact_property($this, 'project'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @return Response
     */
    public function edit()
    {
        $this->project = $this->projectModel->findOrFail($this->params['id']);
        $this->authorize('edit', $this->project);

        // if (is_null($this->project)) {
        //     return Redirect::route('projects.index');
        // }
        // return View::make('projects.edit', compact_property($this, 'project'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @return Response
     */
    public function update()
    {
        $this->project = $this->projectModel->findOrFail($this->params['id']);
        $this->project->fill($this->params['project']); // $this->params['project'] is equivalent to Input::except('_method', '_token')
        $this->authorize('update', $this->project);

        // if ($this->project->save()) {
        //     return Redirect::route('projects.show', $this->params['id']);
        // } else {
        //     return Redirect::route('projects.edit', $this->params['id'])
        //     ->withErrors($this->project->errors())
        //     ->with('message', 'There were validation errors.');
        // }
    }

    /**
     * Remove the specified resource from storage.
     *
     * @return Response
     */
    public function destroy()
    {
        $this->project = $this->projectModel->findOrFail($this->params['id']);
        $this->authorize('destroy', $this->project);

        // $this->project->delete();
        // return Redirect::route('projects.index');
    }

    public function someOtherAction()
    {
        if (array_key_exists('id', $this->params)) {
            $this->project = $this->projectModel->findOrFail($this->params['id']);
        } else {
            $this->projects = $this->projectModel->get(); // is equivalent to $this->projectModel->all()
        }
        $this->authorize('someOtherAction', ($this->project ?: 'Project'));

        // return View::make('projects.someOtherAction', compact_property($this, 'project'));
    }
}

The most complex behavior is inside the create and store actions. There it is setting some initial attribute values based on what the given user has permission to access. For example, if the user is only allowed to create projects where the "visible" attribute is true, then it would automatically set this upon building it.

See Authorizing Controller Actions for details on what options you can pass to the loadAndAuthorizeResource().