Ramy Farid Ramy Farid - 1 month ago 6
PHP Question

Using a policy's this->authorize() check in a laravel controller inside a store() method

So I was reading about using laravel policies for granting authorities on the resources of my application but there seems to be a problem there though I followed the tutorial.

I have a user model which can't be created via HTTP requests except by other users who have the Entrust role of 'Admin' or 'Broker'. What I understood and succeeded to make it work on other actions like indexing users was the following:


  1. Inside the
    AuthServiceProvider.php
    inside the private
    $policies
    array, I registered that User class with the
    UserPolicy
    class like that

    class AuthServiceProvider extends ServiceProvider {

    protected $policies = [

    'App\Model' => 'App\Policies\ModelPolicy',
    User::class => UserPolicy::class,
    Insured::class => InsuredPolicy::class
    ];

    public function boot(GateContract $gate)
    {
    $this->registerPolicies($gate);
    }


    }

  2. Define the UserPolicy controller class

    class UserPolicy {

    use HandlesAuthorization;

    protected $user;

    public function __construct(User $user) {
    $this->user = $user;
    }

    public function index(User $user) {
    $is_authorized = $user->hasRole('Admin');
    return $is_authorized;
    }

    public function show(User $user, User $user_res) {

    $is_authorized = ($user->id == $user_res->id);
    return $is_authorized;
    }

    public function store() {
    $is_authorized = $user->hasRole('Admin');
    return $is_authorized;
    }


    }

  3. Then inside the
    UserController
    class, before performing the critical action I use
    this->authorize()
    check to halt or proceed depending on the privilege of the user

    class UserController extends Controller
    {

    public function index()
    {
    //temporary authentication here
    $users = User::all();
    $this->authorize('index', User::class);
    return $users;
    }

    public function show($id)
    {
    $user = User::find($id);
    $this->authorize('show', $user);
    return $user;
    }

    public function store(Request $request) {


    $user = new User;
    $user->name = $request->get('name');
    $user->email = $request->get('email');
    $user->password = \Hash::make($request->get('password'));

    $this->authorize('store', User::class);

    $user->save();

    return $user;

    }


    }



The problem is that
$this->authorize()
always halts the process on the store action returning exception: This action is unauthorized.

I tried multiple variations for arguments of the authorize() and can't get it to work like the index action

Answer

In store() function of UserPolicy::class you are not passing the User model object:

public function store(User $user) {
   $is_authorized = $user->hasRole('Admin');
   return true;
}

missing argument User $user.

Maybe this is the cause of the problem.