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

FILTER-12: Setting "#####" placeholder for role names to avoid invalid SQL queries. #19

Merged
merged 8 commits into from
Jan 23, 2023

Conversation

Ruhanga
Copy link
Member

@Ruhanga Ruhanga commented Dec 8, 2022

@Ruhanga Ruhanga requested a review from mks-d December 8, 2022 14:11
Comment on lines 90 to 95
//Add '#####' place holder for non authenticated user
userProgramRoleNames.add("#####");
Collection<String> allProgramRoleNames = AccessUtil.getAllProgramRoles();
//Add '#####' place holder for non authenticated user
allProgramRoleNames.add("#####");

Copy link
Member

@mks-d mks-d Dec 8, 2022

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?

Copy link
Member Author

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.

@mks-d mks-d changed the title FILTER-12: Query placeholders to have default strings. FILTER-12: Setting "#####" placeholder for role names to avoid invalid SQL queries. Dec 8, 2022
Comment on lines 89 to 91
Collection<String> userProgramRoleNames = new HashSet();
//Add '#####' place holder for non authenticated user
userProgramRoleNames.add("#####");
Copy link
Member

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("#####"));

Copy link
Member Author

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.

Copy link
Member

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("#####");

Copy link
Member Author

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.

Copy link
Member

@mks-d mks-d left a comment

Choose a reason for hiding this comment

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

As per @wluyima's comment on FILTER-12, and now that you have put your finger on the needed fix, what would it take to

  1. revert back to the original code
  2. introduce a falling test illustrating the issue
  3. bring back your fix to make the test pass

?

Copy link
Member Author

@Ruhanga Ruhanga left a 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.

Comment on lines 28 to 30
@RunWith(PowerMockRunner.class)
@PrepareForTest({ AccessUtil.class, Context.class })
public class DataFilterListenerTest {
Copy link
Member

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?

Copy link
Member

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

Copy link
Member Author

@Ruhanga Ruhanga Dec 12, 2022

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()) {
Copy link
Member

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

Copy link
Member

@wluyima wluyima Dec 10, 2022

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.

Copy link
Member Author

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.

Copy link
Member

@wluyima wluyima Dec 12, 2022

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

Copy link
Member

Choose a reason for hiding this comment

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

@wluyima (I'm just being the messenger here), @Ruhanga is reporting that the faulty SQL syntax such as:

SELECT IN ()
  • fails with MySQL/MariaDB;
  • is in fact ok with H2.

Nathan is touching on that here already.

What do you recommend doing?

Copy link
Member

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?

Copy link
Member Author

@Ruhanga Ruhanga Dec 13, 2022

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.

Copy link
Member

@wluyima wluyima Dec 14, 2022

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

Copy link
Member Author

@Ruhanga Ruhanga Dec 14, 2022

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.

Copy link
Member Author

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.

Copy link
Member

@wluyima wluyima left a 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

Copy link
Member

@wluyima wluyima left a 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

Copy link
Member Author

@Ruhanga Ruhanga left a 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.

Copy link
Member Author

@Ruhanga Ruhanga left a 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.

@mks-d mks-d requested a review from wluyima January 19, 2023 10:07
Copy link
Member

@wluyima wluyima left a comment

Choose a reason for hiding this comment

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

Added comments

@Ruhanga
Copy link
Member Author

Ruhanga commented Jan 20, 2023

I've addressed the comments @wluyima, could you review again? Thanks.

Copy link
Member

@wluyima wluyima left a 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

@Ruhanga
Copy link
Member Author

Ruhanga commented Jan 20, 2023

Thanks @wluyima, I've addressed the final comments. I hope this can now be merged.... :-)

Copy link
Member

@wluyima wluyima left a 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

@mks-d mks-d merged commit f4d71b5 into openmrs:master Jan 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants