Open code1704 opened 15 hours ago
I'd say it should be possible some time in the future but don't know exactly when, my rough estimate is at least Q2 2025
CC: @Bonapara
Below is what Github copilot tells how to support LDAP. Will that work?
Based on the search results, there are no direct mentions of LDAP integration or support in the twentyhq/twenty
repository. However, there are multiple references to Single Sign-On (SSO) and various authentication methods.
Here are some relevant findings:
packages/twenty-website/src/content/developers/self-hosting/self-hosting-var.mdx
packages/twenty-front/src/modules/auth/sign-in-up/hooks/useSSO.ts
packages/twenty-server/src/engine/core-modules/auth/services/sign-in-up.service.ts
For LDAP integration, you might need to extend the current authentication services to support LDAP. This typically involves:
You can start by examining the existing SSO implementations and then add LDAP-specific logic and configuration.
To add LDAP (Active Directory) authentication support for the Twenty CRM repository, you would need to create or modify several files to integrate with LDAP. Below are the steps and example code snippets for integrating LDAP authentication:
Install LDAP Dependencies:
Ensure you have installed the necessary LDAP libraries. For Node.js, you can use ldapjs
.
npm install ldapjs
Add LDAP Configuration: Add LDAP configuration settings to your environment configuration file.
# LDAP Configuration
LDAP_URL=ldap://your-ldap-server.com
LDAP_BIND_DN=cn=read-only-admin,dc=example,dc=com
LDAP_BIND_PASSWORD=your-password
LDAP_SEARCH_BASE=dc=example,dc=com
LDAP_SEARCH_FILTER=(uid={{username}})
Create LDAP Authentication Service: Create a new service to handle LDAP authentication.
// packages/twenty-server/src/engine/core-modules/auth/services/ldap-auth.service.ts
import ldap from 'ldapjs';
export class LdapAuthService {
private client: ldap.Client;
constructor() {
this.client = ldap.createClient({
url: process.env.LDAP_URL,
});
}
private bindAdmin() {
return new Promise((resolve, reject) => {
this.client.bind(process.env.LDAP_BIND_DN, process.env.LDAP_BIND_PASSWORD, (err) => {
if (err) return reject(err);
resolve(true);
});
});
}
private searchUser(username: string) {
const opts = {
filter: process.env.LDAP_SEARCH_FILTER.replace('{{username}}', username),
scope: 'sub',
};
return new Promise((resolve, reject) => {
this.client.search(process.env.LDAP_SEARCH_BASE, opts, (err, res) => {
if (err) return reject(err);
let user = null;
res.on('searchEntry', (entry) => {
user = entry.object;
});
res.on('end', () => {
resolve(user);
});
res.on('error', (err) => {
reject(err);
});
});
});
}
private authenticateUser(dn: string, password: string) {
return new Promise((resolve, reject) => {
this.client.bind(dn, password, (err) => {
if (err) return reject(err);
resolve(true);
});
});
}
public async authenticate(username: string, password: string) {
await this.bindAdmin();
const user: any = await this.searchUser(username);
if (!user) throw new Error('User not found');
await this.authenticateUser(user.dn, password);
return user;
}
}
Integrate LDAP Authentication in Sign-In Service: Modify the sign-in service to include LDAP authentication.
// packages/twenty-server/src/engine/core-modules/auth/services/sign-in-up.service.ts
import { LdapAuthService } from './ldap-auth.service';
export class SignInUpService {
private ldapAuthService: LdapAuthService;
constructor() {
this.ldapAuthService = new LdapAuthService();
}
// Existing methods...
public async signInWithLdap(email: string, password: string) {
try {
const user = await this.ldapAuthService.authenticate(email, password);
// Handle the user object as needed, e.g., create a session, generate JWT, etc.
return user;
} catch (error) {
throw new AuthException('LDAP Authentication failed', AuthExceptionCode.INVALID_INPUT);
}
}
}
Update Routes and Controllers: Update your routes and controllers to handle LDAP sign-in requests.
// packages/twenty-server/src/engine/core-modules/auth/controllers/auth.controller.ts
import { SignInUpService } from '../services/sign-in-up.service';
export class AuthController {
private signInUpService: SignInUpService;
constructor() {
this.signInUpService = new SignInUpService();
}
public async signInLdap(req, res) {
const { email, password } = req.body;
try {
const user = await this.signInUpService.signInWithLdap(email, password);
res.status(200).json(user);
} catch (error) {
res.status(401).json({ message: 'LDAP Authentication failed' });
}
}
}
And update your routes:
// packages/twenty-server/src/engine/core-modules/auth/routes/auth.routes.ts
import express from 'express';
import { AuthController } from '../controllers/auth.controller';
const router = express.Router();
const authController = new AuthController();
router.post('/ldap-signin', authController.signInLdap.bind(authController));
export default router;
Test the Integration: Ensure you test the LDAP authentication thoroughly to handle various edge cases and errors.
This guide provides a basic structure for integrating LDAP authentication into the Twenty CRM application. You may need to adjust the code to fit the existing architecture and handle specific requirements.
Hi @code1704, we are about to add SAML and OIDC, with an estimated time of arrival in one month. Would that work for you? What additional benefits would LDAP provide?
Any plan to support LDAP Auth (like https://www.metabase.com/learn/metabase-basics/administration/permissions/ldap-auth-access-control)?