RocketChat / RocketChat/Rocket.Chat
Allow mixed-case usernames from LDAP
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 46.1k
- Forks
- 13.9k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 130
Description
Description:
When syncing LDAP users with Rocket.Chat users, the Username Field under Sync / Import in LDAP settings maps LDAP fields to Rocket.Chat usernames. However, all LDAP fields are converted to lowercase, preventing usernames like FirstnameLastname from working correctly. The lowercasing is done in the slug() function here:
https://github.com/RocketChat/Rocket.Chat/blob/db6aa025d0ce48e07ae58f94ed406d58867abcfc/packages/rocketchat-ldap/server/loginHandler.js#L95
https://github.com/RocketChat/Rocket.Chat/blob/dcdcbfba9eb10a4b87ad16f2628ec126444853d7/packages/rocketchat-ldap/server/sync.js#L183
Steps to reproduce:
- Enable LDAP logins via Administration > LDAP.
- Set
Username Fieldto#{givenName}#{sn}in Administration > LDAP > Sync / Import. - Have an existing Rocket.Chat user that matches the pattern above (e.g., username is
FirstnameLastname). - Have that user attempt to log in via LDAP.
Expected behavior:
User logs in as the FirstnameLastname username.
Actual behavior:
System tries to create a new user called firstnamelastname (all lowercase), which fails because the email address is already associated with FirstnameLastname username.
Server Setup Information:
- Version of Rocket.Chat Server: 0.69.2
- Operating System: Ubuntu 16.04.5 LTS
- Deployment Method: snap
- Number of Running Instances: 1
- DB Replicaset Oplog: Enabled
- NodeJS Version: v8.11.3
- MongoDB Version: 3.0.15
Additional context
In our case, we have imported a large HipChat export, and all usernames from HipChat are of the form FirstnameLastname. We successfully imported these users and messages, but when those users try to log in to Rocket.Chat via LDAP, their usernames map to firstnamelastname. At that point the system tries to create a new user, and it fails because of a collision with the email address already associated with the FirstnameLastname user.
Suggested resolution:
To preserve backwards compatibility with existing LDAP users, we suggest a checkbox field be added to LDAP Sync / Import settings for "Convert LDAP fields to lowercase in Username Field". If the new option is unchecked, the slug() function would be replaced with another function like slugMixedCase(), which would preserve mixed case usernames.
Relevant logs:
Example of an LDAP login for firstnamelastname when the FirstnameLastname user already exists:
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: rocketchat_logger rocketchat_logger.js:278 LDAPHandler ➔ error Error: User not Found
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at MethodInvocation.<anonymous> (/snap/rocketchat-server/1324/programs/server/packages/rocketchat_ldap.js:647:13)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at /snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:876:30
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at tryLoginMethod (/snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:702:14)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at AccountsServer.Ap._runLoginHandlers (/snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:875:18)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at AccountsServer.Accounts._runLoginHandlers (/snap/rocketchat-server/1324/programs/server/packages/rocketchat_lib.js:3335:36)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at MethodInvocation.methods.login (/snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:933:27)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at MethodInvocation.methodMap.(anonymous function) (packages/rocketchat_monitoring.js:2731:30)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at maybeAuditArgumentChecks (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:1877:12)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at DDP._CurrentMethodInvocation.withValue (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:902:126)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1186:12)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at DDPServer._CurrentWriteFence.withValue (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:902:98)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1186:12)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at Promise (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:902:46)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at new Promise (<anonymous>:null:null)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at Session.method (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:875:23)
Sep 19 12:20:56 chat rocketchat-server.rocketchat-server[8126]: at /snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:754:85
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: rocketchat_logger rocketchat_logger.js:278 LDAPSync ➔ error Error creating user { Error: Username already exists. [403]
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at handleError (/snap/rocketchat-server/1324/programs/server/packages/accounts-password.js:189:17)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at checkForCaseInsensitiveDuplicates (/snap/rocketchat-server/1324/programs/server/packages/accounts-password.js:334:7)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at createUser (/snap/rocketchat-server/1324/programs/server/packages/accounts-password.js:1240:3)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at AccountsServer.Accounts.createUser (/snap/rocketchat-server/1324/programs/server/packages/accounts-password.js:1302:10)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at addLdapUser (/snap/rocketchat-server/1324/programs/server/packages/rocketchat_ldap.js:1289:31)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at MethodInvocation.<anonymous> (/snap/rocketchat-server/1324/programs/server/packages/rocketchat_ldap.js:742:18)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at /snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:876:30
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at tryLoginMethod (/snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:702:14)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at AccountsServer.Ap._runLoginHandlers (/snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:875:18)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at AccountsServer.Accounts._runLoginHandlers (/snap/rocketchat-server/1324/programs/server/packages/rocketchat_lib.js:3335:36)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at MethodInvocation.methods.login (/snap/rocketchat-server/1324/programs/server/packages/accounts-base.js:933:27)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at MethodInvocation.methodMap.(anonymous function) (packages/rocketchat_monitoring.js:2731:30)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at maybeAuditArgumentChecks (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:1877:12)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at DDP._CurrentMethodInvocation.withValue (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:902:126)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1186:12)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at DDPServer._CurrentWriteFence.withValue (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:902:98)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1186:12)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at Promise (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:902:46)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at new Promise (<anonymous>:null:null)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at Session.method (/snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:875:23)
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: at /snap/rocketchat-server/1324/programs/server/packages/ddp-server.js:754:85
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: isClientSafe: true,
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: error: 403,
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: reason: 'Username already exists.',
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: details: undefined,
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: message: 'Username already exists. [403]',
Sep 19 12:22:21 chat rocketchat-server.rocketchat-server[8126]: errorType: 'Meteor.Error' }```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the slug() calls in packages/rocketchat-ldap/server/loginHandler.js around line 95 and packages/rocketchat-ldap/server/sync.js around line 183. Trace how the LDAP Username Field setting reaches these paths and how existing LDAP users are matched. Done means mixed-case usernames such as FirstnameLastname can log in without creating a lowercase duplicate, while existing lowercase behavior remains compatible.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- authentication
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100