Now, for something different from my usual musings, a tech blog!
I recently started setting up a website for a casual gaming group I am part of. I decided to try Drupal as it seemed to have the ultimate flexibility I was looking for and I didn’t have time to code all the features I wanted into the site myself. As I got the ball rolling with Drupal 8, I became increasingly unhappy with the fact that Drupal had no way built into it’s Core to restrict content access to certain authenticated users or, in my case, members. You can use block configuration to limit the visibility of certain elements by roles, but it does not put a hard restriction on viewing the element if the user knows the address. By default, Drupal has several ways to restrict who can create and edit content but assumes that all published content can/should be seen by everyone.
To compound the problem, because Drupal 8 had been “recently” released (out for 4 months when I started with it), the module support for it had not caught up and none of the known modules that restricted access in Drupal 7 were ready for Drupal 8. Eventually, a drupal community member named Peter Majmesku found he needed this functionality so badly that he created the module Permissions by Term: https://www.drupal.org/project/permissions_by_term
Permissions by Term allows you to create a Taxonomy term in Drupal (like a tag) and then apply restrictions to that term by individual users or role groups. Then, any content to which you add a reference to the term will be restricted (i.e. viewable or editable) to only people you have specified.
Making it Work
To begin, install the Permissions by Term module the way you would any other Drupal 8 module using either the link or the download from the project page located at https://www.drupal.org/project/permissions_by_term . Be sure to install/enable it so that it is checked in the Admin Menu > Extend list.
There are many different needs and use cases for restricting access to specific content. I imagine the most common will be that you have content on the site that you want accessible by authenticated users belonging to a specific role group but not the public. Going beyond this, you may want different role groups to be able to access different types of content. In any case, it’s a good idea to have the users, or at least the roles, exist in your system before you attempt to restrict access to them.
It also might be a good idea to grant users the role you intend to restrict access by, though not strictly necessary. You can, of course, add more roles and users after setting the permissions and alter the permissions after they have been specified. So don’t worry if you don’t have your entire permission structure fully baked. However, it would probably help to have a good idea about how you are going to want to organize access in the future before you start restricting it.
If you are satisfied that you know how you want to restrict access, the first step is to create a new Taxonomy vocabulary. This is basically creating a container for the various terms that you might use to restrict access in different ways. You could technically create different vocabularies, each with their own terms to be used for restricting access and your needs might demand it. But I think the most straightforward way to organize it would be to create a vocabulary called something like “Access Restrictions” that you use to put all the restricting terms in. You do this by going to Admin Menu > Structure > Taxonomy and click the + Add vocabulary button. Give your Vocabulary a name and a description of the types of terms it might contain. Once done, click Save.
You will then be presented with the terms associated with the new vocabulary, of which there will be none by default. Click the +Add Term button to add a new one. You can call it whatever you think is appropriate, probably something descriptive of how you plan on using it to restrict access. If you are familiar with Drupal Taxonomy, you will notice a new section for the term called PERMISSIONS. This is where you can restrict access to any number of roles or specific users. Give the term a description, again a good choice would be something that indicates to whom access is restricted by this term and then Save it.
You’ll now have a term you can use to restrict content with. You could certainly add more to suit your restriction needs now or at a later time.
Now you’ll want to create a content type that you are going to restrict access to. Go to Admin Menu > Content types and click the + Add content type button. Drupal being what it is, this could be anything from a type of page to a file. In my case, let’s say it is a type of page that you want to put content on that can only be seen by certain users who are authenticated with your site and members of a specific role group (so not visible to the public). Once you have the details set, click Save and manage fields.
After the content type is created you will be presented with the fields that it will contain. By default there is only a body field. Click the + Add field button to add the field that will activate the access restriction. For this new field you want to ensure that Taxonomy term is selected under Add a new field (this assumes you haven’t already created such a field previously, if you have you can simply select it under Re-use an existing field). You can give the field any label you want, the key part is that the Machine name reads field_secured_areas with that exact spelling. Once you have done this click Save and continue to move on.
You should then be presented with the Field Settings which you should ensure that Type of item to reference is set to Taxonomy term and the Allowed number of values is set to 1 (as of this writing this is all the module supports, though there has been talk about changing it here: https://www.drupal.org/node/2725627). Once you have ensured the above, select Save field settings.
You will then be presented with the field details to edit. You can give the field any label you like, again it might be useful to call it something that refers to the fact that it is there to provide the restriction to the content. Ensure that the Reference method is set to Default and that you check the box next to the vocabulary you created that contains the terms with the restrictions you want to use. At this point you can click Save settings or you can optionally add a DEFAULT VALUE first.
Whether you use a default value, or not, is up to you. If you don’t specify one, then any time a new instance of this content type is created, the value will have to be specified. Otherwise, the content will not be restricted. You may want this. You also may want the field to be editable so anyone with edit rights to this content type can change the restrictions (though importantly, even if a user has the Drupal permissions to edit the content type, they will not be able to edit it if the term permissions restrict their access). Conversely, you may want to specify a default value and then hide the field in the content type’s form display so that any time this content type is created or edited, it automatically has the correct restriction without the creator/editor even knowing it is there. You could also specify a default simply so content creators have a guide so that when they create new content they might usually leave the field alone but could change it if they have specific need.
Once the field is created, you will see it in the list of fields for the content type. Ensure that the machine name for the field is field_secured_areas. You could also add any other fields you want to be part of this content type. It is now ready to use. You can also grant create and edit permissions to other users/roles or add it to their shortcuts.
Now, in any content list you can click the + Add Content button, if you have permissions to do so, and you will see it in the list of content type options. Select it to start creating a new piece of content.
If the field is visible in the Manage form display settings for the content type, you will see it in the editor and possibly be able to edit it. The rest of the content creation is the same as any other Drupal content creation.
If the field is visible in the Manage display settings for the content type, you will see it displayed with the rest of the content.
Any user not specified in the term permissions who attempts to access (either viewing or editing) the content will simply get an access denied response.
That’s it! I can’t speak highly enough about how this module saved my site. I feel as though restricting access to content for certain users is common enough to warrant that functionality being part of Drupal’s Core. Some day it probably will. But for now, you can use this module with Drupal 8 to restrict access any way you need to.