Sami (SychO) I think we should put this drawing in the docs (with a few tweaks), it's quite nice!
matteocontrini this is one of the things that I think could be improved in the docs.
Absolutely agreed! And more charts should help for complicated processes like this. I think I've rewritten the Authorization docs 2 times already, with more iterations, it should keep getting better.
matteocontrini I think I don't get why global permissions exist. For example, why doesn't the viewDiscussions permission allow to specify a model?
The secret here is that "global permissions" don't really exist. Permissions are just strings in the database that can be added and removed to groups.
The "global" bit here is the ->can() check:
- If
->can() is called with just an ability name (note the distinction between "ability" and "permission" is quite important (another thing to emphasize in the docs)), the authorization system will look for "global policies"; that being, those that don't depend on a subject model.
- If
->can() is called with a subject, any policies registered to that subject's model will be applied as @Sami (SychO) mentioned (first looking for method names that match the ability name, then falling back to the can policy method). Note that some core models (Discussion, User, Post (I think that's all?)) will also implicitly expand the method name. So calling $actor->can('duplicate', $discussion) will check if the user has a 'discussion.duplicate' permission as part of the can check.
In either case, if policies return nothing, it'll return true iff the user is in a group that has a permission matching the ability name or the user is an admin.
Now, getting back to viewDiscussions. Note that it's plural: it's not designed to tell if a user can view a particular discussion, but rather whether users can generally view discussions in some part of the forum. So it can't be scoped to a particular discussion (well, it can, but that won't do anything productive), but it CAN be scoped to a tag: $actor->can('viewDiscussions', $tag), and because there is a TagPolicy implementation for this in the tags extension, that will tell whether a user can view discussions (plural) in the tag in question.