Loading core/modules/jsonapi/src/Access/TemporaryQueryGuard.php +0 −12 Original line number Diff line number Diff line Loading @@ -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() Loading core/modules/jsonapi/src/Hook/JsonapiHooks.php +0 −17 Original line number Diff line number Diff line Loading @@ -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'. */ Loading core/modules/jsonapi/tests/src/Functional/WorkflowTest.php +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ class WorkflowTest extends ConfigEntityResourceTestBase { /** * {@inheritdoc} * * @var \Drupal\shortcut\ShortcutSetInterface * @var \Drupal\workflows\WorkflowInterface */ protected $entity; Loading core/modules/shortcut/src/Hook/ShortcutHooks.php +60 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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()); } } } Loading
core/modules/jsonapi/src/Access/TemporaryQueryGuard.php +0 −12 Original line number Diff line number Diff line Loading @@ -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() Loading
core/modules/jsonapi/src/Hook/JsonapiHooks.php +0 −17 Original line number Diff line number Diff line Loading @@ -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'. */ Loading
core/modules/jsonapi/tests/src/Functional/WorkflowTest.php +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ class WorkflowTest extends ConfigEntityResourceTestBase { /** * {@inheritdoc} * * @var \Drupal\shortcut\ShortcutSetInterface * @var \Drupal\workflows\WorkflowInterface */ protected $entity; Loading
core/modules/shortcut/src/Hook/ShortcutHooks.php +60 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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()); } } }