Drupal 8 core Content Moderation module BEWARE! Permissions "gotcha" when re-using Workflows across content types
I recently came across a permissions misconfiguration that left me scratching my head. Users with a certain restricted role had far more privileges than they should and could publish or unpublish any content on the site. Of course, the first place I looked was the permissions page, but nothing looked amiss as far as I could tell in the (hundreds of) tiny checkboxes. It took some trial and error and a dose of luck, but I found the unintuitive culprit. Read on and learn how to save yourself the same time and trouble.
Let’s say you have a site with two content types (Basic Page, Gallery) and two user roles: Authors for creating and editing content, and Publishers for approving it live. Setting up the Content Moderation module to enforce the correct transitions is fairly straightforward and will not be covered here.
Then let’s say you add a new content type with its own user role: “Blog Post” node and “Blog Editor”. Blog posts are less critical to the site, so you want to permit Blog Editors to publish them live without moderation. No sweat! Just create the new Blog Editors role and give it access to (1) editing the Blog content type and (2) use the “Publish” workflow transition.
Now, let’s say you have an existing Author (call her “Taylor”) who also deserves Blog Editor permissions. You add that role to Taylor's user account, so now she has both “Author” and “Blog Editor” roles. Remember that previously, with only the Author role, Taylor could create and edit—but not publish—Basic Pages and Galleries. You might expect with the new role, Taylor just gains create/edit/publish access for Blog posts. Well, she does get that, but so much more! Due to the combination of roles, Taylor can now publish Basic Pages and Galleries in addition to Blog Posts. But why?
Let’s break it down. The Author role gives Taylor create and edit permission to the Basic Page and Gallery content types, and the Blog Editor role grants Taylor access to the Publish transition. And suddenly, voila, Taylor has far greater permissions than we intended.
So, what to do? Simply create separate Content Moderation workflows for the different content types: One for Basic Pages and Galleries, and another for Blog Posts. If you later decide you want to separate Basic Page permissions from Galleries, it’s easy enough to go in and create a third workflow at that time. Now, there’s no “Clone” button on the Workflows listing page, and it’s kind of a PITA to recreate each state and transition one-by-one. So I recommend duplicating the existing workflow configuration file in your config sync directory. E.g.,
cd /path/to/config/sync cp workflows.workflow.editorial.yml workflows.workflow.blog.yml
Then edit the new file, delete the UUID, update its “id” key, save it, and run a configuration import. At this point, you can visit the Workflows configuration page (
/admin/config/workflow/workflows) and update the new workflow’s other settings (like selecting to which content types it applies). Don’t forget to re-export your config so that the proper UUID gets added to the workflow's configuration file.
If the command line isn't your thing, you can visit the Config Import page (
/admin/config/development/configuration/full/import) which provides a simple form for you to enter the contents of a single configuration file to be imported. Just copy the contents of the current workflow’s config export file, paste it into the form, make the same edits described above, then save and voila, you have a brand new workflow available.