openmrs:require not working as expected

I added a new functionality and page and a privilege associated with this page but this is not been respected. I added a page to update license agreement and should only be accessible to anyone with the “Edit License Agreement” privilege but this is not the case. My service method is defined as below

@Authorized(LicenseAgreementModuleConfig.EDIT_LICENSE_AGREEMENT_PRIVILEGE)
@Transactional
LicenseAgreement updateLicenseAgreement(String licenseBody);

And my page has

<openmrs:require privilege="Edit License Agreement" otherwise="/login.htm" redirect="/module/licenseagreement/manageLicenseAgreement.page"/>

But none of these is been respected. I created a new user that doesn’t have this privilege. Entered the link to the page and instead of redirecting me to the login page, it showed me the page even though the user does not have the privilege to.

Now when the user updates the license agreement from the UI and submits the changes, I was at least expecting the service layer to also throw an exception since the person initiating that call does not have the required privilege but that doesn’t happen. The update is successful. I’m I missing something?

Can we look at this module’s source?

1 Like

@dkayiwa sure. Here you go https://github.com/ivange94/openmrs-module-licenseagreement

What is the url of the page that you are referring to?

http://localhost:8080/openmrs/licenseagreement/manageLicenseAgreement.page

My understanding is that the openmrs:require tag is jsp specific.

If that’s the case is there an equivalent for gsp? Also how is the @Autorized supposed to work. It was still able to update the table even though the user that initiated that call does not have the required privilege.

Hi @ivange94

Did you get a chance to have a look to the PatientFlags module for the similar usage that you mentioned above. You can refer it from here - https://github.com/openmrs/openmrs-module-patientflags/blob/master/omod/src/main/webapp/fragments/patientflagsDashboard.gsp#L1

@suthagar23 thanks for your response. That’s the same thing I’m doing here https://github.com/ivange94/openmrs-module-licenseagreement/blob/master/omod/src/main/webapp/pages/manageLicenseAgreement.gsp#L3 and it isn’t working hence this thread.

@ivange94 Have you seen this line - https://github.com/openmrs/openmrs-module-patientflags/blob/master/omod/src/main/resources/webModuleApplicationContext.xml#L44

I can’t sure about this and it might be wrong also, let’s try and see what happens :smile:

The GSP equivalent is

<% context.requirePrivilege("something") %>

Example: https://github.com/openmrs/openmrs-module-providermanagement/blob/4e5cc6b1278aeda7eecccddf39f85219f659328d/omod/src/main/webapp/pages/editProviderRole.gsp#L2

@darius thanks. I don’t know what I may be doing wrong because this doesn’t seem to work. Here’s what I’ve done. Inside config.xml I have a privilege defined like this

<privilege>
    <name>Edit License Agreement</name>
    <description>Update user terms and conditions</description>
</privilege> 
<privilege>
    <name>Access Legal App</name>
    <description>Access Legal App</description>
</privilege> 

I defined an app

[
  {
    "id": "licenseagreement.Legal",
    "description": "Legal App",
    "order": 2,
    "extensions": [
      {
        "id": "licenseagreement.Legal",
        "extensionPointId": "org.openmrs.referenceapplication.homepageLink",
        "type": "link",
        "label": "licenseagreement.legal.app.label",
        "url": "licenseagreement/legal.page",
        "icon": "icon-list-alt",
        "requiredPrivilege": "Access Legal App"
      }
    ]
  }
]

In the gsp page I added this as you recommended

<% context.requirePrivilege("Edit License Agreement")%>

Inside my service I have this

@Authorized(LicenseAgreementModuleConfig.EDIT_LICENSE_AGREEMENT_PRIVILEGE)
@Transactional
LicenseAgreement updateLicenseAgreement(String license);

After running the system, I created user John Doe with role Organizational: Nurse. Since those are new privileges, I didn’t expect this user to have them hence shouldn’t be able to access that part of the system. But when I login with credentials for John Doe, I see the legal app on the landing page even though the user does not have the “Access Legal App” privilege.

When I click on the app, it takes me to page that has the context.requirePrivilege(“Edit License Agreement”) but even though the user doesn’t have that privilege I can still see the page.

Now when the user updates the license and saves it, the updateLicenseAgreement method is called and that is annotated with @Authorized(LicenseAgreementModuleConfig.EDIT_LICENSE_AGREEMENT_PRIVILEGE) so I expected it to fail or throw an exception but none of that happens.

Update:

@Authorized is working fine. It doesn’t allow the user to update the resource since he doesn’t have the privilege. Not sure what I changed but I think this one is working now fine. I get an exception when I try to update the license agreement as John Doe but works fine when I do it as admin. For reference here’s the exception the system throws when I try to perform the update as John Doe https://pastebin.com/zfNiWrxw

Does the update mean that all is working well now?

The update means the @Authorized annotation is working fine but I still have the problem with context.requirePrivilege(“some privilege”) and the requiredPrivilege field for apps. Those don’t seem to be working as I still get access through users that don’t have the required privilege.

Is everything committed?

Yes it is.

Now that you describe it this way I think I know the issue: we have a big piece of tech debt around privileges.

In the reference application, all users are by default given full access to all API privileges (e.g. any privilege that doesn’t start with “App:” or “Task:”).

The way this works is that there’s a “Privilege Level: Full” role and the emrapi module automatically puts privileges in it here.

Thanks @darius for this clarification. So to bypass this I have to rename my privileges to start with "App: "?

Actually make it start with "Task: ".

The way the Reference Application is built, the (UI) application-level privileges are App and Task privileges. App privileges basically would mean showing an app on your home screen, and Task privileges are for individual functions within an app.

Some examples: https://github.com/openmrs/openmrs-module-referencemetadata/blob/master/api/src/main/java/org/openmrs/module/referencemetadata/RolePrivilegeMetadata.java

Thanks @darius