bolt/bolt — pull request #2293 by mathias213 (2014-12-08 09:34:51+00:00)
Title: Add Per Content Permissions with default set to ROLE_ANONYMOUS

Hi all,

This patch is to add permissions set at content level in addition to those set at content type level.

The idea to start that change came from there: https://github.com/bolt/bolt/issues/1263 where almost all needed tool to proceed were prepared. In that thread tobias2k warned about ACLs using terms "bloat" and "creepy" as ACLs are quickly complex.

To limit the complexity inside Bolt's code it was decided to use a user defined select field added to each content types you want to protect. This select will contain all groups of roles you want to be able to set up on these content type's contents.

A new role keyword is defined: "viewers". This role keyword is used in permissions.yml to protect some content types.
Ex:

pages:
frontend: [ viewers ]

Then in contenttypes.yml the select is created:
Ex: this is an extract of "pages" content type declaration with addition of "viewers" select field

template:
type: templateselect
filter: '*.twig'
viewers:
type: select
default: anonymous
values: [ anonymous, everyone, owner, 'admin, editor' ]
taxonomy: [ chapters ]

Here each content of this content type would be grant-able to:
- role "anonymous": all users, a public content.
- role "everyone": only connected users
- role "owner": only owner could see the content in frontend
- roles "admin" or "editor": you would need to belong to admin OR editor to access that content.

So here was the way to extract from Bolt a part of permissions complexity.

As most complexity is pushed on user side now the point - IMHO - would be to help users using this system. The code modification is meant to that purpose.
This modification applies only on frontend content - or at least is meant to apply only there - and it applies in two ways:
- the checkPermission() function in Permissions.php check also per content permissions when needed to add all roles contained in database field "viewers" in available roles array then these available roles are compared to current user's roles
- the executeGetContentQueries() in Storage.php is also modified to add a SQL filter when retrieving multiple contents. This filter avoid breaking limit parameter sent to requests.

So once the patch is added to the code user would need to:
- modify some content type in contenttypes.yml to add "viewers" select.
- modify this content type permissions in permissions.yml to add this internal "viewers" role to "frontend"
- set to "true" flag "frontend_permission_checks" in config.yml
And contents will be filtered.

At this point Bolt will complain the database must be updated, if user do it Bolt will add an empty "viewers" field to this content type table structure. To avoid the whole site becomes unavailable in frontend as no "viewers" roles are defined in our empty field the default behaviour is to consider the content as public and so granted to ROLE_ANONYMOUS in case "viewers" is empty.