-
Notifications
You must be signed in to change notification settings - Fork 13
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
FILTER-12: Setting "#####" placeholder for role names to avoid invalid SQL queries. #19
Conversation
//Add '#####' place holder for non authenticated user | ||
userProgramRoleNames.add("#####"); | ||
Collection<String> allProgramRoleNames = AccessUtil.getAllProgramRoles(); | ||
//Add '#####' place holder for non authenticated user | ||
allProgramRoleNames.add("#####"); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you always set those placeholders now, so then what about lines 102-110, are they still needed then?
Or if you want to keep lines 102-110, should you enclose your change in an if
that checks that the user is not authenticated?
Also, should the same logic not be added further up for the query involved here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you always set those placeholders now, so then what about lines 102-110, are they still needed then?
Yes the lines are needed. #####
is set as the default which is later overridden/filtered out if the user is authenticated.
Or if you want to keep lines 102-110, should you enclose your change in an if that checks that the user is not authenticated?
Let me arrange it then in a straight forward piece of code.
Also, should the same logic not be added further up for the query involved here?
No because that piece is not hit at-least by any api call trying to query the user table.
Collection<String> userProgramRoleNames = new HashSet(); | ||
//Add '#####' place holder for non authenticated user | ||
userProgramRoleNames.add("#####"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not this as a one-liner with the original (better) comment?
// Avoid a 'select IN ()' which would be an invalid query, in theory we expect no role to match #####
Collection<String> userProgramRoleNames = new HashSet<>(Arrays.asList("#####"));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Collection<String> userProgramRoleNames = new HashSet<>(Arrays.asList("#####"));
userProgramRoleNames
should be final in nature since it will be used with the Stream filtering following.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm suggesting a one-liner:
Collection<String> userProgramRoleNames = new HashSet<>(Arrays.asList("#####"));
instead of a two-liner:
Collection<String> userProgramRoleNames = new HashSet();
userProgramRoleNames.add("#####");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahhh, yes for sure. My bad, I my mind I was referring to allProgramRoleNames
. Let me apply the suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mks-d, this literally happens at runtime and would require a runtime environment perhaps also involving oauth2login and a MariaDb to produce a failing test.
@RunWith(PowerMockRunner.class) | ||
@PrepareForTest({ AccessUtil.class, Context.class }) | ||
public class DataFilterListenerTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ruhanga so there weren't any context-sensitive tests in which the malformed SQL exception would come out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree he should add a context sensitive test instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will affect all the other existing tests that depend on the underlying h2 database. I'll have to make them run as separate forks and modify the base filter test class to run on a MySQL/Maria DB as a test container docker container. If green light are on, I can go ahead.
if (Context.isAuthenticated()) { | ||
Collection<Role> userProgramRoles = Context.getAuthenticatedUser().getAllRoles().stream() | ||
.filter(r -> allProgramRoleNames.contains(r.getName())).collect(Collectors.toList()); | ||
|
||
userProgramRoleNames = userProgramRoles.stream().map(r -> r.getName()).collect(Collectors.toSet()); | ||
|
||
if (allProgramRoleNames.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this if clause and the one after it just need to be both moved out of their enclosing if clause to happen after and not before like you are doing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I think you need a context sensitive test to verify the fix, this should be a simple and straight forward test to put together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes but not when depending on the underlying H2 database env.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is just a test like any other context sensitive test, I don't see what the H2 database has to do with it, please explain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this if clause and the one after it just need to be both moved out of their enclosing if clause to happen after and not before like you are doing
@Ruhanga did you also see this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you also see this comment?
Yes @wluyima.
You don't have to set DATABASE_TO_LOWER
Ohh, ok sure. I was just demonstrating an example snippet of the database url. FWIW, simply setting the MODE without providing the corresponding databse url yields no difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I understand, why would you say the database url is not being provided
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to imply that appending MODE=MySQL
to the H2 overall URL requires an existing MySQL db sub url to work as expected. I.e. instead of
jdbc:h2:mem:openmrs;DB_CLOSE_DELAY=30;LOCK_TIMEOUT=10000;MODE=MySQL
I have to do some thing along the following line
jdbc:h2:localhost:<DATABASE_PORT>/openmrs?autoReconnect=true&sessionVariables=default_storage_engine%3DInnoDB&useUnicode=true&characterEncoding=UTF-8;MODE=MySQL
For the latter, I have to spin up a MySQL test container.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've produced a test demonstrating thrown error here #20. This uncovers bugs and breaks ~50% of the existing tests whose errors where silent with an H2 db env.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Context sensitive test needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @wluyima, I've updated the PR. Could you review again? Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @wluyima. Happy new year!!
A kind reminder to have a look into this. Hopefully all is fine.
api/src/main/java/org/openmrs/module/datafilter/impl/ImplDataFilterListener.java
Outdated
Show resolved
Hide resolved
api/src/main/java/org/openmrs/module/datafilter/impl/api/db/hibernate/InterceptorUtil.java
Outdated
Show resolved
Hide resolved
api/src/test/java/org/openmrs/module/datafilter/impl/DataFilterListenerTest.java
Outdated
Show resolved
Hide resolved
api/src/test/java/org/openmrs/module/datafilter/impl/UserProgramBasedFilterTest.java
Outdated
Show resolved
Hide resolved
api/src/test/java/org/openmrs/module/datafilter/impl/UserProgramBasedFilterTest.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments
I've addressed the comments @wluyima, could you review again? Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the stray format change in InterceptorUtil before merging the PR
api/src/main/java/org/openmrs/module/datafilter/impl/ImplDataFilterListener.java
Outdated
Show resolved
Hide resolved
Thanks @wluyima, I've addressed the final comments. I hope this can now be merged.... :-) |
api/src/test/java/org/openmrs/module/datafilter/impl/UserProgramBasedFilterTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one final comment, the PR is already approved and can be merged
Ticket: https://issues.openmrs.org/browse/FILTER-12