Closed (fixed)
Project:
Display Builder
Version:
1.0.x-dev
Component:
State Manager
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
8 Sep 2025 at 15:13 UTC
Updated:
28 Nov 2025 at 16:49 UTC
Jump to comment: Most recent
Comments
Comment #2
pdureau commentedComment #3
smovs commentedComment #4
pdureau commentedThis is a proposal for the logic:
display_builder_instanceentity of the route, check theprofileIdproperty and load thedisplay_builder_profileentity (this may create problems until #3544545: Profile changed in config don't update the instance entity is solved. If yes, let's move this ticket to beta1 scope)Comment #5
pdureau commentedThe logic from comment #4 may not be enough.
We may also need to add to the API checks related to the display we are editing:
administer {entity_type} displaypermissionadminister page_layoutpermissionadminister viewspermissionHow do we implement this in a standardized way? A new method in
DisplayBuildableInterface?Comment #7
smovs commentedI added additional access checks according to the suggestions. Please review
Comment #8
pdureau commentedthanks. i will have a look
Comment #9
pdureau commentedHi Sviatoslav,
Alongside the feedbacks from @mogtofu33
Check access to builder controllers
"builder controllers" are controllers extending
IntegrationControllerBase:You haved added
modules/display_builder_page_layout/src/AccessControlHandler.phpandmodules/display_builder_views/display_builder_views.routing.yml, that's OK.Check access to ApiController
That's the core of the issue.
The goal is to check the requests to ApiContoller. Each endpoint has an "autocast" of
display_builder_instanceentity whereInstanceAccessControlHandleris supposed to be checked. For example:You have added a check to
$entity->getProfile()->getPermissionName(), that's great.Can you also add to the API checks related to the display we are editing:
administer {entity_type} displaypermissionadminister page_layoutpermissionadminister viewspermissionI guess you need a new
DisplayBuildableInterface>getPermissionName()method.Don't hesitate to share your thoughts about this proposal.
Comment #10
pdureau commentedI take it to do the remaining part and send to review.
Comment #11
pdureau commentedComment #12
smovs commentedHi @pdureau
I updated the MR. I added expanded access check coverages. Please let me know if it is enough. Thanks
Comment #13
pdureau commentedComment #14
pdureau commentedWork in progress.
Scope
administer {entity_type} displaypermissionadminister page_layoutpermissionadminister viewspermissionReview with 3 different roles
After pushing an extra commit renaming the permissions.
Limitedprofile is a profile created for this tests in order to check the users can't access the default profile.Role 1: with all permissions (bit not the administrator)
Permissions:
LimitedDisplay Builder profile (Display Buildermodule): YESDefaultDisplay Builder profile (Display Buildermodule): NOField UImodule): YESViewsmodule): YESDisplay Builderfor page layout module): YESTesting
ConfigFormBuilder:Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ✅limitedtodefaultLimitedprofile. Expected: NO. Results: ✅defaulttolimitedLimitedprofile. Expected: ???. Results: ⚠️yes I can. This behavior was not discussed until now, and need to have its own issuePage Layout:
Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ❌ i was able to load itLimitedprofile. Expected: YES. Results: ❌ Got HTTP 403Defaultprofile. Expected: No. Results: ✅ i got HTTP 403Entity view display:
Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ❌ i was able to load itLimitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ❌ i was able to do some changesViews:
Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ❌ i was able to load itLimitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ❌ i was able to do some changesRole 2: has the "classic" permissions of Drupal display building, but not the ones from Display Builder
Permissions:
LimitedDisplay Builder profile (Display Buildermodule): NODefaultDisplay Builder profile (Display Buildermodule): NOField UImodule): YESViewsmodule): YESDisplay Builderfor page layout module): YESPage Layout:
Error: Call to a member function id() on null. We will consider this OK for is and fix it in another issue.Entity view display:
Views:
Role 3: has the Display Builder permissions, but not the ones from classic Drupal display building
Permissions:
LimitedDisplay Builder profile (Display Buildermodule): YESDefaultDisplay Builder profile (Display Buildermodule): NOField UImodule): NOViewsmodule): NODisplay Builderfor page layout module): NOPage Layout:
Entity view display:
Views:
Next steps
What about entity view overrides ?
Also, do we really need "Use Display Builder" permission? It seems this is the same has no "Use the
{Profile}Display Builder profile" permission. Let's remove it if not useful, but we have to ask Jean first.Comment #15
pdureau commentedHi Sviatoslav,
Here is my review for Role 1 & Role 2. I will review Role 3 once the needed work is done.
Thanks for your time. As every security related task, this issue is very valuable.
Comment #16
pdureau commentedi will have a look
Comment #17
pdureau commentedI will rebase, add a kernel test and do some change in the logic.
Comment #18
pdureau commentedwork in progress.
Review with 3 different roles
Limitedprofile is a profile created for this tests in order to check the users can't access the default profile.Role 1: with all permissions (bit not the administrator)
Permissions:
LimitedDisplay Builder profile (Display Buildermodule): YESDefaultDisplay Builder profile (Display Buildermodule): NOField UImodule): YESViewsmodule): YESDisplay Builder for page layoutmodule): YESNodemodule, to test entity view display overrides): YESTesting
ConfigFormBuilder:Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ✅limitedtodefaultprofile. Expected: NO. Results: ✅defaulttolimitedprofile. Expected: ???. Results: ⚠️yes I can. This behavior was not discussed until now, and need to have its own ticketPage Layout:
Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ✅<Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: No. Results: ✅ i got HTTP 403 (to do this test, we need to remove Profile access check first)Entity view display:
Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ✅<Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: No. Results: ✅ i got HTTP 403 (to do this test, we need to remove Profile access check first)Entity view override:
Limitedprofile. Expected: YES. Results: ⚠️ tab visible and access OK, but tab as "display" label instead of the display labelDefaultprofile. Expected: NO. Results: ✅ tab not visible + HTTP 403Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: No. Results: ??? (to do this test, we need to remove Profile access check first)Views:
Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ???Limitedprofile. Expected: YES. Results: ✅Defaultprofile. Expected: NO. Results: ✅ i got HTTP 403 (to do this test, we need to remove Profile access check first)Role 2: has the "classic" permissions of Drupal display building, but not the ones from Display Builder
Permissions:
LimitedDisplay Builder profile (Display Buildermodule): NODefaultDisplay Builder profile (Display Buildermodule): NOField UImodule): YESViewsmodule): YESDisplay Builderfor page layout module): YESNodemodule, to test entity view display overrides): YESPage Layout:
Call to a member function id()Entity view display:
Entity view override:
Views:
Role 3: has the Display Builder permissions, but not the ones from classic Drupal display building
Permissions:
LimitedDisplay Builder profile (Display Buildermodule): YESDefaultDisplay Builder profile (Display Buildermodule): NOField UImodule): NOViewsmodule): NODisplay Builderfor page layout module): NONodemodule, to test entity view display overrides): NOPage Layout:
Entity view display:
Entity view override:
Views:
@jean: Do we really need "Use Display Builder" permission? It seems this is the same has no "Use the
{Profile}Display Builder profile" permission. Let's remove it if not useful.Comment #19
pdureau commentedGitlab CI all green :)
Remaining work in the current issue:
Follow-up for post-beta1:
Comment #20
pdureau commentedDONE:
Comment #21
pdureau commentedNeeds review.
Only 128 lines of PHP code (tests, blank lines & comments removed) to add this very important mechanism ;)
Follow-up for post-beta1:
Comment #22
pdureau commentedrename ConfigFormBuilderTest tests
Comment #23
pdureau commenteddone
Comment #24
pdureau commentedComment #25
pdureau commentedComment #27
mogtofu33 commentedComment #28
pdureau commentedComment #29
pdureau commentedJean, on your 4 comments:
Comment #30
mogtofu33 commentedNeed to fix test ConfigFormBuilderTest, split AccessControlTest for each entity types and use data provider to have lighter and easier to maintain tests.
Comment #31
pdureau commentedI would be happy to do this and fix the phpunit fail probably introduced by the rebase: https://git.drupalcode.org/project/display_builder/-/jobs/7264278
Comment #32
mogtofu33 commentedI am doing a bit on the tests.
Comment #33
mogtofu33 commentedMy bad, didn't want to grab in progress task. I wanted to fix the fail job in a more generic way.
If you can handle the ConfigFormBuilderTest. For the split and data provider let me know if you want me to do it.
Comment #34
pdureau commentedDon't worry. I will rebase your stuff and keep working ConfigFormBuilderTest
Comment #35
pdureau commentedpushed. Pipeline in progress
That would be nice if you do it because I am not sure about the way to do it:
Comment #36
mogtofu33 commentedI had a first pass of update for the tests, ConfigFormBuilderTest was a good start but was failing some test logic, it was good to introduce DisplayBuildableMock so now we can test in a generic way. And later add a more specific test class for our entities.
Next I will try to change it to dataProvider if worth it for each identified cases.
Then I need to split AccessControlTest in each related module, we need tests to be part of the module it target, will create an AccessControlTestBase if needed.
Generally in a test you don't want to repeat the same protected methods, I put them under DisplayBuilderKernelTestBase, you don't want to have code that is not for the current test, it makes it easier to read and maintain. And if the helper parent implementation change, you have only one place to change it for the tests (like creating entities that are not directly tested in the class).
You want the code in the test method to be focused on the assert and as small as possible.
An other point is you assumed the 'profile' key in the tests, I changed it for the const ConfigFormBuilderInterface::PROFILE_PROPERTY.
You left some empty third arguments in the self::assert methods, it's used to describe the test, it makes it easier to read, I personally don't use it enough but that's good practice.
Comment #37
pdureau commentedoh! sure! 👍
Good to know.
Comment #38
mogtofu33 commentedUpdated the AccessControlTest with more cases, different profile id to avoid collusion.
I added the whole cases for a full matrix:
And view/update/delete assert on instance and profile.
Could you confirm the matrix True/False is ok? If so then I can change it for a dataProvider to have less code.
Comment #39
mogtofu33 commentedThe matrix is ok, I keep working on refactoring tests.
Comment #41
mogtofu33 commented