CommentFileSizeAuthor
#33 entityresource_provide-2843750-33.patch11.54 KBWim Leers
#33 interdiff.txt2.06 KBWim Leers
#30 interdiff.txt1.67 KBAnonymous (not verified)
#30 entityresource_provide-2843750-30.patch10.84 KBAnonymous (not verified)
#28 interdiff.txt1.16 KBAnonymous (not verified)
#28 entityresource_provide-2843750-28.patch10.83 KBAnonymous (not verified)
#26 interdiff-24-26.txt5.03 KBAnonymous (not verified)
#26 interdiff-23-26.txt2.39 KBAnonymous (not verified)
#26 entityresource_provide-2843750-26.patch10.82 KBAnonymous (not verified)
#24 interdiff.txt5.5 KBAnonymous (not verified)
#24 entityresource_provide-2843750-24.patch12.97 KBAnonymous (not verified)
#23 interdiff.txt2.23 KBAnonymous (not verified)
#23 entityresource_provide-2843750-23.patch10.9 KBAnonymous (not verified)
#22 interdiff-words.txt4.8 KBAnonymous (not verified)
#22 interdiff.txt6.05 KBAnonymous (not verified)
#22 entityresource_provide-2843750-22.patch12.02 KBAnonymous (not verified)
#21 interdiff.txt10.54 KBAnonymous (not verified)
#21 entityresource_provide-2843750-21.patch11.76 KBAnonymous (not verified)
#15 interdiff.txt1.34 KBWim Leers
#15 entityresource_provide-2843750-15.patch10.68 KBWim Leers
#12 entityresource_provide-2843750-10.patch10.4 KBsumanthkumarc
#6 entityresource_provide-2843750-6.patch9.14 KBsumanthkumarc
#4 entityresource_provide-2843750-4.patch8.85 KBsumanthkumarc
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

naveenvalecha created an issue. See original summary.

sumanthkumarc’s picture

Assigned: Unassigned » sumanthkumarc
sumanthkumarc’s picture

Issue tags: +SprintWeekend2017
sumanthkumarc’s picture

Status: Active » Needs review
FileSize
8.85 KB

Took the help of https://www.drupal.org/node/2832859 MenuLinkContent entity and putting up a patch. If this works, planning on patches for other entities as well.

Status: Needs review » Needs work

The last submitted patch, 4: entityresource_provide-2843750-4.patch, failed testing.

sumanthkumarc’s picture

sumanthkumarc’s picture

Status: Needs work » Needs review

Resolved a silly error. NR to trigger test.

dawehner’s picture

Status: Needs review » Needs work
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutResourceTestBase.php
@@ -0,0 +1,132 @@
+  protected function setUpAuthorization($method) {
+	switch ($method) {
+	  case 'GET':
+		$this->grantPermissionsToTestedRole(['access shortcuts']);
+		break;
+	  case 'POST':
+	  case 'PATCH':
+	  case 'DELETE':
+		$this->grantPermissionsToTestedRole(['administer shortcuts']);
...
+	$shortcut = Shortcut::create(array(
+	  'shortcut_set' => 'default',
+	  'title' => t('Comments'),
+	  'weight' => -20,
+	  'link' => array(
+		'uri' => 'internal:/admin/content/comment',
+	  ),
+	));

Please convert that to spaces, sorry :(

sumanthkumarc’s picture

@dawehner will remove.

Need help in resolving following.

1) Drupal\Tests\hal\Functional\EntityResource\Shortcut\ShortcutHalJsonAnonTest::testGet
Failed asserting that 403 is identical to 200.

2) Drupal\Tests\hal\Functional\EntityResource\Shortcut\ShortcutHalJsonAnonTest::testPost
Failed asserting that 400 is identical to 403.

3) Drupal\Tests\hal\Functional\EntityResource\Shortcut\ShortcutHalJsonAnonTest::testPatch
Failed asserting that 400 is identical to 403.

should i catch error and assert this??

sumanthkumarc’s picture

Version: 8.2.x-dev » 8.3.x-dev
sumanthkumarc’s picture

sumanthkumarc’s picture

sumanthkumarc’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 12: entityresource_provide-2843750-10.patch, failed testing.

Wim Leers’s picture

Please provide interdiffs in the future. Otherwise it's impossible to review differences between previous versions of the patch. For example, it's very hard to tell what changed between #6 and #12. See https://www.drupal.org/documentation/git/interdiff.


The problems you ran into in #9 are all due to bugs:

  1. Not all necessary permissions are granted: users also need the customize shortcut links permission.
  2. ShortcutResourceTestBase::getNormalizedPostEntity() is wrong in two significant ways: it's not sending a bundle (this was causing the 400), plus it's sending a non-existing name field, which should be the title field.
  3. Same root cause as 2.

I fixed just those problems. This patch will still come back red, because there are more problems to solve. But at least you can now continue :)

Finally: you're still using that work-around trait, which means this is 8.2.x-specific. This likely won't get committed to 8.2.x anymore, since 8.4.x was just branched. So, it's best to just remove that altogether.

Back to you, @sumanthkumarc!

Status: Needs review » Needs work

The last submitted patch, 15: entityresource_provide-2843750-15.patch, failed testing.

sumanthkumarc’s picture

@wimleers Thanks. This is my first time in writing tests and learned a lot already. Also, Thanks for the help there.

I'll provide a new patch and interdiff with above points. :)

Wim Leers’s picture

Great, thanks!

himanshu-dixit’s picture

@sumanthkumarc Any progress on this? Do you mind if i take a shot at this?

sumanthkumarc’s picture

Assigned: sumanthkumarc » Unassigned

@himanshu-dixit sure, i'm just busy for sometime. Unassigning myself.

Anonymous’s picture

Status: Needs work » Needs review
FileSize
11.76 KB
10.54 KB

We have #2339903: Shortcut module's access checking is insane and this prevents the output of pretty reason-messages :(.

Also we have issue with a lot of work on refactoring #2083123: Shortcut cleanup: Remove duplicated code and deprecate legacy functions, but unfortunately it does not contain the necessary changes too. I can reroll that issue, but may be better first commit current issue to get better test coverage?

Bit change to get the reasons:

+++ b/core/modules/shortcut/shortcut.module
@@ -65,7 +65,10 @@ function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL) {
   // Sufficiently-privileged users can edit their currently displayed shortcut
   // set, but not other sets. They must also be able to access shortcuts.
   $may_edit_current_shortcut_set = $account->hasPermission('customize shortcut links') && (!isset($shortcut_set) || $shortcut_set == shortcut_current_displayed_set()) && $account->hasPermission('access shortcuts');
-  return AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions();
+  if (!$may_edit_current_shortcut_set) {    
+    return AccessResult::neutral("The 'access shortcuts, customize shortcut links' permissions is required.")->cachePerPermissions();
+  }
+  return AccessResult::allowed()->cachePerPermissions();

Also patch have:

+++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutResourceTestBase.php
@@ -123,11 +131,30 @@ protected function getNormalizedPostEntity() {
     ],
     'link' => [
     [
-      'uri' => 'internal:/admin/content/comment',
+      'uri' => 'internal:/', # 'internal:/', 'route:<front>', 'route:<test>', ...?

I'm not sure with this, but without it there is a fall:

# EntityResourceTestBase.php:692
Failed asserting that two strings are identical.
Expected :{"message":"Unprocessable Entity: validation failed.\ntitle: Name: this field cannot hold more than 1 values.\n"}
Actual   :{"message":"Unprocessable Entity: validation failed.\ntitle: Name: this field cannot hold more than 1 values.\nlink: This value should not be null.\n"}

# or
Actual   :{"message":"Unprocessable Entity: validation failed.\ntitle: Name: this field cannot hold more than 1 values.\nlink.0: The path \u0027internal:\/admin\/content\/comment\u0027 is inaccessible.\n"}

# or
Actual   :{"message":"Unprocessable Entity: validation failed.\ntitle: Name: this field cannot hold more than 1 values.\nlink.0: The path \u0027https:\/\/nl.wikipedia.org\/wiki\/Llama\u0027 is invalid.\n"}

PS. I did not touch the indentations in the code, to better view the changes. But I'll do it in the future with --diff-word

Anonymous’s picture

Anonymous’s picture

bit cleanup short array + separete issue for cheat with assertSame/assertEquals #2859875: Use assertEquals instead of assertSame in EntityResourceTestBase :)

Anonymous’s picture

+++ b/core/modules/shortcut/shortcut.module
@@ -65,7 +65,10 @@ function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL) {
+  if (!$may_edit_current_shortcut_set) {    ¶

line adds whitespace errors :(

Review changes in new patch:

+++ b/core/modules/rest/tests/src/Functional/EntityResource/Shortcut/ShortcutResourceTestBase.php
@@ -39,12 +39,10 @@  protected function setUpAuthorization($method) {
     switch ($method) {
       case 'GET':
-        $this->grantPermissionsToTestedRole(['access shortcuts', 'customize shortcut links']);
-        break;
       case 'POST':
       case 'PATCH':
       case 'DELETE':
-        $this->grantPermissionsToTestedRole(['administer shortcuts']);
+        $this->grantPermissionsToTestedRole(['access shortcuts', 'customize shortcut links']);

It looks like the tests are passing without 'administer shortcuts' permission, I do not know how good this news?

+++ b/core/modules/shortcut/shortcut.module
@@ -65,10 +65,7 @@ function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL) {
...
-  if (!$may_edit_current_shortcut_set) {    
-    return AccessResult::neutral("The 'access shortcuts, customize shortcut links' permissions is required.")->cachePerPermissions();
-  }
-  return AccessResult::allowed()->cachePerPermissions();
+  return AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions();

Return to original code, now changed only ShortcutAccessControlHandler.

+++ b/core/modules/shortcut/src/ShortcutAccessControlHandler.php
   protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
     if ($shortcut_set = $this->shortcutSetStorage->load($entity->bundle())) {
-      return shortcut_set_edit_access($shortcut_set, $account);
+      $access = shortcut_set_edit_access($shortcut_set, $account);
+      if ($access->isNeutral()) {
+        $message = sprintf("The 'access shortcuts' AND 'customize shortcut links' permissions is required to %s this shortcut entity of bundle %s.", $operation, $entity->bundle());
+        $access = AccessResult::neutral($message)->cachePerPermissions()->addCacheableDependency($shortcut_set);
+      }
+      return $access;
     }

Additional access processing. The reason includes the $operation. But we can not distinguish 'update' from 'view' operation without the next change:

+++ b/core/modules/shortcut/shortcut.routing.yml
@@ -58,9 +58,9 @@ entity.shortcut.canonical:
   path: '/admin/config/user-interface/shortcut/link/{shortcut}'
   defaults:
     _entity_form: 'shortcut.default'
-    _title: 'Edit'
+    _title: 'View'
   requirements:
-    _entity_access: 'shortcut.update'
+    _entity_access: 'shortcut.view'
     shortcut: \d+

Looks like just typo, no?

And we have test cover this change via

@@ -148,10 +146,13 @@ protected function getExpectedUnauthorizedAccessMessage($method) {
...
     switch ($method) {
       case 'GET':
+        return "The 'access shortcuts' AND 'customize shortcut links' permissions is required to view this shortcut entity of bundle default.";
Wim Leers’s picture

Status: Needs review » Needs work

It looks like the tests are passing without 'administer shortcuts' permission, I do not know how good this news?

That's how \Drupal\shortcut\ShortcutAccessControlHandler (well, \shortcut_set_edit_access()) is designed to work. So this is fine.


  1. +++ b/core/modules/shortcut/shortcut.routing.yml
    @@ -58,9 +58,9 @@ entity.shortcut.canonical:
       path: '/admin/config/user-interface/shortcut/link/{shortcut}'
       defaults:
         _entity_form: 'shortcut.default'
    -    _title: 'Edit'
    +    _title: 'View'
       requirements:
    -    _entity_access: 'shortcut.update'
    +    _entity_access: 'shortcut.view'
         shortcut: \d+
    

    Why would we be changing this? This is a form to edit a shortcut entity. Requiring view access seems very wrong.

  2. +++ b/core/modules/shortcut/src/ShortcutAccessControlHandler.php
    @@ -52,7 +52,12 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
    +      if ($access->isNeutral()) {
    +        $message = sprintf("The 'access shortcuts' AND 'customize shortcut links' permissions is required to %s this shortcut entity of bundle %s.", $operation, $entity->bundle());
    +        $access = AccessResult::neutral($message)->cachePerPermissions()->addCacheableDependency($shortcut_set);
    +      }
    
    @@ -64,7 +69,11 @@ protected function checkAccess(EntityInterface $entity, $operation, AccountInter
    +      if ($access->isNeutral()) {
    +        $access = AccessResult::neutral("The 'access shortcuts' AND 'customize shortcut links' permissions is required to create this shortcut entity of bundle $entity_bundle.")->cachePerPermissions()->addCacheableDependency($shortcut_set);
    +      }
    

    Why not move this logic directly into shortcut_set_edit_access()?

Anonymous’s picture

Status: Needs work » Needs review
FileSize
10.82 KB
2.39 KB
5.03 KB

Ok, back to #23 and nit cleanup.

#25:

Why would we be changing this? This is a form to edit a shortcut entity. Requiring view access seems very wrong.

An interesting moment, looks like we have one path to canonical and edit_form:

entity.shortcut.canonical:
  path: '/admin/config/user-interface/shortcut/link/{shortcut}'
...
entity.shortcut.edit_form:
  path: '/admin/config/user-interface/shortcut/link/{shortcut}'

And without change entity.shortcut.canonical we have 'update' $operation when we need 'view' in checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
Hence next fail:

# EntityResourceTestBase.php:325
Failed asserting that two strings are identical.
Expected :{"message":"The 'access shortcuts' AND 'customize shortcut links' permissions is required to view this shortcut entity of bundle default."}
Actual   :{"message":"The 'access shortcuts' AND 'customize shortcut links' permissions is required to update this shortcut entity of bundle default."}
Why not move this logic directly into shortcut_set_edit_access()?

shortcut_set_edit_access() hasn't info about current operations ('view', 'create', 'update', 'delete').

And one more thing, it takes only one argument
function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL)
But we call it form ShortcutAccessControlHandler with two arguments :)

protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
  ...
  shortcut_set_edit_access($shortcut_set, $account);


protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
  ...
  shortcut_set_edit_access($shortcut_set, $account);
Wim Leers’s picture

Status: Needs review » Reviewed & tested by the community

Yes, the Shortcut module is a mess. Not something we need to solve here though :)

This patch is perfect now! 99% test coverage. 1% surgical modification to shortcut module.


+++ b/core/modules/shortcut/shortcut.module
@@ -65,7 +65,10 @@ function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL) {
+  if (!$may_edit_current_shortcut_set) {
+    return AccessResult::neutral("The 'access shortcuts' AND 'customize shortcut links' permissions is required.")->cachePerPermissions();
+  }
+  return AccessResult::allowed()->cachePerPermissions();

This is fine!

However, if the committer doesn't like this, it could be changed to this alternative:

$result =  AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions();
if (!$result->isAllowed()) {
  $result->setReason(…);
}
return $result;

Thanks! :)

Anonymous’s picture

Nice hint, now surgical modification looks really perfect!

Wim Leers’s picture

Thanks, great work @vaplas! :)

Anonymous’s picture

Wim Leers’s picture

Looks great!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/shortcut/shortcut.module
@@ -65,7 +65,11 @@ function shortcut_set_edit_access(ShortcutSetInterface $shortcut_set = NULL) {
   // Sufficiently-privileged users can edit their currently displayed shortcut
   // set, but not other sets. They must also be able to access shortcuts.
   $may_edit_current_shortcut_set = $account->hasPermission('customize shortcut links') && (!isset($shortcut_set) || $shortcut_set == shortcut_current_displayed_set()) && $account->hasPermission('access shortcuts');
-  return AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions();
+  $result = AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions();
+  if (!$result->isAllowed()) {
+    $result->setReason("The 'access shortcuts' AND 'customize shortcut links' permissions is required.");
+  }
+  return $result;

The words here are not the same as the logic defining $may_edit_current_shortcut_set. There is something about it being the currently displayed set too. This also makes me wonder if the we should also be doing ->addCacheableDependency($shortcut_set) if the shortcut_set is provided. The caching is out-of-scope here but should have a separate issue to discuss. What is in scope is this message. I'm not sure of what it should be but I know it needs to correctly describe the logic... which is described by:

  // Sufficiently-privileged users can edit their currently displayed shortcut
  // set, but not other sets. They must also be able to access shortcuts.

So maybe something like:
"The shortcut set must be the currently displayed set for the user and the user must have 'access shortcuts' AND 'customize shortcut links' permissions."

Not sure.

Wim Leers’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
2.06 KB
11.54 KB

Good catch!

I forgot for a moment that unfortunately the "reason" message for denying access must reflect the actual complexity of the access checking, regardless of how insane it is (yes, I think shortcut access checking is insane, and I think most would agree).

I think your proposal makes sense. It's complex and confusing, but again… that is only because the access checking is complex and confusing. We must convey all information/requirements, otherwise the "reason" still is incomplete.

Thanks for your diligence.

Wim Leers’s picture

@alexpott pointed out in IRC that we actually want/need addCacheableDependency() in shortcut_set_edit_access(). But fixing that is out of scope here.

I was fairly certain this problem had been reported before. And in fact… \Drupal\shortcut\ShortcutSetAccessControlHandler::checkAccess() gets it right! So the problem is more that shortcut_set_edit_access() is a pointless/stale/wrong duplicate. We already have #2083123: Shortcut cleanup: Remove duplicated code and deprecate legacy functions to fix that. So the follow-up already exists :)

alexpott’s picture

@Wim Leers so should we be adding the setReason to \Drupal\shortcut\ShortcutSetAccessControlHandler::checkAccess() to avoid surprises when we do deprecate? Not sure.

Wim Leers’s picture

#35: when we remove shortcut_set_edit_access(), we'll get test failures for the test coverage added here, because the expected reason will not be present in the 403 response. So I think it's safe to say we won't forget to move this over.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed e1524ff to 8.4.x and 60f5d00 to 8.3.x. Thanks!

The change to shortcut_set_edit_access() is purely informational so there aren't any BC implications.

  • alexpott committed e1524ff on 8.4.x
    Issue #2843750 by vaplas, sumanthkumarc, Wim Leers: EntityResource:...

  • alexpott committed 60f5d00 on 8.3.x
    Issue #2843750 by vaplas, sumanthkumarc, Wim Leers: EntityResource:...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.