Projects:Role Inheritance/Functional&Technical Specifications
The objective of this project is to ease the management of the role creation. The implementation of this project will help to define role permissions (access to organizations, windows, reports, process etc.) by inheriting them from other already existing role permissions. This will allow to define a dynamic role inheritance hierarchy.
With this new mechanism, the role management will be simplified, allowing the generation of the new roles on a hierarchy based procedure: the new role will inherit the permissions copied from other already existing roles.
The way to define role permissions based on inheritance will be done through a new tab, [Role Inheritance], included in the [Role] window. Inside this tab, it will be possible to create new records in order to specify the role whose permissions will be copied into the new role. Every record in this tab will have two fields:
- Inherit From: this is a reference to the role from which the current role will inherit the permissions from.
- Sequence Number: as we are in an scenario with multiple inheritance, the sequence number is the number that will be used to define the inheritance hierarchy and therefore, the order in which permissions to the different elements will be revoked/granted according to the copied roles definition.
Using this configuration, the accesses for the new role will be generated in the corresponding tabs where the permissions are defined, for example, in the sub-tabs of the [Role] window. Also a new field will be included in all those tabs:
- Inherited From: this is a reference to the role where the present role is inheriting a particular permission. For permissions created manually this field will be empty. If this field is not empty, the record can not be edited.
Use Case 1 (Horizontal Hierarchy)
With the current role definition design, if an entity has multiple organizations, users are forced to define the same role per organization multiple times, depending on the organization structure.
The generation of new roles can be done in a flexible way with this mechanism. We can create a role with access to the organizations and one role with the application elements we want to access with the new role, and generate a new role that inherits the permissions from both roles (See image below).
Use Case 2 (Horizontal Hierarchy)
Let's say that we have a sales role and a purchase role. We can use our new way to configure roles to grant access to sales and purchase elements to a new role automatically.
Use Case 3 (Horizontal Hierarchy)
By using the sequence number, we can define the order which the permissions will be inherited. This will allow us, for example, to restrict access to the elements by using the active flag.
Use Case 4 (Vertical Hierarchy)
It will be also possible to define the permissions inheritance in a vertical hierarchy. This will make possible to reflect changes done in a parent node (role A in image below) to its child nodes (role B) and subsequent child nodes (role C).
This project will take advantage of the current infrastructure for securing the application elements. So it does not require to review or change the current logic which gives access a particular role to those elements.
A new way to configure roles is going to be introduced, but this roles will be defined in the same way as it is done manually.
To make this configuration work two implementation parts are involved: the application dictionary infrastructure and a process to manage the inheritance. Apart from these two parts, it would be nice to have a widget or window in order to allow users to see a role inheritance tree in a friendly way.
Application Dictionary Infrastructure
It is necessary to create an application dictionary infrastructure which allows users to create the role configuration. The required application dictionary elements are:
- A new tab called [Role Inheritance] will be added to the [Role] window at level 1. In this tab, several records can be created. In every record the permissions to be copied will be set by specifying a role and a sequence number. The sequence number will be used to set the order of applying the inherited permissions. It will be possible to delete the records in this tab, but at the same time it the ability to update records will be disabled in order to avoid recalculations that can be expensive in terms of performance.
- The windows and tabs which are designed to secure elements by role will include a new read-only field used to specify if a particular access within this tabs has been created by inheritance. This field will be a reference for the role taken as parent. For this reason, in case this field is not empty the record can not be edited. Ideally, these type of records would be read only but due to the lack of a infrastructure to define read-only logic at record level, then we should include some logic to prevent changes on them. The tabs that will include this new field are:
- [Org Access], [Window Access], [Tab Access], [Field Access],[Report and Process Access], [Form Access], [Widget Class Access], [View Implementation] and [Process Definition] in the [Role] window.
- [Table Access] in the [Role Access] window.
- Header of the [Preference] window.
- [Alert Recipient] in the [Alert] window.
- A new field called "Is Template" will be included in the header of the [Role] window. This is a flag to mark if the role can be used to inherit from it. When editing a permission of a role with this flag active, it would be nice to display a warning message in order to inform users that the changes could have implications in other roles involved in the hierarchy. Also it could be necessary to avoid the possibility of uncheck this flag once the role has been used by another one to get its accesses by inheritance.
Note: the users assigned to the roles will not be managed by this project and therefore will not be inherited by the newly created roles. So the [User Assignment] tab in the [Role] window will remain unchanged.
Process to manage permissions inheritance
A process must be defined to manage the creation of the inherited permissions. This can be achieved using an event handler fired when creating, removing or editing records in the [Role Inheritance] tab.
This process will use the role and the sequence number of the records created in the [Role Inheritance] tab, to add the permissions of the new role.
The roles selected to inherit from should be the ones marked as "Is Template". They can be selected in the selector that will be present in the records of the [Role Inheritance] tab. This is intended in order to avoid problems when making changes in role that otherwise could be extended through the entire hierarchy. In addition, the roles candidates to be selected should be of the same access level as the role that will be created.
Besides, it should not be possible to set as non-template an existing template role being used by other roles. A template role must be Manual, i.e., it can not be defined as Automatic.
This will be an additive process, i.e., all the permissions will be copied into the new role and if we need to restrict access to a particular element, then the permission for that element should be copied with the active flag as false.
For example, if we have the following hierarchy A->B->C and A has access to a window, this access will be included during the process for the role C. In case role B does not has access to that very same window, it will have the active flag set to false. Therefore the final permission given to C for that window will be revoked.
For those permissions created manually, they will remain unchanged after setting the inheritance for the role. So, this process will not modify permissions created manually. In the same way, users can not modify an inherited permission.
Also, this process will take into account the preferences defined for a role and it will create them for the new role as part of this inheritance process.
Finally, it must also check that there is not any cycle in the defined hierarchy.
Recalculate Permission Process
When setting inheritances between roles, using the [Role Inheritance] tab, all the permissions will be propagated automatically.
But there are two cases where it would be necessary to force the recalculation of the inherited permissions:
- If a permission is modified directly from the database, then this change will not be propagated automatically.
- When deleting a non inherited permission of a role, because of a technical limitation with Hibernate and the unique constraints defined for the inheritable elements. An example of this use case:
- We create Role A, and we manually give it access to Sales Order window.
- Create Template B, and we manually give it access to Sales Order window also.
- Configure Role A, to inherit from Template B. Role A will inherit all the permissions from Template B. But the permission for Sales Order window which Role A already has, will remain unchanged. (As it has been created manually).
- Delete Sales Order permission from Role A. Due to the technical limitation mentioned above, the Sales Order permission from the template will not be added automatically.
In these cases, it would be necessary to recalculate the permissions of the role in order to avoid having inconsistencies on the inheritances. For this reason, a process to recalculate the permissions is going to be included, which will be hidden by default, as these uses cases are out of the common flow when configuring roles.