Uh oh!
There was an error while loading. Please reload this page.
Fix usernames being case sensitive - #123
Conversation
david-labs-ca
commented
Jun 23, 2025
So, John.doe and john.doe are same person? |
mgaffigan
commented
Jun 23, 2025
@david-labs-ca, there's discussion on the original ticket. I think the world at large usually assumes usernames to be case-insensitive. It's also just plum broken on several case-insensitive database engines in main, so if the decision were to make them case sensitive, a change would still be required. |
tonygermano
commented
Jun 24, 2025
I get angry any time I encounter a system with case-sensitive usernames. I expect to always be able to type my username in all lowercase, regardless of how the admin added it to the system. |
tonygermano
commented
Jul 2, 2025
suggestion: don't assume anything about which charset, collation, or locale are in use I think it would be a good idea to use |
mgaffigan
commented
Jul 7, 2025
@tonygermano Re: existing users, I've added a fallback to match case-sensitive if multiple users match. Adding a new user with a different casing fails with |
tonygermano
commented
Jul 14, 2025
@mgaffigan I don't think the PERSON table is expected to get very large where a scan would be a problem, and this seems evident because there isn't an index on USERNAME. In this case, I think it's better to be safe and use the standard SQL function without making assumptions about the environment rather than going for performance. LOWER should work across all databases respecting their current collation, character encoding, and locale. This is completely up to you, but if you want to address this issue, too, it's related nextgenhealthcare/connect#3386 |
6d64ab2 to
4f8bcddComparemgaffigan
commented
Nov 26, 2025
@tonygermano, I still think COLLATE is the correct way to do this - but I've updated it to use |
tonygermano
commented
Nov 29, 2025
@mgaffigan for completeness, what are your thoughts on updating |
mgaffigan
commented
Nov 29, 2025
If it will get the PR merged, I'm unopposed. I do not think it is called for, but I do not like From a maintenance perspective I think it is counterproductive to keep the different database server scripts in sync: I've never found SQL to be an actually portable language at scale (DDL aside, the query engines are too different). The appropriate interface for changing persistence is at the DAL - not at SQL. This also allows in memory stores for unit tests, no-SQL, etc. |
4f8bcdd to
1ff71d4CompareThere was a problem hiding this comment.
Pull request overview
This PR fixes an issue where usernames were treated as case-sensitive, making it inconsistent and potentially confusing for users. The implementation makes username comparisons case-insensitive across all supported database systems while preserving the original casing stored in the database and preferring exact case matches when multiple users exist with different casing (for backward compatibility).
Key changes:
- Modified database queries to use case-insensitive username comparison via
LOWER()function - Updated
getUser()method to handle potential multiple results and prefer exact case matches - Enhanced
LoginStatusto return the normalized username from the database to the client
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
server/src/com/mirth/connect/server/controllers/DefaultUserController.java | Updated getUser() to return lists and prefer case-sensitive matches; updated authorizeUser() to pass normalized username to LoginStatus |
server/dbconf/postgres/postgres-user.xml | Added case-insensitive username comparison using LOWER() function |
server/dbconf/sqlserver/sqlserver-user.xml | Added case-insensitive username comparison using LOWER() function |
server/dbconf/oracle/oracle-user.xml | Added case-insensitive username comparison using LOWER() function |
server/dbconf/mysql/mysql-user.xml | Added case-insensitive username comparison using LOWER() function |
server/dbconf/derby/derby-user.xml | Added case-insensitive username comparison using LOWER() function |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
pacmano1
left a comment
There was a problem hiding this comment.
I don't know how this will affect the user roles plugin from NG - maybe we don't care?
gibson9583
commented
Dec 14, 2025
We don't care. This will release in a version number unsupported by any open source NG release. With their plugin architecture change - bwc won't work either. |
mgaffigan
commented
Dec 14, 2025
@pacmano1, I can't see how it would be affected. No API changes in this PR, and the case sensitive username is still used after login. |
NicoPiel
left a comment
There was a problem hiding this comment.
Looks good overall. One thing to sanity-check: do we have any call paths where getUser(userId, userName) can be invoked with both args null? In that case selectList() + list.get(0) could yield non-deterministic behavior. If impossible by contract, might be worth a quick guard/comment.
kayyagari
left a comment
There was a problem hiding this comment.
The use of LOWER function made me pause for a while, but that is not a big deal, considering the number of rows person table contains in production deployments.
mgaffigan
commented
Dec 16, 2025
I don't follow. There's already a check to throw an exception when both are null. Perhaps I'm not understanding which getUser you are referring to. |
mgaffigan
commented
Dec 16, 2025
I agree. See prior discussion and edits away from COLLATE. |
tonygermano
commented
Dec 16, 2025
@kayyagari@mgaffigan Yes, it was edited for Oracle db at my request. I concede that it's not the most efficient method, but I think it is the most forgiving of whatever settings the users happen to have configured on their db (especially for non-English databases or alternate character encodings.) I think that's ok considering the likely size of this table, the fact that it isn't indexed in the first place, and the low frequency of this call. |
Signed-off-by: Mitch Gaffigan <mitch.gaffigan@comcast.net>
Signed-off-by: Mitch Gaffigan <mitch.gaffigan@comcast.net>
1ff71d4 to
43bcd32CompareUh oh!
There was an error while loading. Please reload this page.
Closes#122 / original #5569 by:
Implementation Notes:
LOWER()in pgsql instead of collation to avoid having to rely upon system defaults or database defined collation. Presumably table is not so large that sargability is a concern (since we're loading the full table to the client on each login)LOWER()