RocketChat / RocketChat/Rocket.Chat

Allow mixed-case usernames from LDAP

Open
#12,116 3 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: authentication
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:
  1. Enable LDAP logins via Administration > LDAP.
  2. Set Username Field to #{givenName}#{sn} in Administration > LDAP > Sync / Import.
  3. Have an existing Rocket.Chat user that matches the pattern above (e.g., username is FirstnameLastname).
  4. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.