0

I have generated a custom entity using Drupal Console.

drupal generate:entity:content

The entity doesn't have the permission edit own content which we usually have in node types etc... The entities entity_name.permissions.yml the file has the following enteries.

add company entities:
  title: 'Create new Company entities'

administer company entities:
  title: 'Administer Company entities'
  description: 'Allow to access the administration form to configure Company entities.'
  restrict access: true

delete company entities:
  title: 'Delete Company entities'

edit company entities:
  title: 'Edit Company entities'

access company overview:
  title: 'Access the Company overview page'

view published company entities:
  title: 'View published Company entities'

view unpublished company entities:
  title: 'View unpublished Company entities'

I tried understanding, how this is done in node. But in node types permission file also I couldn't find this permission entered.

  • 1
    The generator is just a starting point. You could just add your own permissions in after the file is generated. You could also just add a permission callback in permissions.yml to dynamically generate permissions too. – Kevin Jul 1 '17 at 18:08
2

If you look at the end of the node permissions file, you'll see:

permission_callbacks:
  - \Drupal\node\NodePermissions::nodeTypePermissions

If you look at the buildPermissions method, you'll see where the rest of the node permissions are created.

And then in node.module, take a look at node_node_access implementation of hook_node_access.

Also, see: \Drupal\node\NodeAccessControlHandler and the corresponding Interface class. It seems fairly complex, but both the node_node_access method and the NodeAccessControlHandlerInterface are well-documented and seem like a good place to start for developing your custom entity permissions system.

2

A little surprised how easy this was to fix; but it seems to be working.

Console originally created permissions similar to what @esefwan posted and in MyEntityAccessConrtolHandler.php it created this code:

  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
    /** @var \Drupal\reserve\Entity\MyEntityInterface $entity */
    switch ($operation) {
      case 'view':
        if (!$entity->isPublished()) {
          return AccessResult::allowedIfHasPermission($account, 'view unpublished myentity');
        }
        return AccessResult::allowedIfHasPermission($account, 'view published myentity');

      case 'update':
        return AccessResult::allowedIfHasPermission($account, 'edit myentity entities');

      case 'delete':
        return AccessResult::allowedIfHasPermission($account, 'delete myentity entities');
    }

    // Unknown operation, no opinion.
    return AccessResult::neutral();
  } 

Looking at the code in node.module under node_node_access() i ended up modifying the above to this:

  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
    /** @var \Drupal\reserve\Entity\ReserveReservationInterface $entity */
    switch ($operation) {
      case 'view':
        if (!$entity->isPublished()) {
          $access = AccessResult::allowedIfHasPermission($account, 'view unpublished myentity');
        }
        $access = AccessResult::allowedIfHasPermission($account, 'view published myentity');
        break;

      case 'update':
        $access = AccessResult::allowedIfHasPermission($account, 'edit any myentity');
        if (!$access->isAllowed() && $account->hasPermission('edit own myentity')) {
          $access = $access->orIf(AccessResult::allowedIf($account->id() == $entity->getOwnerId())->cachePerUser()->addCacheableDependency($entity));
        }
        break;

      case 'delete':
        $access =  AccessResult::allowedIfHasPermission($account, 'delete any myentity');
        break;

      // Unknown operation, no opinion.
      default:
        $access = AccessResult::neutral();
    }

    return $access;
  }
  • And did this work for you? Is the code tested? – esafwan Jun 26 at 22:26
  • Been a while now but I think it worked. You could find it in this project: drupal.org/project/reserve – liquidcms Jun 28 at 14:08
1

I'm not sure if Drupal Console has been updated since you asked the question, but what you'll find now is that it defines a set of permissions, but also adds an annotation to the class that defines your entity, something like this:

  handlers = {...
    "access" = "Drupal\my_module\MyModuleAccessControlHandler"
    ...
  }

The AccessControlHandler file will be in your src directory and if you add permissions in the permissions.yml file, you can edit responses to those, using the node_node_access function as an example, as explained in Milos's comment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.