GSOC 2019: Location Based Access Control Phase 2

@suthagar23 In current Implementation while login userproperty is checked for a valid Location or not.

I think we can change it to just check whether a userproperty exists with key locationUuid if-then allow

(or)

split the User property and Check if every id is valid or not.?

Just checking for an element is enough. What do you think?

Oke, Will change to check if User Property with ‘locationUuid’ exists or not .

Thanks

Manage location-based restrictions based on the user roles

@suthagar23

Should this be applied over the results got by Location Restrictions? And on what criteria they are filtered out?

@vankineenitawrun There is some example ACs. So you can plan the work which can fulfill this ACs,

  1. We should able to add accessible locations for roles as well.
  2. If a userRole has accessible locations, and a user with that user role doesn’t have accessible locations -> then assign that userRole based accessible locations for that user.
  3. If a userRole has accessible locations, then if a user with that userRole also has accessible locations, we should give priority to user-based accessible location properties.
  4. If a userRole doesn’t have accessible locations, and a user with that userRole has accessible locations, then we should take user based accessible location properties.
  5. If the user role and user both haven’t accessible location properties, the accessible location property will be empty if that system enabled LBAC.

Let me know if you have any ideas or thoughts?

Role Class has only Role name , Privileges, inheritedRoles, childRoles and extends BaseOpenmrsMetadata

Also Privilege has String name, String description and extends BaseOpenmrsMetadata . BaseOpenmrsMetadata which has metadata fields like created, updates etc.

Then why don’t we create a privilege for a user role to restrict the location based access? (Each locationAccess will create a unique privilege)

like -. locationAccess:locationA, locationAccess:locationB

Changes to Be Made in code

Before installation of LBAC module for every Location in the Database we add corresponding Privilega into the DataBase using UserService.savePrivilege(Privilage p) .

Later user can have Roles can with this privileges.

Then we change the getUserAccessibleLocationUuids(User authenticatedUser) of Locationutils, where the UserLocationUuids along with his role accessible locationsUuids list is returned.

@suthagar23 why do we need role based Location Access as we have the filters or restrictions using the location property?

As a user with the role having the privilege to a particular Location is the same as the person with a location property.?

Since it needs a lot of work to assign locations for each and every user. Rather than that, they can simply assign location access to the user roles. So it can work for them also.

As for easy of implementers, we are providing this features. If they want role based access control - use it, or user based access control - also can use it :slight_smile:

Further, if a doctor user role has access to LocA, LocB, LocC. And a userD who is belongs to that doctor role was assigned only to LocA. Finally the userD can only access to locA.

@suthagar23

User can login in only to Locations with LocationTag as AppFrameworkConstants.LOCATION_TAG_SUPPORTS_LOGIN which are used in LoginPageController in this Line model.addAttribute("locations",appFrameworkService.getLoginLocations()).The Locations which are in User Property has AllActiveLocations. Making first Location in User property as session default location does not allow to login the user.

Here, we show the Amani Hospital.

But here its not there as it is not a login Location so a user with Amani Hospital as a user Property and it being first in the List doesn’t Allow us to Login.

So we need to change List<Location> activeLocations = Context.getLocationService().getAllLocations() at this Line to get only locations with TAG AppFrameworkConstants.LOCATION_TAG_SUPPORTS_LOGIN.

Also, the Header Fragment of the Openmrs gets Locations with the same TAG, at this Line .

The appFrameworkService.getLoginLocations() always gets the Locations with TAG AppFrameworkConstants.LOCATION_TAG_SUPPORTS_LOGIN at this Line

By making this changes,

  1. Can someone use the Ref App as it’s now without any issues if he doesn’t have installed LBAC module?
  2. Do you have any other ideas to skip this changes which can satisfy our requirement?

We just need to change in our Module from

List<Location> activeLocations = Context.getLocationService().getAllLocations()

to

List<Location> activeLocations = appFrameworkService.getLoginLocations();

Fine, go ahead

@suthagar23 Updated Deployment Page for LBAC

https://wiki.openmrs.org/display/docs/Location+Based+Access+Control+-+Deployment+Steps

Changes to be made

getUserAccessibleLocationUuids(User authenticatedUser) function of LocationUtils file.

If the user has the Location user property then return list the locations from user property.

else

If a user has

            Role |  Privileges
          
            R1   |  p11,p12,p13,p14

            R2   |  p21,p22,p23,p24

            R3   |  p31,p32,p33,p34

To get the User Accessible locations from the Roles we need to check every privilege whether does it belongs to any location access and appends the corresponding location to List. Assign the Locations List as User property to user.

Blocker: LBAC-33

  • Enable encounter access based on patient location or multiple admitted/channelled locations.

In the current system, we use Encounter Location for access checking we need to change it to Location of the corresponding patient.

Need to work out both the Issues as per the timeline :slight_smile:

Prepare for Evaluation1.

cc:@suthagar23, above are plans for this week.

@suthagar23 in current system Encouters are only restricted by the Location based on user and the Encouter Location should we change that to based on the location of the person in the Encouter.?

yes, that is the primary plan for this task. Since there can be multiple encounters for a patient during a period. Then finally a doctor can only view the encounters by one location. By this change, a doctor need to view all the past encounters of that patient.

Isn’t that same since patient also has only one Location. so, for a doctor he can access only if encounter’s patient location matches with doctors locations.

Requirement

  • Enable encounter access based on patient location or multiple admitted/channelled locations.

@suthagar23

we can change the current implementation to not remove any encounters when being called for methods getEncountersByPatient and getEncountersByPatientId. As these are used for doctors to get encounters of a patient and so they get all previous encounters of the patient.

But As Doctor can only see the patients who are of his Locations then making Encounters access based on patient Location is of no use. As Doctors locations are a superset of patient Location.