Problem/Motivation
\Drupal\field_ui\Access\ViewModeAccessCheck and \Drupal\field_ui\Access\FormModeAccessCheck are bundled inside the field_ui.module.
Pre-REST, this made sense because there was only one way to handle view modes and that was via the field_ui.module.
But this adds a dependency on field_ui.module if you want to get entity_view_mode and entity_form_mode configuration via REST API.
See related issues: #2843780: EntityResource: Provide comprehensive test coverage for EntityFormMode entity and #2843781: EntityResource: Provide comprehensive test coverage for EntityViewMode entity.
Proposed resolution
Move \Drupal\field_ui\Access\ViewModeAccessCheck and \Drupal\field_ui\Access\FormModeAccessCheck from field_ui.module into entity access handlers inside the Entity core component.
Note: Filing this against the rest.module component for now to get feedback from the REST maintainers first.
Remaining tasks
- Write patch.
- Write tests.
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | 2867266-12.patch | 1.04 KB | wim leers |
| #11 | 2867266-11.patch | 4.67 KB | Anonymous (not verified) |
Comments
Comment #2
shadcn commentedComment #3
shadcn commentedComment #4
wim leersComment #5
jamesdeee commentedI'm going to assign this to myself and have a stab at it. I hope everyone's happy with that - please let me know if not. I've been helping to work through some of the issues at Write EntityResourceTestBase subclasses for every other entity type, and I was just about to have a go at test coverage for EntityFormMode when I saw that @vaplas has linked this ticket.
Comment #6
jamesdeee commentedI'm trying to step my way through this. The first part of the requirement is reasonably clear - ViewModeAccessCheck and FormModeAccessCheck both have an access method (in fact, bar the constructor, that's the only method they have).
The bit I'm less clear on is where they need to go. I've stepped through the code and it looks like entity access is governed by EntityAccessCheck and EntityAccessControlHandler.
They both have their own access methods. I'm sort of assuming one of them gets called by the access method on Entity itself - though I can't quite see how.
So is the task here to adapt one of access methods that already exist in the Entity code, so that the method recognises when the call is for an entity_view_form or an entity_view_mode, and then applies the logic in the access checker classes in field_ui? And if so, can anyone help me out with which access method needs to be adapted?
Or am I just waaay off the mark?
Comment #7
berdirI guess that we need is to convert those into subclasses of EntityAccessControlHandler, similar to other entity types and then put it into the annotation of those entity classes. possibly even the same class/code if it's generic enough. And then update \Drupal\field_ui\Routing\RouteSubscriber::alterRoutes() to use them.
But I'm not sure if we can really replace that, as view/form displays are special in that they are auto-created, at least the default display. So that might not actually exist, but we still want to allow access.
So likely we can't actually replace them completely, just model the new code based on them.
Comment #8
jamesdeee commentedSo you'd end up with something like below (obviously this wouldn't work, as the variables in the function signature don't match the variables in the function body, as I've just cut and pasted this together).
I've put this in the core/config/Entity directory. Is that what you have in mind?
I assume there would need to be some logic somewhere that would match the entity type to the AccessControlHandler - but I don't really understand where that would happen.
Comment #9
wim leersComment #10
jamesdeee commentedOK, so progress on this is slooooow because I don't really completely understand what I'm doing. I think I'm halfway there - if anyone wants to jump in and make suggestions, please do. I'll put this into a patch later - even though it doesn't work I guess it's a good way to kick things off.
So, I've added an access method to the ConfigEntityBase class:
This gets called when a user hits the entity_form_display endpoint. In turn, it creates a new ConfigEntityAccessControlHandler, which just has an access method on it. I figure this is all it needs since the only thing to check is whether the user has the export content permission.
The ConfigEntityAccessControlHandler looks like this:
The main problem I'm having at the moment seems to be cacheing - if I clear the cache then hit the endpoint with an anonymous user, I get an access denied message. If I do the same thing with an admin user, I can access the configuration. If I then go back to the anonymous user and I can get to the config.
I don't really understand where the response gets cached. Can anyone help?
Comment #11
Anonymous (not verified) commentedIt can not affect the cache through a boolean values. Instead, an
AccessResultis used withaddCacheableDependency, or via methods that already contain necessary cache dependencies.But we do not need to change a global handler in this issue. Only EntityFormMode and EntityViewMode. See issue summary (IS) and #7.
Well, I stole the work from the #2866666: Add proper access handlers for view and form displays for our entities, and moved the permissions from field_ui.module. But maybe we need in additional permissions like
administer {$entity->getTargetType()} display mode.Comment #12
wim leersHm, looking at the changes in #11, I wonder why we can't do this instead?
I have the feeling that I'm missing something very obvious…
Comment #13
jamesdeee commented@vaplas - nice job! I was waaaay off the mark!
Yes, I feel like it would be a good idea to introduce that additional permission. But weren't the REST permissions heavily simplified between 8.2 and 8.3? Would this not be a step back?
Comment #14
Anonymous (not verified) commented#12: Hah, great point! Thanks, @Wim Leers! I tried to find a history of changes. And there seemed to be times when it was (see #2105557: Add an admin_permission to EntityType annotations to provide simple default access handling). But then we lost these entities (see #2031717: Make entity module not required). But now EntityFormMode and EntityViewMode are back in service!) So, why not return 'admin_permission' too?
#13: Thanks for the pleasant feedback, @jamesdesq. You are right, the additional permissions are not what we need here :)
Comment #15
wim leers@vaplas I'm asking why #12 is not functionally identical to #11, but just much simpler?
Comment #16
Anonymous (not verified) commented@Wim Leers, I think #12 is very nice way, which in everything is better than #11:)
I was only confused by the phrase:
For this reason, I only added references to the history of access changes to these entities in #14 (for me these links only confirm the correctness of #12 idea). And if no one has any flaws, let's change the status!
Comment #17
tstoecklerAt the very least
field_ui_entity_type_build()needs to be updated to remove the (now-)duplicated setting of the admin permission.So the permission we're referencing here is provided by Field UI, so I guess we would also have to move the permission, but the question is where to move it to?
Comment #18
wim leersIndeed.
I think the answer is:Nope, that does not work, becausefield.permissions.yml?EntityFormMode&EntityViewModelive inlib/Drupal/Core… ugh, this makes total sense given this issue's title (which I hadn't read in some time). It also explains why today's code is what it is.Re-reading the issue brings me back to @Berdir's comment in #7:
@tstoeckler, do you agree with @Berdir's recommendations/thoughts?
Comment #19
tstoecklerI think we are talking about different things here. I just now read the issue summary and that talks about
\Drupal\field_ui\Access\ViewModeAccessCheck(and the form mode equivalent). Despite their name, those actually control access toEntityViewDisplayentities, however, notEntityViewMode(and the form mode equivalent). We already discussed how to make those use the entity access system at #2866666: Add proper access handlers for view and form displays and decided to punt that to #2882273: Make (Form|View)ModeAccessCheck use the entity display access control handler. That last issue also seems to be similar to what @Berdir suggested in #7, although to be honest, I don't grok that comment 100%.The latest patch, however, does actually patch the
EntityViewMode(and form) entity type, not the display one(s).So not sure what this issue is actually about. Having written this, I'm pretty confused, to be honest.
Comment #21
wim leersThis is blocking 4 issues. All 4 of those are part of the 6 remaining blockers to #2824572: Write EntityResourceTestBase subclasses for every other entity type..
Bumping to major.
Assigning to me to address that.
Comment #22
wim leersComment #23
wim leersAs an unexpected side effect, #2907654: No URL can be generated for the 'add-form' route of EntityViewMode and EntityFormMode entities unblocked #2843780 — see #2843780-32: EntityResource: Provide comprehensive test coverage for EntityFormMode entity. In that issue, we (or at least I) didn't realize there was a bug in the entity class for
Entity(Form|View)Mode; now that that is fixed, that issue is also unblocked, hurray! And so is #2843781: EntityResource: Provide comprehensive test coverage for EntityViewMode entity!We should still do this though, since it's nonsensical that the access logic for an entity type lives in a different module than the entity type.
This is now just not a blocker anymore. Also, #21 said this was blocking 4 issues, but it was blocking only 2, my bad!
Comment #35
smustgrave commentedThank you for creating this issue to improve Drupal.
We are working to decide if this task is still relevant to a currently supported version of Drupal. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or is no longer relevant. Your thoughts on this will allow a decision to be made.
Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.
Thanks!