Loading group.services.yml +4 −0 Original line number Diff line number Diff line Loading @@ -156,6 +156,10 @@ services: shared: false # Specific group relation handlers. group.relation_handler.access_control.group_membership: class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipAccessControl' arguments: ['@group.relation_handler.access_control'] shared: false group.relation_handler.entity_reference.group_membership: class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipEntityReference' arguments: ['@group.relation_handler.entity_reference'] Loading src/Plugin/Group/RelationHandler/EmptyAccessControl.php +0 −5 Original line number Diff line number Diff line Loading @@ -2,11 +2,6 @@ namespace Drupal\group\Plugin\Group\RelationHandler; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\group\Entity\GroupRelationshipInterface; use Drupal\group\Entity\GroupInterface; /** * Provides a default access control handler. * Loading src/Plugin/Group/RelationHandler/GroupMembershipAccessControl.php 0 → 100644 +35 −0 Original line number Diff line number Diff line <?php namespace Drupal\group\Plugin\Group\RelationHandler; /** * Checks access for the group_membership relation plugin. */ class GroupMembershipAccessControl implements AccessControlInterface { use AccessControlTrait; /** * Constructs a new GroupMembershipAccessControl. * * @param \Drupal\group\Plugin\Group\RelationHandler\AccessControlInterface $parent * The parent access control handler. */ public function __construct(AccessControlInterface $parent) { $this->parent = $parent; } /** * {@inheritdoc} */ public function supportsOperation($operation, $target) { // While we don't have a dedicated permission for creating a relationship, // as you either need the 'join group' permission to join yourself or full // member admin rights to add other people, we do actually support it. if ($operation === 'create' && $target === 'relationship') { return TRUE; } return $this->parent->supportsOperation($operation, $target); } } src/Plugin/Group/RelationHandlerDefault/AccessControl.php +25 −4 Original line number Diff line number Diff line Loading @@ -54,11 +54,32 @@ class AccessControl implements AccessControlInterface { return FALSE; } /** * Checks operation support across the entire decorator chain. * * Instead of checking whether this specific access control handler supports * the operation, we check the entire decorator chain. This avoids a lot of * copy-pasted code to manually support an operation in a decorator further * down the chain. * * @param string $operation * The permission operation. Usually "create", "view", "update" or "delete". * @param string $target * The target of the operation. Can be 'relationship' or 'entity'. * * @return bool * Whether the operation is supported. */ protected function chainSupportsOperation($operation, $target) { $access_control_chain = $this->groupRelationTypeManager()->getAccessControlHandler($this->pluginId); return $access_control_chain->supportsOperation($operation, $target); } /** * {@inheritdoc} */ public function relationshipAccess(GroupRelationshipInterface $group_relationship, $operation, AccountInterface $account, $return_as_object = FALSE) { if (!$this->supportsOperation($operation, 'relationship')) { if (!$this->chainSupportsOperation($operation, 'relationship')) { return $return_as_object ? AccessResult::neutral() : FALSE; } Loading Loading @@ -97,7 +118,7 @@ class AccessControl implements AccessControlInterface { * {@inheritdoc} */ public function relationshipCreateAccess(GroupInterface $group, AccountInterface $account, $return_as_object = FALSE) { if (!$this->supportsOperation('create', 'relationship')) { if (!$this->chainSupportsOperation('create', 'relationship')) { return $return_as_object ? AccessResult::neutral() : FALSE; } $permission = $this->permissionProvider->getPermission('create', 'relationship'); Loading @@ -124,7 +145,7 @@ class AccessControl implements AccessControlInterface { // operation yet, it's probably nicer to return neutral here. This way, any // module that exposes new operations will work as intended AND NOT HAVE // GROUP ACCESS CHECKS until Group specifically implements said operations. if (!$this->supportsOperation($operation_to_check, 'entity')) { if (!$this->chainSupportsOperation($operation_to_check, 'entity')) { return $return_as_object ? AccessResult::neutral() : FALSE; } Loading Loading @@ -195,7 +216,7 @@ class AccessControl implements AccessControlInterface { * {@inheritdoc} */ public function entityCreateAccess(GroupInterface $group, AccountInterface $account, $return_as_object = FALSE) { if (!$this->supportsOperation('create', 'entity')) { if (!$this->chainSupportsOperation('create', 'entity')) { return $return_as_object ? AccessResult::neutral() : FALSE; } $permission = $this->permissionProvider->getPermission('create', 'entity'); Loading tests/src/Unit/AccessControlTest.php +261 −197 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
group.services.yml +4 −0 Original line number Diff line number Diff line Loading @@ -156,6 +156,10 @@ services: shared: false # Specific group relation handlers. group.relation_handler.access_control.group_membership: class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipAccessControl' arguments: ['@group.relation_handler.access_control'] shared: false group.relation_handler.entity_reference.group_membership: class: 'Drupal\group\Plugin\Group\RelationHandler\GroupMembershipEntityReference' arguments: ['@group.relation_handler.entity_reference'] Loading
src/Plugin/Group/RelationHandler/EmptyAccessControl.php +0 −5 Original line number Diff line number Diff line Loading @@ -2,11 +2,6 @@ namespace Drupal\group\Plugin\Group\RelationHandler; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\group\Entity\GroupRelationshipInterface; use Drupal\group\Entity\GroupInterface; /** * Provides a default access control handler. * Loading
src/Plugin/Group/RelationHandler/GroupMembershipAccessControl.php 0 → 100644 +35 −0 Original line number Diff line number Diff line <?php namespace Drupal\group\Plugin\Group\RelationHandler; /** * Checks access for the group_membership relation plugin. */ class GroupMembershipAccessControl implements AccessControlInterface { use AccessControlTrait; /** * Constructs a new GroupMembershipAccessControl. * * @param \Drupal\group\Plugin\Group\RelationHandler\AccessControlInterface $parent * The parent access control handler. */ public function __construct(AccessControlInterface $parent) { $this->parent = $parent; } /** * {@inheritdoc} */ public function supportsOperation($operation, $target) { // While we don't have a dedicated permission for creating a relationship, // as you either need the 'join group' permission to join yourself or full // member admin rights to add other people, we do actually support it. if ($operation === 'create' && $target === 'relationship') { return TRUE; } return $this->parent->supportsOperation($operation, $target); } }
src/Plugin/Group/RelationHandlerDefault/AccessControl.php +25 −4 Original line number Diff line number Diff line Loading @@ -54,11 +54,32 @@ class AccessControl implements AccessControlInterface { return FALSE; } /** * Checks operation support across the entire decorator chain. * * Instead of checking whether this specific access control handler supports * the operation, we check the entire decorator chain. This avoids a lot of * copy-pasted code to manually support an operation in a decorator further * down the chain. * * @param string $operation * The permission operation. Usually "create", "view", "update" or "delete". * @param string $target * The target of the operation. Can be 'relationship' or 'entity'. * * @return bool * Whether the operation is supported. */ protected function chainSupportsOperation($operation, $target) { $access_control_chain = $this->groupRelationTypeManager()->getAccessControlHandler($this->pluginId); return $access_control_chain->supportsOperation($operation, $target); } /** * {@inheritdoc} */ public function relationshipAccess(GroupRelationshipInterface $group_relationship, $operation, AccountInterface $account, $return_as_object = FALSE) { if (!$this->supportsOperation($operation, 'relationship')) { if (!$this->chainSupportsOperation($operation, 'relationship')) { return $return_as_object ? AccessResult::neutral() : FALSE; } Loading Loading @@ -97,7 +118,7 @@ class AccessControl implements AccessControlInterface { * {@inheritdoc} */ public function relationshipCreateAccess(GroupInterface $group, AccountInterface $account, $return_as_object = FALSE) { if (!$this->supportsOperation('create', 'relationship')) { if (!$this->chainSupportsOperation('create', 'relationship')) { return $return_as_object ? AccessResult::neutral() : FALSE; } $permission = $this->permissionProvider->getPermission('create', 'relationship'); Loading @@ -124,7 +145,7 @@ class AccessControl implements AccessControlInterface { // operation yet, it's probably nicer to return neutral here. This way, any // module that exposes new operations will work as intended AND NOT HAVE // GROUP ACCESS CHECKS until Group specifically implements said operations. if (!$this->supportsOperation($operation_to_check, 'entity')) { if (!$this->chainSupportsOperation($operation_to_check, 'entity')) { return $return_as_object ? AccessResult::neutral() : FALSE; } Loading Loading @@ -195,7 +216,7 @@ class AccessControl implements AccessControlInterface { * {@inheritdoc} */ public function entityCreateAccess(GroupInterface $group, AccountInterface $account, $return_as_object = FALSE) { if (!$this->supportsOperation('create', 'entity')) { if (!$this->chainSupportsOperation('create', 'entity')) { return $return_as_object ? AccessResult::neutral() : FALSE; } $permission = $this->permissionProvider->getPermission('create', 'entity'); Loading
tests/src/Unit/AccessControlTest.php +261 −197 File changed.Preview size limit exceeded, changes collapsed. Show changes