Loading modules/wse_config/src/EntityAccess.php 0 → 100644 +92 −0 Original line number Diff line number Diff line <?php namespace Drupal\wse_config; use Drupal\Core\Access\AccessResult; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\workspaces\WorkspaceManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Service wrapper for hooks relating to entity access control. * * @internal */ class EntityAccess implements ContainerInjectionInterface { use StringTranslationTrait; /** * The entity type manager service. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The workspace manager service. * * @var \Drupal\workspaces\WorkspaceManagerInterface */ protected $workspaceManager; /** * Constructs a new EntityAccess instance. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager service. * @param \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager * The workspace manager service. */ public function __construct(EntityTypeManagerInterface $entity_type_manager, WorkspaceManagerInterface $workspace_manager) { $this->entityTypeManager = $entity_type_manager; $this->workspaceManager = $workspace_manager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('workspaces.manager') ); } /** * Implements a hook bridge for hook_entity_access(). * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to check access for. * @param string $operation * The operation being performed. * @param \Drupal\Core\Session\AccountInterface $account * The user account making the to check access for. * * @return \Drupal\Core\Access\AccessResult * The result of the access check. * * @see hook_entity_access() */ public function entityOperationAccess(EntityInterface $entity, $operation, AccountInterface $account) { // We only need to act here if we're dealing with a config entity. if ($operation != 'delete' || !($entity instanceof ConfigEntityInterface) || !$this->workspaceManager->hasActiveWorkspace()) { return AccessResult::neutral(); } $result = $this->entityTypeManager->getStorage('wse_config')->getQuery() ->condition('workspace', $this->workspaceManager->getActiveWorkspace()->id()) ->condition('name', [$entity->getConfigDependencyName()], 'IN') ->execute(); if ($result) { return AccessResult::allowedIfHasPermission($account, 'delete wse_config'); } return AccessResult::forbidden(); } } modules/wse_config/wse_config.module +16 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,9 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\views\Form\ViewsForm; use Drupal\views_ui\Form\Ajax\ViewsFormBase; use Drupal\views_ui\ViewFormBase; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\wse_config\EntityAccess; /** * Implements hook_entity_type_alter(). Loading Loading @@ -85,3 +88,16 @@ function wse_config_form_alter(array &$form, FormStateInterface $form_state, $fo $form_state->set('workspace_safe', TRUE); } } /** * Implements hook_entity_access(). * * @todo Support deleting of config that is active in live. The implementation * here will disallow deletion of config entities, which are active in live, * inside a workspace. */ function wse_config_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { return \Drupal::service('class_resolver') ->getInstanceFromDefinition(EntityAccess::class) ->entityOperationAccess($entity, $operation, $account); } Loading
modules/wse_config/src/EntityAccess.php 0 → 100644 +92 −0 Original line number Diff line number Diff line <?php namespace Drupal\wse_config; use Drupal\Core\Access\AccessResult; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\workspaces\WorkspaceManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Service wrapper for hooks relating to entity access control. * * @internal */ class EntityAccess implements ContainerInjectionInterface { use StringTranslationTrait; /** * The entity type manager service. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The workspace manager service. * * @var \Drupal\workspaces\WorkspaceManagerInterface */ protected $workspaceManager; /** * Constructs a new EntityAccess instance. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager service. * @param \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager * The workspace manager service. */ public function __construct(EntityTypeManagerInterface $entity_type_manager, WorkspaceManagerInterface $workspace_manager) { $this->entityTypeManager = $entity_type_manager; $this->workspaceManager = $workspace_manager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('workspaces.manager') ); } /** * Implements a hook bridge for hook_entity_access(). * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to check access for. * @param string $operation * The operation being performed. * @param \Drupal\Core\Session\AccountInterface $account * The user account making the to check access for. * * @return \Drupal\Core\Access\AccessResult * The result of the access check. * * @see hook_entity_access() */ public function entityOperationAccess(EntityInterface $entity, $operation, AccountInterface $account) { // We only need to act here if we're dealing with a config entity. if ($operation != 'delete' || !($entity instanceof ConfigEntityInterface) || !$this->workspaceManager->hasActiveWorkspace()) { return AccessResult::neutral(); } $result = $this->entityTypeManager->getStorage('wse_config')->getQuery() ->condition('workspace', $this->workspaceManager->getActiveWorkspace()->id()) ->condition('name', [$entity->getConfigDependencyName()], 'IN') ->execute(); if ($result) { return AccessResult::allowedIfHasPermission($account, 'delete wse_config'); } return AccessResult::forbidden(); } }
modules/wse_config/wse_config.module +16 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,9 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\views\Form\ViewsForm; use Drupal\views_ui\Form\Ajax\ViewsFormBase; use Drupal\views_ui\ViewFormBase; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\wse_config\EntityAccess; /** * Implements hook_entity_type_alter(). Loading Loading @@ -85,3 +88,16 @@ function wse_config_form_alter(array &$form, FormStateInterface $form_state, $fo $form_state->set('workspace_safe', TRUE); } } /** * Implements hook_entity_access(). * * @todo Support deleting of config that is active in live. The implementation * here will disallow deletion of config entities, which are active in live, * inside a workspace. */ function wse_config_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { return \Drupal::service('class_resolver') ->getInstanceFromDefinition(EntityAccess::class) ->entityOperationAccess($entity, $operation, $account); }