Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / modules / workspaces / src / EntityAccess.php
1 <?php
2
3 namespace Drupal\workspaces;
4
5 use Drupal\Core\Access\AccessResult;
6 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
7 use Drupal\Core\Entity\EntityInterface;
8 use Drupal\Core\Entity\EntityTypeManagerInterface;
9 use Drupal\Core\Session\AccountInterface;
10 use Drupal\Core\StringTranslation\StringTranslationTrait;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
12
13 /**
14  * Service wrapper for hooks relating to entity access control.
15  *
16  * @internal
17  */
18 class EntityAccess implements ContainerInjectionInterface {
19
20   use StringTranslationTrait;
21
22   /**
23    * The entity type manager service.
24    *
25    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
26    */
27   protected $entityTypeManager;
28
29   /**
30    * The workspace manager service.
31    *
32    * @var \Drupal\workspaces\WorkspaceManagerInterface
33    */
34   protected $workspaceManager;
35
36   /**
37    * Constructs a new EntityAccess instance.
38    *
39    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
40    *   The entity type manager service.
41    * @param \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager
42    *   The workspace manager service.
43    */
44   public function __construct(EntityTypeManagerInterface $entity_type_manager, WorkspaceManagerInterface $workspace_manager) {
45     $this->entityTypeManager = $entity_type_manager;
46     $this->workspaceManager = $workspace_manager;
47   }
48
49   /**
50    * {@inheritdoc}
51    */
52   public static function create(ContainerInterface $container) {
53     return new static(
54       $container->get('entity_type.manager'),
55       $container->get('workspaces.manager')
56     );
57   }
58
59   /**
60    * Implements a hook bridge for hook_entity_access().
61    *
62    * @param \Drupal\Core\Entity\EntityInterface $entity
63    *   The entity to check access for.
64    * @param string $operation
65    *   The operation being performed.
66    * @param \Drupal\Core\Session\AccountInterface $account
67    *   The user account making the to check access for.
68    *
69    * @return \Drupal\Core\Access\AccessResult
70    *   The result of the access check.
71    *
72    * @see hook_entity_access()
73    */
74   public function entityOperationAccess(EntityInterface $entity, $operation, AccountInterface $account) {
75     // Workspaces themselves are handled by their own access handler and we
76     // should not try to do any access checks for entity types that can not
77     // belong to a workspace.
78     if ($entity->getEntityTypeId() === 'workspace' || !$this->workspaceManager->isEntityTypeSupported($entity->getEntityType())) {
79       return AccessResult::neutral();
80     }
81
82     return $this->bypassAccessResult($account);
83   }
84
85   /**
86    * Implements a hook bridge for hook_entity_create_access().
87    *
88    * @param \Drupal\Core\Session\AccountInterface $account
89    *   The user account making the to check access for.
90    * @param array $context
91    *   The context of the access check.
92    * @param string $entity_bundle
93    *   The bundle of the entity.
94    *
95    * @return \Drupal\Core\Access\AccessResult
96    *   The result of the access check.
97    *
98    * @see hook_entity_create_access()
99    */
100   public function entityCreateAccess(AccountInterface $account, array $context, $entity_bundle) {
101     // Workspaces themselves are handled by their own access handler and we
102     // should not try to do any access checks for entity types that can not
103     // belong to a workspace.
104     $entity_type = $this->entityTypeManager->getDefinition($context['entity_type_id']);
105     if ($entity_type->id() === 'workspace' || !$this->workspaceManager->isEntityTypeSupported($entity_type)) {
106       return AccessResult::neutral();
107     }
108
109     return $this->bypassAccessResult($account);
110   }
111
112   /**
113    * Checks the 'bypass' permissions.
114    *
115    * @param \Drupal\Core\Session\AccountInterface $account
116    *   The user account making the to check access for.
117    *
118    * @return \Drupal\Core\Access\AccessResult
119    *   The result of the access check.
120    */
121   protected function bypassAccessResult(AccountInterface $account) {
122     // This approach assumes that the current "global" active workspace is
123     // correct, i.e. if you're "in" a given workspace then you get ALL THE PERMS
124     // to ALL THE THINGS! That's why this is a dangerous permission.
125     $active_workspace = $this->workspaceManager->getActiveWorkspace();
126
127     return AccessResult::allowedIf($active_workspace->getOwnerId() == $account->id())->cachePerUser()->addCacheableDependency($active_workspace)
128       ->andIf(AccessResult::allowedIfHasPermission($account, 'bypass entity access own workspace'));
129   }
130
131 }