Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
When logged in as any user with the 'link to any page' permission, the unmasquerade link in the user account menu is visible even if not masquerading. The current method of applying an access check (_user_is_masquerading) to the route works for users that have not been granted the 'link to any page' permission. (@see \Drupal\Core\Menu\DefaultMenuLinkManipulators::menuLinkCheckAccess).
Comment | File | Size | Author |
---|---|---|---|
#32 | 2695779-32.patch | 1.81 KB | mglaman |
#28 | 2695779-28.patch | 3.13 KB | mglaman |
#18 | unmasquerade_link-2695779-17.patch | 2.85 KB | imot3k |
Comments
Comment #2
coderdan CreditAttribution: coderdan at Phase2 commentedComment #3
coderdan CreditAttribution: coderdan at Phase2 commentedComment #6
andypostComment #7
steveoriolPatch #2 works for me on D8.3.2, thanks.
Comment #8
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedI think we should check a route name (masquerade.unmasquerade) here rather than the index. This way, we could remove all custom menu links (if there are any) as well.
Providing a patch with the mentioned change.
Comment #9
andypostNice trick but it needs clean-up and a kind of container param to enable (or somehow other way to configure)
@file should be removed
Use `\Drupal::` as inline
MasqueradeMenuLinkTree::class
Looks it need to be regenerated to remove "@file" header
Comment #10
mbovan CreditAttribution: mbovan at MD Systems GmbH commentedAddressed feedback from #9 and fixed code style issues.
Comment #11
DuneBLI confirm that the patch #10 solve this issue on 8.4
Many thanks!!
Comment #12
abu-zakham CreditAttribution: abu-zakham as a volunteer and at Vardot commentedAlso I confirm that the patch #10 solve this issue.
Thanks.
Comment #13
andypostThis approach works but is very hackish cos overrides default core behavior so will not be commited until core decide a way ahead
Comment #14
msajko CreditAttribution: msajko at Websolutions Agency commentedDifferent approach for this issue.
Comment #16
msajko CreditAttribution: msajko at Websolutions Agency commentedFixed new approach: menu link enabled/disabled
Comment #18
imot3k CreditAttribution: imot3k commentedThis patch fixes the following error:
Exception: Error: Class 'Drupal\masquerade\Plugin\Menu\Drupal' not found
Drupal\masquerade\Plugin\Menu\UnmasqueradeMenuLink::create()() (Line: 46)
Comment #19
wturrell CreditAttribution: wturrell commented(Patch #17 working for me.)
Comment #20
slashrsm CreditAttribution: slashrsm at Tag1 Consulting commentedI can also confirm that the patch works as expected and also the implementation looks sensible.
Comment #21
andypostYep, looks much better now but require test coverage
Comment #22
slashrsm CreditAttribution: slashrsm at Tag1 Consulting commentedI think that there is a cache issue with the current patch. To repoduce:
- Make sure caches are enabled etc.
- Log in as the user you will masquerade as later
- "Unmasquerade" link obvioulsy won't appear in the menu, but its disabled state gets cached
- Now log in as another user and masquerade as the first one
- "Unmasquerade" link is not displayed in the menu but it should be
- Now clear the caches and reload the page
- "Unmasquerade" link will appear.
Comment #23
wturrell CreditAttribution: wturrell commentedI can reproduce @slashrsm's bug in #22.
Have looked at code, but nothing is jumping out at me.
(Unrelated novice cache context question – given UnmasqueradeMenuLink::getCacheContexts() returns one context only 'session.is_masquerading' - what happens if more than one user is masquerading at the same time?)
Comment #24
andypost@wturrell
'session.
context prefix means that this link varies per user's session flagComment #25
DanChadwick CreditAttribution: DanChadwick commentedThe root of this problem is that the menu links don't respect route access for user 1. Personally, I'd say this is a core bug, but I need to work around this in my module for several items that the administrator should not see. Unmasquerade is one of these, since I don't allow users to masquerade as administrators (including user 1).
Using #17 as inspiration, I am simply adding this class in MYMODULE.links.menu.yml to any route that should not be visible to user 1.
This would need a little adapting for masquerade. Specifically, the menu should be enabled if
uid != 1 || $is_masquerading
.Note that you can continue to use the yml for the title and description, and that there is no reason to override the constructor to save the masquerading status since it is never used. I am not getting caching problems with the context I'm using above and unless uid 1 can masquerade as uid 1 (and I don't think you can masquerade as yourself), I would think that context would work for masquerade.
I'm new to D8, so I may be wrong here. Thanks for the great module. I've been using the D7 version for years.
Comment #26
hudriI'm running v2.0@beta, and I can confirm the cache bug of #22 - WITHOUT any patches from here installed.
Comment #27
mglamanAdding a menu link plugin patch, shortly. The problem is you cannot alter the definition in the constructor as it'll become serialized that way.
Comment #28
mglamanModified a test to show `Unmasquerade` should not show unless you are masquerading.
Comment #29
andypostThank you for patch! Looks nice workaround
Minor nit is missing class description with todo reference to core issue about permission
Comment #30
mglaman👍 thanks, @andypost. I'll make a follow up later. And I will actually run the tests locally and fix the failure.
Comment #31
mglamanOkay, so in my testing, locally:
`masquerade as super user` is broken, somehow, with this patch.
---
So this patch just uncovered that the tests have been false-positive on masquerading as a root user. The page has "You are not authorized to access this page.", which means that never worked.
---
Edit 2: you always see access denied on /masquerade after submitting the form 🤷♂️
Comment #32
mglamanI can't figure out why masquerading as uid1 breaks the menu link. I've tried everything in the tests. Even using messenger::addStatus in isEnabled. It just doesn't even run when switching to uid1.
Comment #33
andypostLooks it needs to fix related first
Comment #34
claudiu.cristeaThis is more a workaround. We should focus on the core issue that, magically, fixes also this issue. Closing as duplicate of #2463753: [regression] Do not bypass route access with 'link to any page' permissions for menu links.
Comment #35
steveoriolI confirm that patch on "https://www.drupal.org/project/drupal/issues/2463753" fix the issue on D9.3.6