Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Giving a user role access to all group content without granting 'administer groups' #213

Open
pfrenssen opened this issue May 27, 2016 · 2 comments

Comments

@pfrenssen
Copy link
Collaborator

In our project we have a "moderator" role which is intended for content managers. These people are allowed to view, edit and delete all group content. Currently the only way to give them access seems to be to give them the "administer groups" permission, but this will also give them the power to create groups, change roles and permissions etc. This is not desirable, they should only have access to group content.

I tried to implement this but hit a number of problems:

  1. Looking at OgAccess::userAccessEntity() there is no alter hook here to modify the access rules for group content. At a certain point the groups are retrieved and OgAccess::userAccess() is called which has an alter hook, but this is on group level, not on group content level. Giving the user access here would also give access to modify the groups themselves, not only the group content. We can live with this for the moment, but would need to address this before going into production.
  2. If I implement the hook in OgAccess::userAccess() then I can still not give access. This is my hook implementation:
function joinup_og_user_access_alter(&$permissions, &$cacheable_metadata, $context) {
  // Moderators should have access to edit and delete all group content in
  // collections.
  /** @var \Drupal\Core\Session\AccountProxyInterface $user */
  $user = $context['user'];
  $operation = $context['operation'];
  $group = $context['group'];

  $is_moderator = in_array('moderator', $user->getRoles());
  $is_collection = $group->bundle() === 'collection';
  $operation_allowed = in_array($operation, ['create', 'update', 'delete']);

  if ($is_moderator && $is_collection && $operation_allowed) {
    $permissions[] = $operation;
  }
}

So far so good, OgAccess::userAccess() now returns AccessResult::allowed(), but this is now trumped in og_entity_access():

function og_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
  // ...

  // Our user does not have 'administer group', so this is FORBIDDEN.
  $access = OgAccess::userAccessEntity('administer group', $entity, $account);

  if ($access->isNeutral()) {
    return $access;
  }
  else {
    // Code path enters here. userAccessEntity() returns ALLOWED, but doing
    // an orIf() will return FORBIDDEN if any of the two are forbidden. So no access :( 
    $access = $access->orIf(OgAccess::userAccessEntity($operation, $entity, $account));
  }

  // ...
}

So it looks like userAccessEntity('administer group', $entity, $account) should return NEUTRAL, unless it expressly forbids access.

@pfrenssen
Copy link
Collaborator Author

Hmm actually calling userAccessEntity() with the operation 'administer group' seems nonsensical, the only entity operations that exist are 'create', 'update', 'delete' and 'view'.

@pfrenssen
Copy link
Collaborator Author

I have a proposed fix for problem 2 in PR #214.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant