Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

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);
    }
}

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;
    }
}

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

like image 547
Ramy Farid Avatar asked Oct 29 '16 12:10

Ramy Farid


People also ask

How do I check permissions on a laravel controller?

There is a controller helper function named authorize that you can call from any method in a controller that extends App\Http\Controllers\Controller . This method accepts the action name and the model, and it will throw an exception if the user is not authorized.

How do I authorize laravel?

Laravel provides two primary ways of authorizing actions: gates and policies. Think of gates and policies like routes and controllers. Gates provide a simple, closure-based approach to authorization while policies, like controllers, group logic around a particular model or resource.

What is authorization and authentication in laravel?

Thus, authentication involves checking the validity of the user credentials, and authorization involves checking the rights and permissions over the resources that an authenticated user has.

What is the use of @CAN in laravel?

This package doesn't add any permission-specific Blade directives. Instead, use Laravel's native @can directive to check if a user has a certain permission. You can use @can , @cannot , @canany , and @guest to test for permission-related access.


1 Answers

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.

like image 70
Amit Gupta Avatar answered Oct 19 '22 11:10

Amit Gupta