Lighthouse: Can directive not working with input types

Created on 29 Mar 2019  路  8Comments  路  Source: nuwave/lighthouse

Describe the bug

You end up with an error when trying to use the @can directive and Input Types. The error says:
Too few arguments to function App\\Policies\\PostPolicy::update(), 1 passed in Illuminate\\Auth\\Access\\Gate.php on line 689 and exactly 2 expected

This seems to happen when using the can directive and trying to update a relation or when you combine @can and @update with the flatten argument.

When you type it like:
updatePosts(input: TheInputType!) @can(ability: "update") @upgrade(flatten: true) the Can directive fails since a second argument is not provided to the policy.

When you type it like:
updatePosts(id: ID! @eq, input: TheInputType!) @can(ability: "update") @upgrade(flatten: true)
the Can directive passes, but fails at the Update directive since after flattening it will only return the id in the directive.

Expected behavior

The expected behaviour is it to validate the policy and update the model without failure.

Schema

input UpdatePostsInput {
    id: ID @eq
    name: String
}

Mutation {
  updatePosts(input: UpdatePostsInput!): Post @can(ability: "update") @update(flatten: true)
}

Output/Logs

Click to expand

Too few arguments to function App\\Policies\\PostPolicy::update(), 1 passed in C:\\Users\\123\\Sites\\456\\vendor\\laravel\\framework\\src\\Illuminate\\Auth\\Access\\Gate.php on line 689 and exactly 2 expected


Environment

Lighthouse Version: dev-master fb52b
Laravel Version: 5.8
PHP Version: 7.2

Additional context

From what I can see this is because of the recent pull request #684. Specifically these lines:
https://github.com/nuwave/lighthouse/blob/fb52b50410cc142ad8153ffcfc3a0da282b1e7db/src/Schema/Directives/Fields/CanDirective.php#L45-L50
Since the input is not yet flattened the id argument is not set, which results in the secondary argument not being supplied to the policy.

bug

Most helpful comment

I added the find attribute and it works.

@can(ability: "update", model: "App\\Cashier\\Subscription", find: "id")

All 8 comments

Good analysis. Working on a generalized fix for flattening.

@kraffslol this should be working with the new @spread directive in v3.3.0, can you check?

You can use it instead of the flatten argument.

https://lighthouse-php.com/3.3/api-reference/directives.html#search

Can confirm! Both alternatives specified in the issue now works as expected.

I have the same problem with the version 4.3

extend type Mutation @middleware(checks: ["auth:api"]) { updateSubscriptionsQuantity( input: UpdateSubQuantityInput! @spread ): Subscriptions @can(ability: "update", model: "App\\Cashier\\Subscription") @update(model: "App\\Cashier\\Subscription") }

and this is the error:

"Too few arguments to function App\Policies\SubscriptionPolicy::update(), 1 passed in /usr/src/app/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php on line 691 and exactly 2 expected",

Any idea?

I added the find attribute and it works.

@can(ability: "update", model: "App\\Cashier\\Subscription", find: "id")

@cfaguilera20 how is your SubscriptionPolicy::update?

@enzonotario this is the policy:

    public function update(User $user, Subscription $subscription)
    {
        return $user->id === $subscription->user_id || $user->role == 'admin';
    }

type Mutation {
deletePost(id: ID!): Post @can(ability: "delete", find: "id") @delete
}

This is ok, but how to remove it and make it short.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

a-ssassi-n picture a-ssassi-n  路  3Comments

spawnia picture spawnia  路  3Comments

sadhakbj picture sadhakbj  路  4Comments

mikeerickson picture mikeerickson  路  3Comments

nguyentrongbang picture nguyentrongbang  路  3Comments