Verified Commit b4c833bf authored by Andrei Mateescu's avatar Andrei Mateescu
Browse files

task: #3581817 Move uses of Shortcut from Jsonapi to Shortcut

By: sourav_paul
By: smustgrave
By: quietone
By: longwave
By: amateescu
parent 860e7433
Loading
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -290,18 +290,6 @@ protected static function getAccessCondition($entity_type_id, CacheableMetadata
        $cacheability->addCacheTags($entity_type->getListCacheTags());
        break;

      case 'shortcut':
        // Unless the user can administer shortcuts, allow access only to the
        // user's currently displayed shortcut set.
        // @see \Drupal\shortcut\ShortcutAccessControlHandler::checkAccess()
        if (!$current_user->hasPermission('administer shortcuts')) {
          $shortcut_set_storage = \Drupal::entityTypeManager()->getStorage('shortcut_set');
          $specific_condition = new EntityCondition('shortcut_set', $shortcut_set_storage->getDisplayedToUser($current_user)->id());
          $cacheability->addCacheContexts(['user']);
          $cacheability->addCacheTags($entity_type->getListCacheTags());
        }
        break;

      case 'user':
        // Disallow querying values of the anonymous user.
        // @see \Drupal\user\UserAccessControlHandler::checkAccess()
+0 −17
Original line number Diff line number Diff line
@@ -212,23 +212,6 @@ public function jsonapiNodeFilterAccess(EntityTypeInterface $entity_type, Accoun
    ];
  }

  /**
   * Implements hook_jsonapi_ENTITY_TYPE_filter_access() for 'shortcut'.
   */
  #[Hook('jsonapi_shortcut_filter_access')]
  public function jsonapiShortcutFilterAccess(EntityTypeInterface $entity_type, AccountInterface $account): array {
    // @see \Drupal\shortcut\ShortcutAccessControlHandler::checkAccess()
    // \Drupal\jsonapi\Access\TemporaryQueryGuard adds the condition for
    // "shortcut_set = $shortcut_set_storage->getDisplayedToUser($current_user)"
    // so this does not have to.
    return [
      JsonApiFilter::AMONG_ALL => AccessResult::allowedIfHasPermission($account, 'administer shortcuts')->orIf(AccessResult::allowedIfHasPermissions($account, [
        'access shortcuts',
        'customize shortcut links',
      ])),
    ];
  }

  /**
   * Implements hook_jsonapi_ENTITY_TYPE_filter_access() for 'taxonomy_term'.
   */
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ class WorkflowTest extends ConfigEntityResourceTestBase {
  /**
   * {@inheritdoc}
   *
   * @var \Drupal\shortcut\ShortcutSetInterface
   * @var \Drupal\workflows\WorkflowInterface
   */
  protected $entity;

+60 −0
Original line number Diff line number Diff line
@@ -2,11 +2,17 @@

namespace Drupal\shortcut\Hook;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\jsonapi\JsonApiFilter;

/**
 * Hook implementations for shortcut.
@@ -137,4 +143,58 @@ public function userDelete(EntityInterface $entity): void {
    \Drupal::entityTypeManager()->getStorage('shortcut_set')->unassignUser($entity);
  }

  /**
   * Implements hook_jsonapi_ENTITY_TYPE_filter_access() for 'shortcut'.
   */
  #[Hook('jsonapi_shortcut_filter_access')]
  public function jsonapiShortcutFilterAccess(EntityTypeInterface $entity_type, AccountInterface $account): array {
    // @see \Drupal\shortcut\ShortcutAccessControlHandler::checkAccess()
    // queryShortcutAccessAlter() narrows results to only shortcuts in the
    // user's currently displayed shortcut set for non-administrators.
    return [
      JsonApiFilter::AMONG_ALL => AccessResult::allowedIfHasPermission($account, 'administer shortcuts')->orIf(AccessResult::allowedIfHasPermissions($account, [
        'access shortcuts',
        'customize shortcut links',
      ]))->addCacheContexts(['user']),
    ];
  }

  /**
   * Implements hook_query_TAG_alter() for 'shortcut_access'.
   *
   * Unless the user can administer shortcuts, restricts queries to only return
   * shortcuts from the user's currently displayed shortcut set.
   *
   * @see \Drupal\shortcut\ShortcutAccessControlHandler::checkAccess()
   */
  #[Hook('query_shortcut_access_alter')]
  public function queryShortcutAccessAlter(AlterableInterface $query): void {
    $account = $query->getMetaData('account') ?: \Drupal::currentUser();

    // Administrators can access all shortcuts.
    if ($account->hasPermission('administer shortcuts')) {
      return;
    }

    // Non-administrators can only access shortcuts in their displayed set.
    $shortcut_set = \Drupal::entityTypeManager()
      ->getStorage('shortcut_set')
      ->getDisplayedToUser($account);

    $tables = $query->getTables();
    $base_table = $query->getMetaData('base_table');
    if (!$base_table) {
      foreach ($tables as $table_info) {
        if (!$table_info instanceof SelectInterface && $table_info['table'] === 'shortcut_field_data') {
          $base_table = $table_info['alias'];
          break;
        }
      }
    }

    if ($base_table) {
      $query->condition("$base_table.shortcut_set", $shortcut_set->id());
    }
  }

}