Problem/Motivation
Right now each content entity type needs to define its set of permissions from scratch, then declare a matching access handler. This is pure boilerplate, an entity type's permissions can very precisely be guessed based on the interfaces it implements and the permission granularity it specifies. Furthermore, requiring each developer to create a new access handler each time leaves room for frequent bugs, such as wrong cacheability metadata.
Until this gets committed in Drupal core, Node view permissions module enables permissions "View own content" and "View any content" for each content type on permissions page as it was on Drupal 6.
Proposed resolution
The permissions currently vary based on two factors:
- EntityOwnerInterface
- Permission granularity (bundle / entity_type)
Future iterations of the patch / issue followups would also take into account EntityPublishedInterface.
Generated permissions:
- "administer $entity_type_id" (god mode permission)
- "access $entity_type_id overview" (the basic permission for listings)
- "view $entity_type_id" OR "view own $entity_type_id" / "view any $entity_type_id" depending on EntityOwnerInterface
- create/update/delete permissions per bundle or per entity type, also taking into account EntityOwnerInterface
Note that view permissions are never per-bundle cause we have no way to enforce it, we'd need query access for that (ala node access).
Just like we did for route providers, we introduce the concept of permission providers. That makes this generation opt-in.
Each participating entity type would define the core's permission provider, and the matching access handler. Core calls the permission provider of each entity type when building permissions.
The proposed solution was implemented in the Entity API contrib module (#2801031: Provide a generic entity access handler and permissions) and is used by Commerce and other contrib modules.
Remaining tasks
Roll the patch
| Comment | File | Size | Author |
|---|---|---|---|
| #96 | 2809177-96.patch | 43.55 KB | jibran |
Issue fork drupal-2809177
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
holist commentedI ported the changes to EntityAccessControlHandler and created the permissions provider. Ran out of time after that, tests and permission.yml still need to be ported from the patch in the related Entity API issue.
Comment #3
pwolanin commentedIssue summary needs a lot more detail
Comment #4
bojanz commentedComment #5
bojanz commentedComment #6
bojanz commentedThis issue should also credit mglaman since he wrote the Entity API code with me.
Here's an initial patch. One permission provider, one access handler, matching unit tests.
Questions:
1) EntityType has getRouteProviders(), do we want a matching getPermissionProviders()? Don't see much of a benefit.
2) Do we want to call the permission providers in Drupal\user\PermissionHandler? If yes, we'll need to expand its doc block. If no, we'll need to find a new home for this code. Perhaps a permission_callback + class in system.permissions.yml? Not that great.
3) How do we feel about GenericEntityAccessControlHandler? I assume we don't want to modify the parent class to keep this functionality opt-in. Bikesheds on the name?
Comment #7
bojanz commentedNote for the next reroll:
Both of these EntityAccessControlHandler references should be \Drupal\Core\Entity\GenericEntityAccessControlHandler.
Comment #9
slashrsm commentedWe briefly discussed this at media sprint in Berlin and mostly agreed that it would make sense to also support per-bundle view permissions.
Comment #10
bojanz commentedWe can't do that until we implement query access, otherwise there would be no way to enforce it.
That makes it followup material.
Here is a patch for #7 + the test bot explosions.
Comment #12
dawehner+1 for adding documentation how to use it
Nitpick: I always use tripple equal for strings these days.
Note: I would use an elseif here as well, and otherwise throw an exception or so. Do you think this makes sense?
I don't see something like that in
\Drupal\node\NodePermissions. Is this really needed?One thing I was wondering, ... should we have two classes instead of this if/else?
Mh, I would have expected system module to implement this hook and integrate it?
Comment #13
dawehnerme neither to be honest
In an ideal world,
\Drupal\Component\Discovery\YamlDiscoverywould somehow find acore.permissions.ymlfile as well :( When we put it into a yml file, moving it into a different one, is no BC break at all.That's a tricky one. I also commented/wondered about the class for itself.
Comment #15
manuel garcia commentedRe: #12
2. Done
3. Makes sense to me, done.
4. I'm not sure, left it in there.
5. While I was having a look at this I noticed that the only method from
GenericEntityAccessControlHandlerthat is not an exact copy ofEntityAccessControlHandler's methods isGenericEntityAccessControlHandler::checkCreateAccessso perhaps there's no need to define the rest here?Ran out of time as I've got to feed the kids, but anyway here's a tiny bit of progress =)
Comment #17
andypostWhy they are separate names? I think better to use "any" in both cases (means they should be added unconditionally)
On other hand when owner should just add only "personal/own" update/delete
Comment #18
bojanz commentedA few random responses.
No opinion yet on #17. I think that the permission names are separate because implementing code (D7, D8 contrib) always did it that way, so it was carried over.
Yes, otherwise the labels don't sort as expected.
Feels simpler to have a single class, 1 access control handler relying on 1 permission provider. If 1 permission provider becomes 2, keeping them in sync becomes a task. But I'll accept being outvoted if others feel strongly about this.
Comment #20
vijaycs85Patch in #15 still applies. Fixing test failures with some cleanup on test file.
Comment #21
bojanz commentedWe need to reroll the patch from Entity API, beta1 has major improvements (split into cacheable and non-cacheable providers)
Comment #23
vijaycs85Comment #24
chr.fritschHere is a new patch. I applied https://github.com/fago/entity/commit/9e60a18f49290032cbfbae315259a68cb2... on top of #2809177: Introduce entity permission providers
Comment #26
chr.fritschFixed the last two failing tests...
Comment #27
dawehnerThank you @chr.fritsch for the patches!
Comment #28
wim leersComment #29
phenaproximaI really like this patch a lot. I think it will smooth out permission handling quite a bit -- it's a nice win, and a nice looking patch. I didn't get all the way through it, but here is what I found:
Should be rephrased a bit: "Provides generic, cacheable entity permissions."
"These include"
UncacheableEntityPermissionProvider is in the \Drupal\Core\Entity namespace.
Class is missing a description. Also, is there any reason for this class to not be abstract?
This assumes there is an overview page. Maybe this permission should only be generated if there is a 'collection' route for the entity type?
This check is repeated a couple of times. Maybe it should be a helper method?
Will #2924785: Provide a mechanism to deprecate permissions affect this? If so, how?
This name is misleading, because the constructor makes it quite clear that the entity type must have a permission provider. Maybe we should rename this to something like PermissionsBasedEntityAccessControlHandler or similar?
Considering that $operation can be anything (filter formats, for example, define a 'use' operation), this seems potentially brittle. Not sure what, if anything, we should do about that, though...just thought I'd bring it up.
Nit: There's an extra set of parentheses here.
Same here.
I feel like we could shorten this a bit by using $result->orIf().
Comment #30
dinesh18 commentedI have fixed below points mentioned in the comment #29
Fixed : 1, 2, 3 , 8 and 11 numbered points.
Here is the interdiff and patch.
Comment #31
dinesh18 commentedComment #33
bojanz commentedThanks for the review!
Regarding:
I generally dislike adding helpers that replace a single line check, it just adds a mental jump. I don't mind being overruled though.
Comment #35
mmbkI'll start working on the failed test, and coding standard messages
Comment #36
mmbkFound the failing code: The new class should be called PermissionBasedAccessControlHandler it does not extend this class.
Note: as non-native-engllish-speaker I feel the the correct Name should be PermissionBasedAccessControlHandler not PermissionsBasedAccessControlHandler. I will name the class like this. Ofcourse a native speaker will convince me to keep the suggested name (including the 's')
Comment #37
mmbkRefactored handler's an Test's names to PermissionBasedEntityAccessControlHandler
enforced coding standards, as annotated during last test.
Comment #38
mmbkContinue here:
Comment #39
mmbk#29 5. - removing the assumption, that the entity_type has an collection route is finished, but I have to leave the Sprint, I'll provide the patch tomorrow.
Comment #40
mmbkHere comes the promised patch, I had to adjust a few things:
In EntityPermissionProviderBase::buildPermission I checked the existance of the collection-linkTemplate.
This pushed me straight to the tests, as the prophesized entity_types did not provide the method 'hasLinkTemplate', so they failed.
When comparing both test-classes 'EntityPermissionProviderTest' and 'UncacheableEntityPermissionProviderTest' I found them nearly identitcal, because of this I made 'UncacheableEntityPermissionProviderTest' a derived class of 'EntityPermissionProviderTest'. So I could eliminate the identical methods and variables in 'UncacheableEntityPermissionProviderTest'.
Further more I could introduce the method 'EntityPermissionProviderTest::prophesizeEntityType' that prophesizes an entity_type that is defined by function's parameter, making the entityTypeProvider more clearly.
The already existing test-entity_types claim to have an overview-page, the new orange-entity_type doesn't.
Unfortunately (viewed from the test side) the expectations of both entityTypeProviders are not identical - so they are both needed.
Comment #42
mmbkThoughts:
The provider baseclass 'EntityPermissionProviderBase' is marked as @internal, (to keep other developers from using it yet?) shouldn't the derived classes @internal as well?
I feel the tests need a base-class - but I didn't want to change it in my first larger patch without consultations. If it's likely that more EntityPermissionProviders will be introduced I think it's necessary, if the two existing will remain the only providers it's a nice-to-have.
Failed to apply ? :_( - I'll check this
Comment #43
mmbkSorry - Second try - interdiff of #40 is still valid
Comment #44
mmbkComment #45
timmillwoodI think we could do with a change record for this.
Comment #46
bojanz commentedWe need to roll-in the fix from this Entity API issue: #2951270: Core's generated collection routes do not support the provided "access overview" permission.
Should be simpler here, we just modify the core's DefaultHtmlRouteProvider::getCollectionRoute with something like:
Comment #47
tstoecklerRe #46: I opened #2953566: Allow entities to specify a "collection permission", FYI
Comment #48
tstoecklerI think it would make sense to use the admin permission here instead of hardcoding the permission machine name that is declared by the entity type and also update the documentation accordingly.
Comment #49
gabesulliceJust adding this because the _somewhat_ recent work around entity access policies in #777578: Add an entity query access API and deprecate hook_query_ENTITY_TYPE_access_alter() and broken out into https://www.drupal.org/project/entity_access_policies
seems related.
Comment #50
manuel garcia commentedPostponed #273595: Move permission "view any unpublished content" from Content Moderation to Node on this.
Comment #51
lisastreeter commentedI've updated that patch and rolled-in the fix from this Entity API issue: #2951270: Core's generated collection routes do not support the provided "access overview" permission, as suggested in comment #46.
I took a look at the suggestion in #48, but I wasn't exactly sure how to "use the admin permission". I can get the admin permission machine name with
entity_type->getAdminPermission(), but if that permission is already defined elsewhere, it doesn't need to be built... I think I must be missing something here. My brief efforts to make the proposed change resulted in a bunch of broken tests. So I figured I should get some clarification first before proceeding.Comment #52
tstoecklerRe #51, thanks for the update!
You were right on track, using
$entity_type->getAdminPermission()was exactly what I had in mind. The idea would be that with this patch modules would no longer have to define the admin permission explicitly themselves, as we would do it for them. It might result in a few broken tests, but we should try to fix the tests in that case. Thanks for your effort!Comment #53
bojanz commentedI am planning to come back to this patch soon.
I've made a number of improvements upstream, in preparation for a reroll of the core patch.
Bug fixes:
#2977224: EntityAccessControlHandler::checkEntityOwnerPermissions() doesn't cache update/delete results per user
#2977379: UncacheableEntityAccessControlHandler::checkEntityOwnerPermissions() incorrectly checks access for unpublished entities
New feature (resolving #9 from this issue):
#2977231: EntityPermissionProvider should provide per-bundle view permissions
I've also cleaned up both the tests and the docblocks.
Currently exploring an access handler logic deduplication in #2977381: Reduce duplication between EntityAccessControlHandler and UncacheableEntityAccessControlHandler.
Of course, if anyone is interested in rerolling the patch even partially (with a portion of the fixes from upstream), please go ahead.
Comment #54
lisastreeter commentedI've rerolled the patch with the fixes from:
#2977224: EntityAccessControlHandler::checkEntityOwnerPermissions() doesn't cache update/delete results per user
#2977379: UncacheableEntityAccessControlHandler::checkEntityOwnerPermissions() incorrectly checks access for unpublished entities
#2977231: EntityPermissionProvider should provide per-bundle view permissions
Comment #55
joachim commentedI'm gathering issues that reduce the amount of boilerplate required for custom entity types at #2316171: [meta] Improve DX of entity defining (if you want a UI).
Comment #56
manuel garcia commentedThanks! - I think this is ready for a round of reviews.
Comment #57
bojanz commentedFound and fixed another bug upstream: #2978943: UncacheableEntityPermissionProvider generates incorrect view permissions for entities without an owner.
While rerolling, let's also include #2977381: Reduce duplication between EntityAccessControlHandler and UncacheableEntityAccessControlHandler.
Comment #59
seanbThe
$operation ownshould always be cached per user right?And I also think the
$operation anyshould not have to be cached per user?I must be missing something, but how does providing the permission
view own ($bundle) $entity_typeimpact the caching of the update/delete operations?This seems like a valid use case? Could we add this?
Comment #60
wim leers#59.1++ and #59.2++, absolutely!
#59.3: good question. I looked at the commit history of the
entitymodule; this was introduced in https://github.com/fago/entity/pull/51. The fundamental reason seems to have been . @dawehner in #27.1 also said the reasoning behind this needs to be clearly documented in the issue summary.I think the reasoning is that anything showing unpublished entities is uncacheable anyway: listing unpublished entities is not something you ever do for anonymous visitors. Hence the presence of
view own unpublished {$entity_type_id}in the cacheable permissions provider. But usingview own {$entity_type_id}applies also to published content, and listing published entities is of course something you would do for anonymous visitors; usingview own {$entity_type_id}would "infect" that listing with poor cacheability, hence it's namedUncacheableEntityPermissionsProvider. Even though it's technically not uncacheable, but per-user cacheable aka poorly cacheable, aka pretty much uncacheable in most real-world situations (unless you throw massive cache storage at the problem).Initial quick review, deep dive coming:
s/{Entity/{UncacheableEntity/
Rather than overwriting, use
->orIf().Let's remove the comment and instead pass it as the
$reasonargument — this will result in better DX for Drupal's HTTP APIs :)Comment #61
gabesulliceThis is really impressive work!
I only had time to review the non-test code. Please understand this is mostly bike shed/nitpicky review... so, feel free to ignore and counter whatever you'd like and tell me how wrong I am 😅.
ubernit: just expand these into their own lines.
I wonder if there's a way that this requirement can be met without defining an entirely separate class.
Maybe we could find a way to put a
protected static $hasViewOwnEntityPermission = FALSEon the base class.nit: add an extra newline
❤️ this class name.
Maybe we need an
Entity\Accessnamespace though?nit: s/permission/permissions/g
same.
"Builds permissions based solely on entity type."
strtolower($plural_label)?"Builds entity permissions based on their bundle."
Again, I think this should be lower-cased.
In this case, shouldn't it be the singular label?
Doesn't this also cause "uncacheability"? Does it need to be moved?
I don't see where this class is ever actually used. What am I missing? Is it intended to be a core service?
If it's not a leftover, should it implement
EntityPermissionsProviderInterface?If so, this would just be
{@inheritdoc}This cache info should be added in the
checkEntityOwnerPermissionsandcheckEntityPermissionsmethods. Why? BecausecheckEntityPermissionsdoes not actually vary per entity.This is where
addCacheableDependency($entity)should be. It should be on all of these because it depends on the entity's published status.These, however, do not need to be cached per entity.
Shouldn't this be named
buildPermissions? It will include bundle permissions AFAICT.Comment #62
wim leersThis has the potential to massively improve the DX and SX, by bringing more consistency to both developers and site builders. Tagging and bumping to .
Comment #63
wim leers#61.8+10: Germans won't be happy :)
#61.12+15+16+17: agreed, and you addressed this in https://github.com/fago/entity/pull/53
#61.13: see
entity.permissions.yml#61.7+9+18: see
\Drupal\Core\Entity\EntityTypeInterface::getPermissionGranularity().Comment #64
amateescu commentedI've been working on this in the past few days, and here's what I propose for this issue:
- Let's handle only permission providers in this patch and introduce the matching access handler in a followup, because I think the permission provider topic is complex enough to require proper discussion on its own.
- The current implementation from the contrib Entity API module lays an excellent foundation for this work, but IMO it's missing a key concept: a generic way of getting the permission name for a specific operation of a given entity type. For example: "what's the name of the
view any publishedpermission for nodes? how about media items? (access contentandview media)".While the existing implementation takes the approach of standardizing permission names, I think it's very unlikely that every core/contrib/custom module will (or can) deprecate their existing permissions and use the ones provided by the new entity handler. In fact, I'm pretty sure that renaming the
access contentpermission toview nodewould be so disruptive that it can't be accepted even for Drupal 9.Therefore, my proposal is to add a bunch of methods to
EntityPermissionProviderInterfacethat will allow each entity type to provide a mapping between their existing permission names to a known set of "operations": view any/own published, update any/own, delete any/own, etc.If the number of proposed methods is too high for a single interface, we could move the "own" methods to a separate one. Same for publishing related methods.
Another goal that I'd like to accomplish here is to deprecate the
admin_permissionandpermission_granularityentity type annotation properties, since they can be expressed now by providing a custom permission handler.Here's a patch for this proposal, really looking forward to any feedback :) I also generated an interdiff to #54, but it's not really useful for anything.
We also need to think about providing similar methods for revision-related permissions, but let's settle on the basics first and then decide if we want to tackle those here or in a followup.
Comment #65
joachim commented> - Let's handle only permission providers in this patch and introduce the matching access handler in a followup
+1
Smaller scope and smaller patches is good!
> IMO it's missing a key concept: a generic way of getting the permission name for a specific operation of a given entity type. For example: "what's the name of the view any published permission for nodes? how about media items? (access content and view media)".
That seems useful.
I haven't the time right now for an in-depth review, so here are just a few observations:
Missing a value for @type.
Vague pondering: what about combining these pairs of methods into one, with a $scope parameter that takes 'any' / 'own' / NULL? Too complex?
Nitpick: I think in documentation, variables are usually given in CAPS. So: 'access ENTITY_TYPE'.
Comment #66
amateescu commentedThat's exactly how I started writing these methods, but they seemed too complex indeed and decided to go for more explicit ones instead :)
Comment #68
amateescu commentedFixed the problems pointed out in #65 and the test fails.
Comment #70
amateescu commentedSigh.. fixed those fails and opened #3010805: Fix misleading variable names in EntityTypeManagerInterface.
Comment #72
amateescu commentedMaybe we should go one step further and enforce the usage of the default permission handler for all entity types..
Comment #74
kristiaanvandeneyndeRe #64:
+1
+1, but careful. I proposed this when discussing the query access handler and Bojan said it was a no-go (because it wasn't in the permission handler, which we're working on here so it might be a go after we change it here). See the discussion here: https://github.com/fago/entity/pull/52/files#diff-e0716a56db3064f97a0a45...
+1
Definitely +1, entity type definitions are becoming more and more bloated.
Re #65 / #66:
I'd use explicit methods instead of a catch-all because if we forget about something now, we might need to break BC to factor in new logic. With explicit methods, we can simply add new methods.
Comment #75
kristiaanvandeneyndeYou're losing valuable translatable metadata by converting the permissions to strings early on. I'd use a sort callable that converts the permissions to strings inside the callable, leaving the originals untouched or introduce a sortPermissions method on the handler (not a fan, but would work).
On an unrelated note, there are many entity types that don't have a notion of "own" entities (almost all config entities). Should the default permission provider really do calculations regarding "own" entities? Seems like we could shave of a few nano/milliseconds here by having two providers to extend from?
Then in EntityType we could default to a given provider based on whether the entity type implements EntityOwnerInterface.
Comment #76
joachim commented> That's exactly how I started writing these methods, but they seemed too complex indeed and decided to go for more explicit ones instead :)
Thinking about this more: whether we want them explicit or systematic depends on what their intended purpose is.
I remembered a module I made for D7, which shows entity permissions in an easy-to-read grid: https://www.drupal.org/project/permission_grid
For a use case like this, it would be useful to have just one method: getPermission($verb, $scope, $bundle), so the caller can iterate and get everything in a systematic way.
Comment #77
joachim commentedAnother thought: the whole of the entity access API works with verb parameters -- as in $entity->access($operation, $account).
So it would be consistent to use that here too.
Comment #78
jonathanshawLooks like #57 might have been forgotten along the way.
Comment #79
amateescu commented@jonathanshaw, re #78: Nope, the patch from #64 has been written mostly from scratch, and it doesn't resemble anymore the code from the Entity API contrib module.
I discussed this patch with @bojanz a couple of times in the last month and we agreed to provide a middle ground between explicit and systematic methods, and fold the "any|own" concept into a
$scopeargument. This also resolves the problem pointed out in the second paragraph from #75: entity types that don't implementEntityOwnerInterfacewill simply not return anything for the "own" permission names.Another thing we agreed on was to take out the "published" part from the
viewPublishedPermission()method, so it makes more sense for entity types that don't implementEntityPublishedInterface.@joachim:
The difference with with the entity access layer is that here we have 3 concepts ($operation, $scope, $bundle) instead of one, and bundling all three of them in a single method would provide an inferior DX (compared to the access layer) :)
Comment #81
amateescu commentedFixed the last test fail.
Comment #82
gabesulliceI went ahead and made some of the changes I talk about in the review below (the ones with checkmarks), feel free to take or leave any of them :)
Hmm, why not call this
getPermissionsand build it during construction of the provider?I like the
$scopeidea!✅ We could create another issue to add a
static compare(TranslatableMarkup $a, TranslatableMarkup $b)to theTranslatableMarkupclass.✅ This is an incomplete listing, it's missing the 'published' permissions and I think that this should just be removed, the
$permissionMapproperty is self-documenting enough.✅ Nit: "Note that the 'view own published' permissions will require caching per user. This may harm performance on most sites and is therefore disabled by default."
It's not just bundle specific. Right?
✅ This would be easier to alter/extend by method decoration if it returned the map array, rather than setting the class state within the method. Like so:
$this->permissionMap = $this->buildPermissionMap()✅ Same as above.
✅
__BUNDLE__is begging for a class constant.✅ If
$bundlewere required, it might make this a little simpler to use sinceEntityInterface->bundle()will return the entity type ID if the entity does not have bundles.That way callers writing generic code won't need to do any gymnastics to figure out whether to pass the value or not. Additionally, I think it will allow getting rid of
$perBundlePermissionMap.Comment #84
gabesulliced.o had a little too much I think.
Comment #85
dawehnerMay I ask whether the better fix wouldn't be to fix admin/people/permissions?
Is there a case where 'default' is an expected behaviour? Returning an empty array seems not needed. How about throwing an exception in that case?
I do agree with @gabesullice ... given that everything is prefixed with get already using get for all permissions too seems sensible.
Is it just me or would
$permission = implode('+', array_filter([$admin_permission, $collection_permission]))be more readable?Comment #87
jibranComment #88
aaronmchaleHad a quick stroll through this issue and the latest patch, here's some of my thoughts.
Regarding permission names: there seems to be a standardisation trend in Core now for generated permissions towards a schema of
ENTITY_TYPE BUNDLE: PERMISSION. Most recent example of this is #2914486: Add granular permissions to the Layout Builder, which was inspired by the format used for generated Field UI permissions. I vote we try and stick with this new de facto standard for permission naming as it encourages consistency and so makes everyone's lives easier.Regarding #6:
I'm tempted to say that it could be useful to provide this method, it keeps things consistent, and probably makes it easier to get a list of the providers. Is there a reason we wouldn't want to provide this method?
DefaultEntityPermissionProviderclass: this has a bunch of stub methods, will these be filled out later? Otherwise it might make sense to just remove these so that theEntityPermissionProviderInterfaceforces any extending classes to define these, therefor increasing reliability.I notice that the Entity Type Label Singular and Plural values used to build the permission titles. I wonder if it would be useful to introduce new optional keys to the Entity Type Annotation in the event the Entity Type wants to provide different labels for the Permission Titles. There is already president for doing this, e.g. the key
label_collectionwhich overrides the title of the Collection route. Of course if we did decide to implement this, the new keys should be optional and if not specified simply fall-back to the Singular and Plural Labels.Comment #89
ksbuble commentedI am at Seattle Sprint and working on this issue.
Update: No longer working on this. We thought this was a novice issue and it is not.
Comment #90
alisonI see mentions of "view own unpublished ENTITY_TYPE," but not "view unpublished (BUNDLE) ENTITY_TYPE" (or "view own unpublished (BUNDLE) ENTITY_TYPE") -- are these perms out of scope for this issue?
(I ask b/c there was a question over on #2875867: Add per-bundle unpublished content permissions about possibly switching gears to this issue, instead of that one -- or maybe it's just that #2875867 ought to be postponed until after this one (#2809177) is done?)
Comment #92
manuel garcia commentedComment #93
jofitzRe-rolled for D8.9.x
Comment #94
matsbla commentedFor Comment entity there is an additional factor: You can only create comments if the comment field of parent node/entity is still open. For comments there is now only an 'edit own' permissions, but not 'edit any', should that really be introduced?
Comment #96
jibranReroll for 9.1.x
Comment #97
jibranNW for #85.
Comment #98
aaronmchaleThanks for all the work on this so far.
DefaultEntityPermissionProvidershould either explicitly returnNULLor just return the value of$this->getAdminPermission().This is on
EntityPermissionProviderInterfaceso'view any published'might not make sense here, as "published" is only applicable toEditorialEntityPermissionProvider.EntityPermissionProviderInterface::getViewUnpublishedPermissioneven existing in that interface, the concept of published vs unpublished is only applicable to Content Entities which implement the Publishable interface, and is completely irrelevant for Config Entities. Perhaps we need aEditorialEntityPermissionProviderInterface.null(lowercase) is used, I believe our coding standards sayNULL(uppercase) should be used.While this might be useful, I think introducing that in this issue is far too out of scope, as the scope of this issue should be within the Entity system, if we need this we should open a separate issue, correctly scoped, and postpone on it.
I see we are using the pattern of
BUNDLE: PERMISSION, but at least for the machine names (so not the ones that people see in the UI, although why not for those too) I do believe we should prefix that withENTITY_TYPE, even if that might require some BC work for core or contrib while implementing this new API, I think it's better to be consistent with this new precedent rather than continue old inconsistencies.Thanks,
-Aaron
Comment #101
jibran#3043321: Use generic access API for node and media revision UI has been fixed.
Comment #107
bhanu951 commentedMR #2912 Is a reroll of patch from #96 for 10.1.x branch review comments from #98 need to be addressed.
Comment #108
anybodyComment #109
anybody@bojanz in #53 you wrote:
but the issue summary still says:
I wasn't confident enough to remove that from the issue summary, so could you perhaps have a look to be sure it should be removed?
Looks like the MR already contains the relevant code:
(https://git.drupalcode.org/project/drupal/-/merge_requests/2912/diffs#10...)
I just created #3353503: Add "view $bundle media" permission where exactly that is needed, but I can't tell if it's still an issue. I think it isn't?
Thanks!
Next steps: Solve #85 and #98
Comment #110
grevil commentedWe're currently writing a new permission module: https://www.drupal.org/project/entity_access_by_reference_field
For that reason, we had a look into the different
hook_entity_accessimplementations in core:All of them, but node, use "update", only node uses "edit".
Also, the documentation at https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21... says
but the code in the MR uses "edit" instead of "update". That's quite confusing and we think there should be a consensus on one correct term!
Here's the current implementation from the MR:
So, we'd strongly suggest to change "edit" to "update". Also, the method names use "update", like
getUpdatePermission()Should I update the MR accordingly?
Comment #111
grevil commentedMy bad, the operation is always "update", but the permission is "edit" (which is still quite confusing).
Comment #113
anybody@Core maintainers: Any chance or way to push this forward? Seems this lost traction again, but other important issues are postponed on this (like #273595: Move permission "view any unpublished content" from Content Moderation to Node) and that is still something weird in core, because in the current state users are permitted to view a node they can edit and can't save the node they edit, because URL alias checks view access! See #3167732: Non-admins cannot save unpublished nodes with path alias
So I think for the permission system this is really important to unblock the other issues. How to proceed?
Comment #120
kristiaanvandeneyndeI'd be willing to give this another go, but with what I've learned in the past 6 years since I commented here I'd have to revisit if what was being discussed back then is still relevant now. I have since dropped my dependency on contrib Entity API and created new mechanisms in Group to deal with access.
Some of these are permission providers and access control handlers, but as services that can easily be decorated. Ultimately, I'd like to see if we can do something similar in core but that would be a huge endeavor. Either way, most of the discussion happened years ago and perhaps the first step should be to check how much of the discussion is still applicable today.
Comment #121
bhanu951 commentedMade changes against head and fixed phpstan issues and tests.
Comment #122
kristiaanvandeneyndePlease read my latest comment.
One thing I for instance think is a huge foot-gun is putting the specific permission methods on the interface. Right now it's getUpdatePermission, getDeletePermission, etc. but we cannot know all of the possible entity operations in a site. In Group I fixed this by having a method that takes an operation and returns a permission.
Either way, I don't think we should introduce yet another handler that no-one else can alter properly due to how handlers work in core right now.
Comment #123
ressaAdding workaround in Issue Summary:
Based on comments in #3090468: Access Control with View Own Content / View Own Entity in Core, thanks @pameeela and @anybody!
Comment #125
steinmb commentedRead through the issue. The MR as now is quite small but I wonder, would it make sense to split EntityAccessControlHandler and providers into separate issues. Would that make this issue movable again?
@kristiaanvandeneynde can you elaborate a bit? I am not sure I follow.