Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TRUNK-6203: Global properties access should be privileged #4601

Merged
merged 21 commits into from
Jun 26, 2024

Conversation

wikumChamith
Copy link
Contributor

@wikumChamith wikumChamith commented Mar 25, 2024

Description of what I changed

Adding @Authorized(PrivilegeConstants.GET_GLOBAL_PROPERTIES) annotation to throw an authentication exception if a user is not authenticated when requesting a global property. Used Context.addProxyPrivilege("Get Global Properties") to extend the privilege to anonymous users in tests and before login.

Issue I worked on

see https://openmrs.atlassian.net/browse/TRUNK-6203

Checklist: I completed these to help reviewers :)

  • My IDE is configured to follow the code style of this project.

    No? Unsure? -> configure your IDE, format the code and add the changes with git add . && git commit --amend

  • I have added tests to cover my changes. (If you refactored
    existing code that was well tested you do not have to add tests)

    No? -> write tests and add them to this commit git add . && git commit --amend

  • I ran mvn clean package right before creating this pull request and
    added all formatting changes to my commit.

    No? -> execute above command

  • All new and existing tests passed.

    No? -> figure out why and add the fix to your commit. It is your responsibility to make sure your code works.

  • My pull request is based on the latest changes of the master branch.

    No? Unsure? -> execute command git pull --rebase upstream master

@dkayiwa
Copy link
Member

dkayiwa commented Mar 27, 2024

@wikumChamith when you run these changes with the reference application modules, were you able to log in and load the main landing dashboard?

@wikumChamith
Copy link
Contributor Author

@dkayiwa Yes, Everything seems fine on my end.

@dkayiwa
Copy link
Member

dkayiwa commented Mar 28, 2024

@wikumChamith did you accidentally leave out the setGlobalProperty() method?

@wikumChamith
Copy link
Contributor Author

@dkayiwa I updated the PR.

@dkayiwa
Copy link
Member

dkayiwa commented Mar 28, 2024

@wikumChamith are you still able to run the reference application even with that change without getting errors?

@wikumChamith
Copy link
Contributor Author

@dkayiwa Yes, Are you getting any errors?

@dkayiwa
Copy link
Member

dkayiwa commented Mar 28, 2024

@wikumChamith have you also tested and confirmed that, with your changes, non logged in users can no longer access global properties as per the ticket requirements? In other words, anonymous users should get some sort of access denied errors when they try to access this: http://localhost:8080/openmrs/ws/rest/v1/systemsetting

@wikumChamith wikumChamith force-pushed the TRUNK-6203 branch 2 times, most recently from 82724fd to 37b5a03 Compare March 30, 2024 15:04
@wikumChamith
Copy link
Contributor Author

@dkayiwa, I've made updates to the PR. Additionally, I've created pull requests for the modules to enable anonymous users to access the login page.

openmrs-module-uiframework : openmrs/openmrs-module-uiframework#77
openmrs-module-referenceapplication : openmrs/openmrs-module-referenceapplication#104
openmrs-module-legacyui : openmrs/openmrs-module-legacyui#190

Regarding the openmrs-module-owa, I encountered an issue. We need to add the 'Get Global Properties' privilege to allow anonymous users to access the login page. However, the method in question (OwaFilter.java#L39) gets called by all requests. Adding Context.addProxyPrivilege(GET_GLOBAL_PROPERTIES) here would grant the privilege to all anonymous requests.

One potential solution I could think of is using request.getHeader("referer") to add the privilege only to requests originating from the login page. Do you have any alternative suggestions for addressing this issue?"

@dkayiwa
Copy link
Member

dkayiwa commented Mar 31, 2024

@wikumChamith how about if we intentionally expect this to fail until when accessed by a logged in user?

@wikumChamith
Copy link
Contributor Author

@dkayiwa main issue here is users won't be able to access the login page because of that.

@@ -588,9 +588,8 @@ public void getGlobalProperty_shouldFailIfUserHasNoPrivileges() {
Context.logout();
Context.authenticate(getTestUserCredentials());

APIException exception = assertThrows(APIException.class, () -> adminService.getGlobalProperty(property.getProperty()));
assertEquals(exception.getMessage(), String.format("Privilege: %s, required to view globalProperty: %s",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind explaining why you changed the contents of String.format()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format of the exception message changes after adding the authorization.

@wikumChamith
Copy link
Contributor Author

@dkayiwa I have created another PR for this using a different approach: #4617

What method do you suggest?

@dkayiwa
Copy link
Member

dkayiwa commented May 9, 2024

@dkayiwa I have created another PR for this using a different approach: #4617

What method do you suggest?

I think the approach in this pull request is simpler. Don't you think so?

@@ -57,6 +57,7 @@ public static Locale getDefaultLocale() {
if (defaultLocaleCache == null) {
if (Context.isSessionOpen()) {
try {
Context.addProxyPrivilege(PrivilegeConstants.GET_GLOBAL_PROPERTIES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this? Who calls it in the startup process?

}

/**
* Returns true if path matches pattern in gzip.acceptCompressedRequestsForPaths property
*/
private boolean isCompressedRequestForPathAccepted(String path) {
try {
Context.addProxyPrivilege(PrivilegeConstants.GET_GLOBAL_PROPERTIES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this? Who calls it in the startup process?

@@ -124,9 +125,9 @@ private boolean isGZIPEnabled() {
}

try {
Context.addProxyPrivilege(PrivilegeConstants.GET_GLOBAL_PROPERTIES);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also just catch the APIAuthenticationException here and log it, before returning false, in order to reduce the need to add proxy privileges. This is based on the fact that it is not a big deal for a not yet logged in user to miss gzip compression. They can have it after login.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wikumChamith i am changing my mind on this. I think it would be better to add the proxy privilege to avoid these unnecessary errors before login. :)

import org.openmrs.test.StartModule;
import org.openmrs.test.jupiter.BaseContextSensitiveTest;
import org.openmrs.util.RoleConstants;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to make any changes in this file?

@@ -21,8 +21,8 @@
<global_property property="valid.integer" property_value="1234" uuid="b7225607-d0c4-4e44-8be5-31e1ac7e1fda"/>
<global_property property="valid.double" property_value="1234.54" uuid="b7225607-d0c4-4e44-8be6-31e1ac7e1fda"/>

<privilege privilege="Some Privilege For View Global Properties" description="This is a test privilege for view global properties" uuid="d979d066-15e6-467c-9d4b-cb575ef12345"/>
<privilege privilege="Some Privilege For Edit Global Properties" description="This is a test privilege for edit global properties" uuid="d979d066-15e6-467c-9d4b-cb575ef54321"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we should change this file. Can't we do without these changes? The tests that expect these values should still do so.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changing this could lead to problems with tests. For an example let's consider the following test.

public void getGlobalPropertyObject_shouldReturnGlobalPropertyIfUserIsAllowedToView() {
executeDataSet(ADMIN_INITIAL_DATA_XML);
GlobalProperty property = getGlobalPropertyWithViewPrivilege();
// authenticate new user without privileges
Context.logout();
Context.authenticate(getTestUserCredentials());
// add required privilege to user
Role role = Context.getUserService().getRole("Provider");
role.addPrivilege(property.getViewPrivilege());
Context.getAuthenticatedUser().addRole(role);
assertNotNull(adminService.getGlobalPropertyObject(property.getProperty()));
}

If we keep the privilege name as "Some Privilege For View Global Properties," this test will fail with an error message stating:

org.openmrs.api.APIAuthenticationException: Privileges required: Get Global Properties

We could mitigate the error by adding Context.addProxyPrivilege(PrivilegeConstants.GET_GLOBAL_PROPERTIES);
However, this goes against the test's purpose: to validate that only users with the appropriate privilege can access global properties.

@@ -473,8 +475,14 @@ public void changePassword_shouldMatchOnIncorrectlyHashedSha1StoredPassword() {
executeDataSet(XML_FILENAME);
Context.logout();
Context.authenticate("incorrectlyhashedSha1", "test");

userService.changePassword("test", "Tester12");
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this try finally?

@@ -515,8 +523,13 @@ public void changePassword_shouldMatchOnCorrectlyHashedSha1StoredPassword() {
executeDataSet(XML_FILENAME);
Context.logout();
Context.authenticate("correctlyhashedSha1", "test");

userService.changePassword("test", "Tester12");
try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this try finally? And the ones below?

@dkayiwa
Copy link
Member

dkayiwa commented Jun 11, 2024

Try create a new server.

@wikumChamith
Copy link
Contributor Author

@dkayiwa I tested on both Reference Application 2.14.0-SNAPSHOT and 2.13.0. Looks like the issue is with the new SPA module. I'll look into this.

@dkayiwa
Copy link
Member

dkayiwa commented Jun 11, 2024

I'll look into this.

Awesome! Looking forward to the fix. 😊

@wikumChamith
Copy link
Contributor Author

wikumChamith commented Jun 19, 2024

@dkayiwa, I am encountering an issue when running the O2 reference application with these changes. Upon launching the server, I face a browser error stating:

localhost redirected you too many times.: ERR_TOO_MANY_REDIRECTS

Apart from this, the only backend error I saw during redirects:

INFO - uncaughtException_jsp._jspService(515) |2024-06-19T19:01:24,921| Exception was thrown by not authenticated user

It looks like the issue is related to the openmrs-module-referenceapplication as the legacy-ui login page is accessible without this module. I also tried giving proxy privileges in a few instances within the reference application module where global properties were accessed but that didn't resolve the issue.

Any insights on how to resolve this are highly appreciated.

@dkayiwa
Copy link
Member

dkayiwa commented Jun 19, 2024

@wikumChamith does this problem happen only with your modified version of openmrs-core?

@wikumChamith
Copy link
Contributor Author

@wikumChamith does this problem happen only with your modified version of openmrs-core?

Yeah. This only occurs on TRUNK-6203

@wikumChamith
Copy link
Contributor Author

wikumChamith commented Jun 19, 2024

@dkayiwa This fixes the issue: openmrs/openmrs-module-referenceapplication#105

Previously this didn't work for me because of another issue on my side.

try {
return Context.getConceptService().getConcept(Integer.valueOf(s));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wikumChamith is this supposed to be part of this pull request?

Copy link
Contributor Author

@wikumChamith wikumChamith Jun 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this from 😅 ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You better find out. 😊

pom.xml Outdated
@@ -942,7 +942,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<version>3.7.0</version>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to be part of this pul request?

@wikumChamith
Copy link
Contributor Author

@dkayiwa I think those two changes are from the rebase. They are similar to the current master:

Concept#hydrate

pom.xml

@dkayiwa
Copy link
Member

dkayiwa commented Jun 20, 2024

I do not care where they came from. All i want is not to see them here. 😊

@wikumChamith
Copy link
Contributor Author

@dkayiwa I removed those changes.

@wikumChamith
Copy link
Contributor Author

@dkayiwa I updated the PR.

@dkayiwa dkayiwa merged commit 95051a0 into openmrs:master Jun 26, 2024
11 checks passed
Wandji69 pushed a commit to Wandji69/openmrs-core that referenced this pull request Jun 27, 2024
* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* TRUNK-6203: Global properties access should be privileged

* Removing random changes

* Removing random changes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants