Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authorization Policy without model

I need to authorize users on a forum. So in blade, I have @can('editPost', $post) before showing the form to reply to a topic. My PostPolicy class has a editPost method that validates to true if it's the users own post.

However, the issue appears when I want to do a simple check, like deletePost(). This checks to see if Auth::user()->isAdmin

public function deletePost(User $user) {
    return Auth::user()->isAdmin;
    // return $user->isAdmin
}

However, this won't even get called, since I'm not passing an instance of Post

My real world application is much more complicated, but I'm using isAdmin as a simple example.

I guess defining $gate->define('deletePost', 'App\Policies\PostPolicy@deletePost'); in AuthServiceProvider could work, but would end up separating my definitions and methods, and ultimately for a large app clutter the AuthServiceProvider

like image 536
Pistachio Avatar asked Nov 06 '15 22:11

Pistachio


People also ask

What is an authorization policy?

An authorization policy either grants or excludes permission to a user or user group, acting in one of more roles, to perform an operation on an type of object, for a resource which is scoped by its resource type. The elements of an authorization policy are described below: User. Who initiates the operation.

What is authorization and authentication in laravel?

In addition to providing built-in authentication services, Laravel also provides a simple way to authorize user actions against a given resource. For example, even though a user is authenticated, they may not be authorized to update or delete certain Eloquent models or database records managed by your application.

What are laravel policies?

Policies in Laravel: Laravel Gates and policies are like routes and controllers, respectively. Gates allows users to define an authorization using a simple closure-based approach. If you want an action unrelated to any specific model, gates are perfect to use.


2 Answers

When you register a policy it is the classname that is used to route checks to the class, so in order to get routed to the policy you can just pass the class name of the type you registered it with.

Try using @can('delete', Post::class) and see if that gets you there

refer to Illuminate\Auth\Access\Gate::firstArgumentCorrespondsToPolicy

EDIT After a little more diggin I found this https://github.com/laravel/framework/commit/70f75255808ffc96275e6f2f356616dd2e163434#diff-961368895033e553787b301c3be0e17a

so it looks like if you on version 5.1.23 then you will be able to pass a string otherwise your will need to just pass new Post

like image 106
RDelorier Avatar answered Oct 21 '22 04:10

RDelorier


In controllers

$this->authorize('<ability>', <Class-With-Rule::class> | <Full-Path-To-Class>);

In Blade view

@can('<ability>', <Class-With-Rule>::class> | <Full-Path-To-Class>)

In Eloquent model

$user->can('<ability>', <Class-With-Rule>::class> | <Full-Path-To-Class>);
like image 31
user634545 Avatar answered Oct 21 '22 04:10

user634545