Policies
To limit which users may view, create, update, or delete resources, Nova leverages Laravel’s authorization policies. Policies are simple PHP classes that organize authorization logic for a particular model or resource. For example, if your application is a blog, you may have aPost
model and a corresponding PostPolicy
within your application.
When manipulating a resource within Nova, Nova will automatically attempt to find a corresponding policy for the model. If Nova detects a policy has been registered for the model, it will automatically check that policy’s relevant authorization methods before performing their respective actions, such as:
viewAny
view
create
update
replicate
delete
restore
forceDelete
Post
model, you simply need to define an update
method on the model’s corresponding policy class:
app/Policies/PostPolicy.php
Undefined Policy Methods
If a policy exists but is missing a method for a particular action, Nova will use the following default permission for each actions:Policy Action | Default Permission |
---|---|
viewAny | Allowed |
view | Forbidden |
create | Forbidden |
update | Forbidden |
replicate | Fallback to create and update |
delete | Forbidden |
forceDelete | Forbidden |
restore | Forbidden |
add{Model} | Allowed |
attach{Model} | Allowed |
attachAny{Model} | Allowed |
detach{Model} | Allowed |
runAction | Fallback to update |
runDestructiveAction | Fallback to delete |
Hiding Entire Resources
If you would like to hide an entire Nova resource from a subset of your dashboard’s users, you may define aviewAny
method on the model’s policy class. If no viewAny
method is defined for a given policy, Nova will assume that the user can view the resource:
app/Policies/PostPolicy.php
When Nova & Application Authorization Logic Differs
If you need to authorize actions differently when a request is initiated from within Nova versus your primary application, you may utilize Nova’swhenServing
method within your policy. This method allows you to only execute the given callback if the request is a Nova request. An additional callback may be provided that will be executed for non-Nova requests:
app/Policies/PostPolicy.php
Using Separate Policy Classes for Nova Resources
You may also create a policy specifically for Nova resources instead of relying on the Eloquent model’s application level policy. To get started, generate a new Nova policy via thenova:policy
command:
nova:policy
command above will create a new policy class as App\Nova\Policies\PostPolicy
. In addition, the generated policy will authorize against App\Nova\Post
instead of App\Models\Post
. To register the policy with your Nova resource, you should specify the policy within the resource’s $policy
property:
app/Nova/Post.php
Relationships
We have already learned how to authorize the typical view, create, update, and delete actions, but what about relationship interactions? For example, if you are building a podcasting application, perhaps you would like to specify that only certain Nova users may add comments to podcasts. Again, Nova makes this simple by leveraging Laravel’s policies. When working with relationships, Nova uses a simple policy method naming convention. To illustrate this convention, lets assume your application hasPodcast
resources and Comment
resources. If you would like to authorize which users can add comments to a podcast, you should define an addComment
method on your podcast model’s policy class:
app/Policies/PodcastPolicy.php
add{Model}
policy method naming convention for authorizing relationship actions.
Authorizing Attaching / Detaching
For many-to-many relationships, Nova uses a similar naming convention. However, instead ofadd{Model}
, you should use an attach{Model}
/ detach{Model}
naming convention. For example, imagine a Podcast
model has a many-to-many relationship with the Tag
model. If you would like to authorize which users can attach “tags” to a podcast, you may add an attachTag
method to your podcast policy. In addition, you will likely want to define the inverse attachPodcast
on the tag policy:
app/Policies/PodcastPolicy.php
attachAny{Model}
method on your policy class. This will prevent the “Attach” button from displaying in the Nova UI entirely:
app/Policies/PodcastPolicy.php
When working with many-to-many relationships, make sure you define the proper authorization policy methods on each of the related resource’s policy classes.
Disabling Authorization
If one of your Nova resources’ models has a corresponding policy, but you want to disable Nova authorization for that resource (thus allowing all actions), you may override theauthorizable
method on the Nova resource:
app/Nova/~Resource.php
Fields
Sometimes you may want to hide certain fields from a group of users. You may easily accomplish this by chaining thecanSee
method onto your field definition. The canSee
method accepts a closure which should return true
or false
. The closure will receive the incoming HTTP request:
app/Nova/~Resource.php
Authorizable
trait’s can
method on our User
model to determine if the authorized user is authorized for the viewProfile
action. However, since proxying to authorization policy methods is a common use-case for canSee
, you may use the canSeeWhen
method to achieve the same behavior. The canSeeWhen
method has the same method signature as the Illuminate\Foundation\Auth\Access\Authorizable
trait’s can
method:
To learn more about Laravel’s authorization helpers and the
can
method, check out the full Laravel authorization documentation.Index Filtering
You may notice that returningfalse
from a policy’s view
method does not stop a given resource from appearing in the resource index. To filter models from the resource index query, you may override the indexQuery
method on the resource’s class.
This method is already defined in your application’s App\Nova\Resource
base class; therefore, you may simply copy and paste the method into a specific resource and then modify the query based on how you would like to filter the resource’s index results:
app/Nova/~Resource.php
Relatable Filtering
If you would like to filter the queries that are used to populate relationship model selection menus, you may override therelatableQuery
method on your resource.
For example, if your application has a Comment
resource that belongs to a Podcast
resource, Nova will allow you to select the parent Podcast
when creating a Comment
. To limit the podcasts that are available in that selection menu, you should override the relatableQuery
method on your Podcast
resource:
app/Nova/~Resource.php
Dynamic Relatable Methods
You can customize the “relatable” query for individual relationships by using a dynamic, convention based method name that is suffixed with the pluralized name of the model. For example, if your application has aPost
resource, in which posts can be tagged, but the Tag
resource is associated with different types of models, you may define a relatableTags
method to customize the relatable query for this relationship:
app/Nova/~Resource.php
resource
and resourceId
for the request via the NovaRequest
instance that is passed to your method:
app/Nova/~Resource.php
Relationship Types
When a Nova resource depends on another resource via multiple fields, you will often assign the fields different names such as:app/Nova/User.php
app/Nova/User.php
Scout Filtering
If your application is leveraging the power of Laravel Scout for search, you may also customize theLaravel\Scout\Builder
query instance before it is sent to your search provider. To accomplish this, override the scoutQuery
method on your resource class:
app/Nova/Post.php