Corteza, at the moment, does not provide a native feature which would allow you to define hierarchical user relations. The outlined solution provides an example of how you could programmatically achieve this.
The demonstration uses an example where we have three roles; admin -> manager -> user where user reports to the manager and the manager to the admin.
The desired output is that the user can see their own records, the manager their own records and all user records, the admin their own records and all user records and all manager records.
Since Corteza doesn’t support hierarchical roles, we’ll use composition instead. Since we want users to see their own records, we’ll define a contextual role which will allow us to define just that.
Next, we want a parent role to see the records created by it’s child roles for which we’ll need to define an workflow.
The workflow would grab the record owner, determine the owner’s highest role and grant access to the parent of the highest role.
Next, we’ll need to correctly assign roles to our test users.
We’ll have 3 users; test user, test manager, test admin and 3 roles; user, manager, admin.
Each user will receive a role appropriate for them, as well as all roles which are below them; so:
- Test-user will have user role.
- Test-manager will have manager, user role.
- Test-admin will have admin, manager, user
This solution allows us to replace the need for hierarchical structure into the compositional structure (which Corteza uses) and utilizes automation to automatically manage the heavy lifting.
In this example, I’ve prefixed the relevant roles with xx__%d to help with lookup as well as determining their relation. You can opt-in for something else, such as using a special module which outlines relations.
The 4 roles are:
- Owner – used to give permissions to access your own records. This is a contextual role with the expression of resource.ownedBy == userID
- User – used to give permissions to users to access specific records
- Manager – used to give permissions to managers to access specific records
- Admin – used to give permissions to administrators to access specific records
The xx__3_user role, the xx__3_ part tells us the role is below the xx__2_manager role, the xx__2_ part tells us the role is below the xx__1_admin role.
Configuring Test Users
Here we show the configuration for all three test users which are mentioned in the solution outline section above.
Base Permission Configuration
The fairly strict and minimalistic configuration outlined below may not be suitable for all instances. For example, denying all authenticated users from reading any record might be too extreme for some cases. Adjust as needed.
We firstly need to make some generic configurations to the access control permissions.
In the list of all modules, we need to deny users from reading any record of any module – this will prevent the users from seeing what they’re not supposed to.
Next, in the module configuration screen, we need to allow the xx_owner role to read the records – this will allow the users to access their own records.
Configuring Permission Management
Lastly, we need a workflow to manage our access control permissions. The workflow described below grants owner’s parent role to access the records.
For production, you’ll need to expand the workflow to also prevent the owner’s parent to access the record in case the owner is changed, or the role hierarchy is changed.
A quick rundown of the important parts
We trigger the workflow when the record is updated with an owner, we fetch the owner’s roles and prepare some initial state.
In the following Iterator, we find the hirearchically highest role the owner has which we’ll later use to find the parent.
Here we use the hierarchy index (the xx_1 – the number bit) to determine this.
Lastly, we iterate all parent roles and grant them access to the current record.
Workflow JSON Config