garrettmassey's avatar

Nova's HasMany add{model} permission incorrectly allowing access

I have a model/policy/resource called "Department" and a model/policy/resource called "User". A department has many users in a 'staff' relationship like so:

    /**
     * Get the staff for the department.
     *
     * @return HasMany<User>
     */
    public function staff(): HasMany
    {
        return $this->hasMany(User::class, 'department_id');
    }

The Department resource's fields for detail looks like this:

and my Department policy has this method:

/**
     * @param User $user
     * @param Department $department
     * @return bool
     */
    public function addStaff(User $user, Department $department): bool
    {
        return false;
    }

However, when I am on the detail view of a specific department, I see the option to create a new staff member in that department, and that is not supposed to happen. I'm not sure what I'm missing, any thoughts?

0 likes
2 replies
LaryAI's avatar
Level 58

The issue you're experiencing is likely due to the way Nova handles permissions for related resources. In your case, the addStaff method in the Department policy is intended to prevent users from adding new staff members to a department. However, Nova might not be correctly associating this policy method with the HasMany relationship.

Here are a few steps you can take to troubleshoot and resolve this issue:

  1. Ensure Policy is Registered: Make sure that your Department policy is correctly registered in the AuthServiceProvider. It should look something like this:

    protected $policies = [
        Department::class => DepartmentPolicy::class,
    ];
    
  2. Check Policy Method Naming: Nova uses specific naming conventions for policy methods. For a HasMany relationship, Nova might expect a method like createUser or createStaff in the User policy, not addStaff in the Department policy. Ensure that the method name aligns with Nova's expectations.

  3. User Policy: If the User model has its own policy, ensure that it includes a method like create or createForDepartment that returns false. This method should be responsible for determining if a user can be created in the context of a department.

    public function create(User $user): bool
    {
        return false;
    }
    
  4. Override Resource Methods: If the above steps don't resolve the issue, you can override the authorizedToCreate method in the User resource to explicitly check the policy:

    public static function authorizedToCreate(Request $request)
    {
        return false;
    }
    
  5. Debugging: Add some logging or debugging statements in your policy methods to ensure they are being called as expected. This can help you identify if the issue is with the policy not being invoked.

By following these steps, you should be able to prevent unauthorized creation of staff members in the department detail view. If the problem persists, consider reviewing the Nova documentation or checking for any updates or known issues related to your version of Nova.

garrettmassey's avatar

I mixed it up, I meant to put addUser instead of addStaff on the policy. Changing that fixed it.

Please or to participate in this conversation.