9

I am using Drupal 8 and I am a little bit confused that there is no core functionality to restrict the access to some nodes based on roles or users.

I found PageAccess, which is marked as unsecure and ACL/Access Control which are both dev and not working on my system.

Isn't there any option to do so? I need the private sector on my site and can't believe there is no way in Drupal.

Hope you can help me, because if not I have to redo the whole site with another wcms.

6 Answers 6

4

The Group module is what you should be looking at.

It creates groups as entities, making them fully fieldable, extensible and exportable. For this specific question, you'd enable the gnode submodule, and for each group type you would define the appropriate permissions (view, edit, delete, etc) for the various Content Types.

For the private sector (as in your question), it seems that you would want to grant access to what, in Group, is called "Members". But you wouldn't allow access to that part of the website for:

  • "Outsiders" (= logged in users who are not a member of a group).
  • "Anonymous" (site visitors that are not logged it).

More info

Resources

3

Try using the Group module.

The Group module allows you to create arbitrary collections of your content and users on your site and grant access control permissions on those collections

It has a release candidate published, so it should be somewhat stable and an initial 1.x should be coming soon because it is actively maintained. Over 4,000 sites are using this module.

3

There is the Access by Entity module that can do this.

https://www.drupal.org/project/access_by_entity

There is also Permissions by Term.

https://www.drupal.org/project/permissions_by_term

There is also Taxonomy Access Control Lite.

https://www.drupal.org/project/tac_lite

1

If all you want to do is control access to nodes or content types based roles one of the most straight forward modules is node view permissions

If you want to do anything fancier, like your own forums or groups of content editors etc then group as discussed by @Pierre.Vriens is hard to go past.

1

We can use Node View Permissions module to achieve the requirement. Try this, hope it helps.

1

This is a few years old but I thought I would throw in an answer on how to do this with a very light weight custom module. This answer would be applicable to Drupal 8, 9, and 10.

I am using Drupal 8 and I am a little bit confused that there is no core functionality to restrict the access to some nodes based on roles or users.

Yes, welcome to the world of Drupal! Drupal doesn't have an out of the box UI for restricting access to nodes based on roles.

I found PageAccess, which is marked as unsecure and ACL/Access Control which are both dev and not working on my system.

No comment on these modules. I find contributed modules end up giving you more than you need. If you are not comfortable with coding than a good module that does what you want is encouraged.

Isn't there any option to do so? I need the private sector on my site and can't believe there is no way in Drupal.

Hope you can help me, because if not I have to redo the whole site with another wcms.

You have likely found a solution that works for you but for someone looking in the future here is how you can do it with a custom module.

  1. Name and place your module
  2. Let Drupal know about it
  3. Create a .module file

Create a .module file

Within your custom module root folder, the same place your .info file is, create a new file with your module name ending with .module. i.e. custom-module/custom-module.module)

Within that file add the following code:

<?php

/**
 * @file
 * Contains custom_module.module
 */

// Allows you to load the node's info
use Drupal\node\NodeInterface;
// Allows you to load and change access attributes
use Drupal\Core\Access\AccessResult;


/**
 * Implements hook_ENTITY_TYPE_access().
 */
function custom_module_node_access(NodeInterface $node, $op, AccountInterface $account) {
    /**
     * The $node argument can be either a $node object or a machine name of
     * node's content type. It is called multiple times during a page load, so
     * it is enough if you perform the check once you get the object.
     *
     * If $node is an object, is a custom_content_type, and the operation is
     * view get the role continue processing or return access neutral. If the
     * current user does not have the paid_user role and the node is published
     * return access forbidden.
     */
    if (is_object($node) && $node->getType() == 'custom_content_type' && $op == 'view' ) {
        // Get the roles of the current user.
        $roles = \Drupal::currentUser()->getRoles();
        // If the current user does not have the paid_user role deny access.
        if (!in_array('paid_user', $roles))  {
            return AccessResult::forbidden();
        }

    }
    // Return a neutral opinion otherwise.
    return AccessResult::neutral();
}

About the code... The comments in the code already explain quite a bit but there are a few things that I intentionally left out of the comments as they aren't really comment worthy.

Drupal has a standard way of doing things. Either a node is a draft or published. Published for the most part means it is viewable by the public and draft means that it isn't. Using the hook_ENTITY_TYPE_access() function I can change that functionality.

By checking if the node is an object it only triggers the code on the page once. Likely, you only want to limit viewer to a specific content type. That is why I am checking for custom_content_type. That would be replaced with the machine name of your content type. I am also want the $op or operation the be view to continue processing. These checks narrow down the scope to what access I want to affect.

The return AccessResult::neutral(); at the end is best practice if there is no change to the access results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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