Skip to content
This repository has been archived by the owner on Jul 16, 2021. It is now read-only.

Proposal: Update Authorization to Allow Checks on Multiple Abilities #657

Closed
mikebronner opened this issue Jun 27, 2017 · 7 comments
Closed

Comments

@mikebronner
Copy link

mikebronner commented Jun 27, 2017

Right now checking multiple abilities is cumbersome, for example:

if (auth()->check() && auth()->user()->can('edit', $post) || auth()->user()->can('create', $post)) {
    //
}

Would become more succinct using an optional array as the first parameter:

if (auth()->check() && auth()->user()->can(['edit', 'create'], $post)) {
    //
}

or:

@can (['edit', 'create'], $post)
    //
@endcan

The evaluation would default to or (meaning if any of the abilities were truthful, the check would pass. I could see adding an optional attribute in the 3rd $options parameter that would allow setting the check to and.

This would have to work in blade directives and middlewares as well. Admittedly, this is a pretty intrusive change, but would not break backwards compatibility, as the first parameter would either be a string or an array of strings.

Would love to hear your thoughts, recommendations, etc. Thanks!

@BrandonSurowiec
Copy link

BrandonSurowiec commented Jun 28, 2017

I like the idea, but I would use different blade directives to indicate AND or Or. I wouldn't tack on a third param. Usually it's a code smell when you're toggling behavior like that and it becomes a bit ambiguous when looking at it. (The params manifest as a true/false value and are hard to understand, even though this case you would prob pass a string.)

I'm not sure that the default should be OR. Maybe it should be AND. Then we can use the blade directives: @can(['edit', 'create']) and @canOr(['edit', 'create'], $post). I would rather default to stricter security instead of less with the @can directive. Thoughts?

@decadence
Copy link

decadence commented Jun 28, 2017

Would be better to have canAll (or canEach) and canAny

@mikebronner
Copy link
Author

@decadence I like that direction. That way there is no ambiguity as to how permissions are actually resolved. I think that would alleviate @BrandonSurowiec 's concerns as well. This would also make it much simpler to implement, and not require retooling of all the underlying methods.

@BrandonSurowiec
Copy link

BrandonSurowiec commented Jun 28, 2017

The every method in functional programming indicates all values are truthy, so maybe @canEvery would be appropriate. I like @decadence's idea.

@mikebronner
Copy link
Author

mikebronner commented Jul 4, 2017

Yea, that sounds good: @canAny and @canEvery. Will start working on a PR today.

@mikebronner
Copy link
Author

mikebronner commented Jul 4, 2017

One thing I don't like about ...checkEvery($abilities... is that every refers to a singular noun, while all refers to a plural noun. It's less fluent to read and requires an extra "brain-cycle" to register, because you trip over it linguistically. As opposed to ...checkAll($abilities.... I do think checkEvery is more explicit in its meaning though. (This is in the gate class, not the blade directive.)

@mikebronner
Copy link
Author

mikebronner commented Jul 15, 2017

PR #19900 didn't make it. Next attempt is in PR #20084 (laravel/framework#20084)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants