Commit 627078f1 authored by Karl Shea's avatar Karl Shea Committed by Karl Shea
Browse files

Issue #3189571 by KarlShea: revokeSingleAuthorization removed on authorization

parent eed1ac0c
Loading
Loading
Loading
Loading
+76 −43
Original line number Diff line number Diff line
@@ -9,7 +9,9 @@ use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\group\Entity\Group;
use Drupal\group\Entity\GroupRole;
use Drupal\group\GroupMembershipLoaderInterface;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Using Authorization to assign permissions to Groups.
@@ -30,6 +32,33 @@ class GroupConsumer extends ConsumerPluginBase {
   */
  protected $allowConsumerTargetCreation = FALSE;

  /**
   * The membership loader service.
   *
   * @var \Drupal\group\GroupMembershipLoaderInterface
   */
  protected $membershipLoader;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition, GroupMembershipLoaderInterface $membership_loader) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->membershipLoader = $membership_loader;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('group.membership_loader')
    );
  }

  /**
   * {@inheritdoc}
   */
@@ -80,7 +109,7 @@ class GroupConsumer extends ConsumerPluginBase {
  /**
   * {@inheritdoc}
   */
  public function createConsumerTarget($consumer): void {
  public function createConsumerTarget(string $consumer): void {
    // @todo Implement createConsumerTarget() method.
    // We are not currently allowing auto-recreation of AD groups in Drupal.
    // No work to do.
@@ -101,10 +130,10 @@ class GroupConsumer extends ConsumerPluginBase {
  /**
   * {@inheritdoc}
   */
  public function grantSingleAuthorization(UserInterface $user, $consumer_mapping): void {
    if (!empty($consumer_mapping) && $consumer_mapping !== 'none' && $user->id()) {
  public function grantSingleAuthorization(UserInterface $user, $consumerMapping): void {
    if (!empty($consumerMapping) && $consumerMapping !== 'none' && $user->id()) {

      [$group_id, $role_id] = explode('--', $consumer_mapping);
      [$group_id, $role_id] = explode('--', $consumerMapping);
      $group = Group::load($group_id);
      $role = GroupRole::load($role_id);

@@ -146,37 +175,45 @@ class GroupConsumer extends ConsumerPluginBase {
    }
  }

  public function revokeGrants(UserInterface $user, array $context): void {
    // TODO: Implement revokeGrants() method.
  }

  /**
   * {@inheritdoc}
   */
  public function revokeSingleAuthorization(&$user, $op, $incoming, $consumer_mapping, &$user_auth_data, $user_save = FALSE, $reset = FALSE): void {
    // This method was in the original project, but is not actually defined
    // as part of the authorization interface.  Not sure how this is supposed
    // to be implemented, but leaving it for posterity.
    if (!empty($consumer_mapping) && $consumer_mapping['group'] != 'none') {

      $group_id = explode('--', $consumer_mapping['group'])[0];
      $role_id = explode('--', $consumer_mapping['group'])[1];
      $group = Group::load($group_id);
      $role = GroupRole::load($role_id);
  public function revokeGrants(UserInterface $user, array $context): void {
    // Find the granted groups and roles from the applied grants (context).
    $granted_group_roles = [];
    foreach ($context as $mapping) {
      [$group_id, $role_id] = explode('--', $mapping);
      $granted_group_roles[$group_id][] = $role_id;
    }

    // Load all of the user's memberships.
    $memberships = $this->membershipLoader->loadByUser($user);

    foreach ($memberships as $membership) {
      $group = $membership->getGroup();

      // Wrapped membership content.
      $membershipContent = $membership->getGroupContent();

      if (!isset($granted_group_roles[$group->id()])) {
        // Entire group was removed, so either remove all roles or delete membership.
        if ($this->configuration['delete_membership']) {
          $membershipContent->delete();
        }
        else {
          $membershipContent->set('group_roles', []);
          $membershipContent->save();
        }
      }
      else {
        // The group exists in the grants, so check all of the roles.
        $roles = $membership->getRoles();
        $roles_to_keep = [];

      // Go through all roles that the user has on this group, find the role
      // to remove, remove it and then save the users roles (membership) again.
      $memberships = $group->getContentByEntityId('group_membership', $user->id());
      if (!empty($memberships) && is_array($memberships)) {
        /** @var \Drupal\group\Entity\GroupContent $membership */
        foreach ($memberships as $group_content_id => $membership) {
          $group_roles = $membership->get('group_roles');
          /** @var EntityReferenceItem $group_role */
          foreach ($group_roles as $index => $group_role) {
            if ($group_role->target_id != $role_id) {
              $roles_to_keep[] = ['target_id' => $group_role->target_id];
        foreach ($roles as $role) {
          if (in_array($role->id(), $granted_group_roles[$group->id()])) {
            // Role exists in grants, so keep it.
            $roles_to_keep[] = ['target_id' => $role->id()];
          }
          else {
            $this->messenger()->addStatus($this->t('Your %role role, in the %group group, has been revoked', [
@@ -185,14 +222,10 @@ class GroupConsumer extends ConsumerPluginBase {
            ]));
          }
        }
          $membership->set('group_roles', $roles_to_keep);
          $membership->save();
        }

        // If the user has not more roles in this group, remove membership.
        if (empty($roles_to_keep) && $this->configuration['delete_membership']) {
          $membership->delete();
        }
        // Update the membership's roles.
        $membershipContent->set('group_roles', $roles_to_keep);
        $membershipContent->save();
      }
    }
  }