Authorization in Pillar is based on roles and capabilities to allow access to certain features, and groups to handle per-project and within-project permissions.
Roles and Capabilities
Each user has a list of zero or more roles, which originate from different systems. For example, the 'subscriber' role is managed by the Blender Store, and the 'demo' role is managed by Blender ID. The roles are then mapped to a set of capabilties for the user, and the Pillar (and extensions) code checks for those capabilities.
Organization-provided roles are prefixed with 'org-'. This allows recomputation of users' roles by taking the union of all roles without 'org-' prefix and all the roles given by their organizations.
As a concrete example, here are some of the mappings that are in use by Pillar at the moment of writing. These can change at any time and do not reflect what is currently in production on any of the Pillar-based systems.
|subscriber||attract-view, home-project, subscriber|
|demo||attract-view, home-project, subscriber|
|flamenco-user||flamenco-use, flamenco-view, flamenco-view-logs|
In the code, capabilities of the current user can be checked using:
from pillar.auth import current_user def somefunc(): if not current_user.has_cap('attract-view'): return 'Access denied', 403 return 'Access granted'
Flask endpoints can be protected using the
from pillar.api.utils.authorization import require_login @require_login(require_cap='attract-view') def somefunc(): return 'Access granted'
User permissions within projects is managed by group membership. Users can be member of multiple groups. Each project has its "admin group", and membership of that group implies membership of the project. Membership of this group is what the "share project" feature manages.
Each project, node type, and node, can contain permissions per group, which are expressed as the allowed HTTP methods (GET to read, POST to create new, PUT to replace, and PATCH to perform operations).