Search code examples
laravellaravel-5laravel-authorization

How to define a policy method with no argument in Laravel 5.2?


It's sometimes necessary to check user authorization for an action with no argument like create/store method:

class PostPolicy
{
    use HandlesAuthorization;

    /**
     * Determine if the user can create a new post.
     *
     * @param  \App\User $user
     * @return bool
     */
    public function create(User $user)
    {
        if($user->is_admin)
        {
            return true;
        }

        return false;
    }
}

and use the authorize method in PostController:

class PostController extends Controller
{
    /**
     * Show the form for creating a new post.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $this->authorize('create');

        //...
    }
}

But it seems that a policy method with no arguments can not correspond to the authorize method on a controller and authorization always fails.


Solution

  • If a policy method has been defined with no arguments like this:

    class PostPolicy
    {
        use HandlesAuthorization;
    
        /**
         * Determine if the user can create a new post.
         *
         * @param  \App\User $user
         * @return bool
         */
        public function create(User $user)
        {
            return $user->is_admin;
        }
    }
    

    You may use the authorize method like this:

    class PostController extends Controller
    {
        /**
         * Show the form for creating a new post.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            $this->authorize('create', \App\Post::class);
    
            //...
        }
    }
    

    and within blade templates by using the @can Blade directive:

    @can('create', \App\Post::class)
        <!-- The Current User Can Update The Post -->
    @endcan
    

    It's also possible to use Gate facade, the User model or the policy helper.