Re-Design

Table of Contents

Proposal #1: Multiple Roles per User and separation between Permissions and Access Scopes

This design tries to address two of the missing features of the current implementation:

  1. Multiple Roles per User
  2. Separation between Access Scopes (Organization, Facility, Workspace, Room) and Permissions

Multiple Roles per User

Allowing a User to have more than 1 Role give us the possibility to define very specific Roles and then compose them in different ways to create different logical roles. This composition of Roles also makes possible to reuse already defined Roles simplifying their configuration.

In the application, when a permission needs to be enforced, the group of all the Permissions from all the Roles the User has is going to be used. Permissions are always added when creating the group of all the Permissions a User has.

Access Scopes

In the current implementation, some Permissions are associated to an Organization and some of them are not. This tightly-coupled relationship between Permissions and Organizations makes impossible (or very cumbersome) to create a more fine-grained and friendly way of defining Permissions.

The new approach is to define different Access Scopes. An Access Scope grants access to one or more Organization, Facility, Workspace and/or Room. The Access Scope is defined by the Role/s a User has and all the Permissions are evaluated in this scope.  

All the Permissions a User has are evaluated in the same Access Scope

The proposed solution sacrifices the possibility of having different Access Scopes for different Permissions in order to gain simplicity both in the implementation and in the configuration of the Roles. 

Proposed EM

Each organizational unit (Organization, Facility, Workspace and Role) now has a corresponding table that grants access to individual roles. In this way, we could have a granularity up to the Room level.

In this new approach, the table RolePermission doesn't have the column OrganizationId anymore. The scope where a permission is applied is given by the join of all the *Access tables where the Role is present.

Access Scopes are inclusive

A Role that has access to Organization 'A' also has access to any organizational unit below it. 

Permission Mappings

The application currently supports 31 different permissions. The new design will reduce the number of permissions to 14. Some of the old permissions had a 'list' and 'read' version (i.e. read_users and list_users) that were actually never used in reality. The new design will merge those 2 kind of permissions into a single 'read' one.

The current implementation also has some permissions of the form *_from_all_organizations (i.e. list_users_from_all_organizations) that are no longer needed given the new Access Scopes. Same thing happens to the permissions of the form *_from_current_organization and *_from_current_facility.

Some other permissions like list_organizations, list_facilities, list_workspaces and list_rooms are no longer explicit permissions. They can now be related to a particular Access Scope.

The mappings between the current permissions and the proposed ones are:

Current Permission
New Permission
Used In
Comment
list_organizations 

This permissions has no counterpart in the new design. List Organizations operation will return all the Organizations that are in the Access Scope of the user that is invoking the operation. Read Organization operation will fail if the invoker doesn't has access to the requested Organization.

read_organization
list_facilities This permissions has no counterpart in the new design. List Facilities operation will return all the Facilities that are in the Access Scope of the user that is invoking the operation. Read Facility operation will fail if the invoker doesn't has access to the requested Facility.
read_facility
list_workspaces This permissions has no counterpart in the new design. List Workspaces operation will return all the Workspaces that are in the Access Scope of the user that is invoking the operation. Read Workspace operation will fail if the invoker doesn't has access to the requested Workspace.
read_workspace
list_rooms This permissions has no counterpart in the new design. List Rooms operation will return all the Rooms that are in the Access Scope of the user that is invoking the operation. Read Room operation will fail if the invoker doesn't has access to the requested Room.
read_room
list_rolesread_role



read_role
  • Read Organization's Role
list_usersread_user





list_users_from_all_organizations
  • List Users (if 'location' is not specified, this permission is required)
read_user
delete_userdelete_user 
modify_usermodify_user
 
There is no longer a distinction between modify_user and modify_user_nfc_tag
 

modify_user_nfc_tag

modify_own_usermodify_own_user 
list_patients_from_all_organizationsread_patient


list_patients_from_current_organization
list_patients_from_current_facility
modify_patients_from_all_organizationsmodify_patient





modify_patients_from_current_organization
modify_patients_from_current_facility
list_discharged_patientsread_discharge_patient 
discharge_patientsdischarge_patient 
final_discharge_patientsfinal_discharge_patient 
send_messagessend_messages 

read_alerts_only_from_associated_patients

read_alerts_only_from_associated_patients 

read_alerts_from_entire_organization

read_alerts_from_entire_organization 
re_schedule_alerts_from_all_organizationsre_schedule_alerts



re_schedule_alerts_from_organization
It is important to notice that, when configuring permissions, some permissions are not compatible with some scopes. For example, a User having read_user permission only in a Room Access Scope will not be able to list users in the application. The reason behind this is that, in the application, Users are associated to Facilities and not to Rooms. 

Flow Diagrams

List Organization Units (OU)

OU list operations are always limited to a parent scope. Given the hierarchical structure of OUs, in order to list the OUs in one level (i.e. Facilities) we need to provide the parent of the OU (i.e. Organization).

Translated into REST URLs, these operations are:

/organizations
/organizations/{organizationId}/facilities
/organizations/{organizationId}/facilities/{facilityId}/workspaces
/organizations/{organizationId}/facilities/{facilityId}/workspaces/{workspaceId}/rooms 

The tricky part here is that a OU should be available to a user even in the cases where the user only has access to a descendant of that OU. By doing this we can guarantee that the user will be able to locate a OU that he/she has access to even if he/she doesn't have access to any of its parents.
This is a specific behavior for the OU listing operations. 

As an example let's analyse the following topology:

In the previous image, the green nodes are the OUs present in the User's Access Scope, the yellow nodes are the OUs reachable by a parent node and the blue nodes are the OUs that are reachable because of a children. The white nodes are OUs that are not accessible in the user's Access Scope.

These are the results of some of the list operations against that hierarchy:

URLResults
/organizationsOrganization A, Organization B, Organization D
/organizations/A/facilitiesFacility A.2
/organizations/B/facilitiesFacility B.1, Facility B.2
/organizations/D/facilitiesFacility D.1, Facility D.2
/organizations/A/facilities/A.1/workspacesFORBIDDEN
/organizations/A/facilities/A.2/workspacesWorkspace A
/organizations/A/facilities/B.1/workspacesWorkspace A
/organizations/A/facilities/B.2/workspacesWorkspace A
/organizations/A/facilities/A.2/workspaces/A/roomsRoom A, Room B
/organizations/A/facilities/B.1/workspaces/A/roomsRoom A
/organizations/A/facilities/B.2/workspaces/A/roomsRoom A
/organizations/A/facilities/D.1/workspaces/A/roomsRoom A

Read OU

OUs are accessible for read as long as the user's Access Scope contains the OU itself or some of its parents.

Continuing with the sample OU hierarchy, any green or yellow node can be read. Any white or blue node will return a FORBIDDEN error.

List operations

List operations on resources that are not part of the OU hierarchy (i.e. users, patients, etc) have a similar behavior. The following example details the flow for a listUsers operation, but this flow can be extrapolated to other resources.

 

Read/Update/Delete Operations

Read operations on resources that are not part of the OU hierarchy (i.e. users, patients, etc) have a similar behavior. The following example details the flow for a readUser operation, but this flow can be extrapolated to other resources.

Other permissions that also fall into this category are re_schedule_alerts, discharge_patient and final_discharge_patient.

Access Scope-free permissions

There are certain permissions that are not evaluated in any Access Scope. Examples of these permissions are: send_messages, read_alerts_only_from_associated_patients and read_alerts_from_entire_organization.
When these permissions need to be evaluated, the application just checks whether the permission is present or not in the User's role/s. 

 

Proposal #2: Separate Access Scope for each permission