Follow-up to #3026897: [META] Centralize all permission calculations/operations

We should only pass around pure value objects of group permissions once the permission building has taken place. In order to do this, we should introduce a new, refinable object that can be used to spawn an immutable object. In order to make sure we can allow these permissions to be properly altered, we should use a tagged service and move the existing implementation into services with said tag as a proof of concept.

Need to update this CR: https://www.drupal.org/node/3035038

Comments

kristiaanvandeneynde created an issue. See original summary.

kristiaanvandeneynde’s picture

Status: Active » Needs review
StatusFileSize
new83.63 KB

This introduces the tagged service, the refinable object, moves logic to services and allows permissions to be altered with said services. Needs a CR to indicate that permissions can now be altered.

kristiaanvandeneynde’s picture

Wow, green on the first try! Now to edit the CR here: https://www.drupal.org/node/3041094

ronaldtebrake’s picture

Nice work!
Functionally tested multiple scenarios all pass very nicely.
- Added new group types
- Changed permissions for roles
- Changed roles on group members

All had the desired effect on the access of the group and it's entities.

A couple of tiny nitpicks but other than that works like a charm.

  1. +++ b/src/Access/DefaultGroupPermissionCalculator.php
    @@ -0,0 +1,144 @@
    +    foreach ($this->membershipLoader->loadByUser($account) as $group_membership) {
    +      $group_id = $group_membership->getGroup()->id();
    +      $permissions = [];
    +
    +      foreach ($group_membership->getRoles() as $group_role) {
    +        $permissions = array_merge($permissions, $group_role->getPermissions());
    +        $calculated_permissions->addCacheableDependency($group_role);
    +      }
    

    We'd be better of not using array_merge in this loop. Using that in a loop could be very costly.

  2. +++ b/src/Access/SynchronizedGroupPermissionCalculator.php
    @@ -0,0 +1,124 @@
    +      if (!empty($group_role_ids)) {
    +        /** @var \Drupal\group\Entity\GroupRoleInterface $group_role */
    +        foreach ($group_role_storage->loadMultiple($group_role_ids) as $group_role) {
    +          $permissions = array_merge($permissions, $group_role->getPermissions());
    +          $calculated_permissions->addCacheableDependency($group_role);
    +        }
    +      }
    

    Similar as the above

  3. +++ b/src/Access/SynchronizedGroupPermissionCalculator.php
    @@ -0,0 +1,124 @@
    +    foreach ($group_type_storage->loadMultiple() as $group_type_id => $group_type) {
    

    $group_type seems to be an unused variable.

Will leave it at needs review for now, can imagine others are keen to test this out as well.

kristiaanvandeneynde’s picture

Thanks for the review! Leaving this open until next week for reviews to come in. I'd also like to clean up the chain calculator because it reuses about 95% the same code 3 times.

kristiaanvandeneynde’s picture

A second pass through the gathered permission to allow for altering might be interesting as well. That would make it easier for people who already want global roles to persist after joining a group (which will be the default in 8.2.0).

kristiaanvandeneynde’s picture

Let's get rid of the half-baked cache context logic and polish up #2551419: Abstract RenderCache into a separate service that is capable of cache redirects in a non-render array-specific way and use it to wrap the cache backends we're using. Then we can simply read out the cache contexts from the calculated permissions, which we'll need to add in the calculators.

kristiaanvandeneynde’s picture

StatusFileSize
new93.09 KB

This does not take into account the suggestions from #4 yet, but simply introduces the new caching system.

kristiaanvandeneynde’s picture

StatusFileSize
new98.86 KB

This takes care of the notes from #4 and adds the most recent VariationCache work from core.

kristiaanvandeneynde’s picture

StatusFileSize
new799 bytes
new98.86 KB

Minor fix, also concerned about the composer error.

Status: Needs review » Needs work

The last submitted patch, 10: group-3041087-10.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jonathanshaw’s picture

D8.8 requires php7? Maybe need to fix the projects drupal-ci yml

kristiaanvandeneynde’s picture

Status: Needs work » Needs review
StatusFileSize
new98.98 KB
new1.84 KB
kristiaanvandeneynde’s picture

@jonathanshaw Thanks. I fixed it by going into my project page's Automated Testing tab and removing some tests there.

kristiaanvandeneynde’s picture

Status: Needs review » Fixed

Fixed, we need this now and simply can't wait for core any longer. Committed with copies of classes that should eventually make it into core.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.