SUPERUSER cannot Enroll Patient in Program

Hello there,

After making some tests with role System Developer (SUPERUSER), it was noticed that a user with this role cannot Enroll Patient in Program, cannot Edit and/or Delete patient enrollment. On the below image the buttons to enroll, edit and delete are missing:

image

After a little investigation on coreapps widgets controllers for program and programstatus, it seems there is a part of the code that is fetching current user privileges through openmrsREST to give, or not, privileges to these buttons on program and programstatus widgets. Check code here and here

When calling openmrsREST the response for this role (System Developer) is:

{
  "sessionId": "3C1981EE238AB54D657923B4D13EFC3B",
  "authenticated": true,
  "user": {
    "uuid": "5f1e7c8b-fdc1-447c-b0b8-efba5c97d72f",
    "display": "dev_user",
    "username": "dev_user",
    "systemId": "215-4",
    "userProperties": {
      "loginAttempts": "0",
      "emrapi.lastViewedPatientIds": "5687"
    },
    "person": {
      "uuid": "7c6f1670-9588-45db-8ddf-506fa7e1afb7"
    },
    "privileges": [],
    "roles": [
      {
        "uuid": "8d94f852-c2cc-11de-8d13-0010c6dffd0f",
        "name": "System Developer"
      }
    ]
  },
  "locale": "en_GB",
  "allowedLocales": [
    "en",
    "es",
    "fr",
    "it",
    "pt"
  ],
  "sessionLocation": {
    "uuid": "8fe901fb-4f09-466e-a7ea-dd95e0f3048d",
    "display": "Location A",
    "links": [
      {
        "rel": "self",
        "uri": "http://localhost:8081/openmrs/ws/rest/v1/location/8fe901fb-4f09-466e-a7ea-dd95e0f3048d"
      }
    ]
  }
}

The privileges array is empty so conditions like the one below will never be true for this SUPERUSER.

if (response.user.privileges.some( (p) => { return p.name === 'Task: coreapps.enrollInProgram'; })) {
  this.canEnrollInProgram = true;
};

Meaning that SUPERUSER can never enroll a patient.

This is happening also for relationships widget. Check code here .

What are your thoughts on this? Should we make a fix to ignore privileges if it’s superuser?

Thank you in advance for you feedback about this subject.

cc: @mksd @mogoodrich

1 Like

@ifernandes, I’d think of the fix as addressing the associated rest endpoint, to provide all privileges if the user has super privileges.

2 Likes

@ruhanga so you’re suggesting to fill the SUPERUSER-named role (so, "System Developer" basically) with all privileges just before returning here:

public UserAndPassword1_8 getByUniqueId(String uuid) {
  return new UserAndPassword1_8(Context.getUserService().getUserByUuid(uuid));
}

?

@dkayiwa, @mogoodrich, thoughts?

1 Like

Yes @mksd or even better returning early with all privileges for such user here

My preference is an end point that takes advantage of: Context.hasPrivilege(privilege)

@dkayiwa you mean adding a new endpoint in Core Apps?

If yes, does that mean it is not a good practise to check for the user’s individual privileges in client-side code? Precisely because admin has no individual privileges and will therefore never be granted any rights?

My preference would be in the rest webservices module.

I like to shield the client from internal implementation details of how privileges are associated with an account. The client just asks for whether an account has a certain privilege and the server takes care of the rest.

1 Like

@dkayiwa the default representation of User seems to expose the list of granted privileges: openmrs-module-webservices.rest/UserResource1_8.java at b6e6fe09307bad6720357dd7bb0af093bd7e327f · openmrs/openmrs-module-webservices.rest · GitHub

So in a sense this is already happening, it’s just that System Developers display an inconsistent behaviour, or what’s your take?

1 Like

Going by this would mean an enumeration of all roles in the system, and then return all privileges for each role, for the super user. I find that uglier than a simple new end point which delegates to: https://github.com/openmrs/openmrs-core/blob/2.4.0/api/src/main/java/org/openmrs/api/context/Context.java#L693-L705

FWIW, the underlying business logic of hasPrivilege is a bit more than a simple User.getPrivileges() as you can see here: https://github.com/openmrs/openmrs-core/blob/2.4.0/api/src/main/java/org/openmrs/api/context/UserContext.java#L302-L346

Alternatively, the client can just check for the System Developer role from the default User representation, and if found, assume all privileges.

1 Like

That’s sounds like a good idea for an easy way out :slight_smile:

@ifernandes?

It sound good to me also :wink: Thanks @dkayiwa and @mksd. So maybe I can create a ticket and start working on this.

1 Like