Add TLS support to ingest GSuite LDAP data

Signed-off-by: Praphull Purohit <praphull.purohit@truecaller.com>
This commit is contained in:
Praphull Purohit
2024-03-01 12:34:48 +01:00
parent 1f553d2728
commit 019e13c2b0
7 changed files with 50 additions and 10 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-ldap': patch
---
Add TLS support to ingest GSuite LDAP data
@@ -39,8 +39,8 @@
"@backstage/plugin-catalog-common": "workspace:^",
"@backstage/plugin-catalog-node": "workspace:^",
"@backstage/types": "workspace:^",
"@types/ldapjs": "^2.2.0",
"ldapjs": "^2.2.0",
"@types/ldapjs": "^2.2.5",
"ldapjs": "^2.3.3",
"lodash": "^4.17.21",
"uuid": "^9.0.0",
"winston": "^3.2.1"
@@ -15,8 +15,10 @@
*/
import { ForwardedError, stringifyError } from '@backstage/errors';
import * as fs from 'fs';
import ldap, { Client, SearchEntry, SearchOptions } from 'ldapjs';
import { cloneDeep } from 'lodash';
import tlsLib from 'tls';
import { Logger } from 'winston';
import { BindConfig, TLSConfig } from './config';
import { createOptions, errorString } from './util';
@@ -44,9 +46,28 @@ export class LdapClient {
bind?: BindConfig,
tls?: TLSConfig,
): Promise<LdapClient> {
const readTLSOptionFile = (file?: string) =>
file !== undefined ? fs.readFileSync(file).toString() : undefined;
const getTlsOptions = () => {
const certs = readTLSOptionFile(tls?.certs);
const keys = readTLSOptionFile(tls?.keys);
if (certs !== undefined || keys !== undefined) {
return {
secureContext: tlsLib.createSecureContext({
cert: certs,
key: keys,
}),
rejectUnauthorized: tls?.rejectUnauthorized,
};
}
return tls;
};
const client = ldap.createClient({
url: target,
tlsOptions: tls,
tlsOptions: getTlsOptions(),
});
// We want to have a catch-all error handler at the top, since the default
@@ -80,7 +80,11 @@ describe('readLdapConfig', () => {
{
target: 'target',
bind: { dn: 'bdn', secret: 's' },
tls: { rejectUnauthorized: false },
tls: {
rejectUnauthorized: false,
keys: '/tmp/keys.pem',
certs: '/tmp/certs.pem',
},
users: {
dn: 'udn',
options: {
@@ -140,7 +144,11 @@ describe('readLdapConfig', () => {
{
target: 'target',
bind: { dn: 'bdn', secret: 's' },
tls: { rejectUnauthorized: false },
tls: {
rejectUnauthorized: false,
keys: '/tmp/keys.pem',
certs: '/tmp/certs.pem',
},
users: {
dn: 'udn',
options: {
@@ -49,6 +49,10 @@ export type LdapProviderConfig = {
export type TLSConfig = {
// Node TLS rejectUnauthorized
rejectUnauthorized?: boolean;
// A file containing private keys in PEM format
keys?: string;
// A file containing cert chains in PEM format
certs?: string;
};
/**
@@ -205,6 +209,8 @@ export function readLdapConfig(config: Config): LdapProviderConfig[] {
}
return {
rejectUnauthorized: c.getOptionalBoolean('rejectUnauthorized'),
keys: c.getOptionalString('keys'),
certs: c.getOptionalString('certs'),
};
}
@@ -105,7 +105,7 @@ function decode(
function formatGUID(objectGUID: string | Buffer): string {
let data: Buffer;
if (typeof objectGUID === 'string') {
data = new Buffer(objectGUID, 'binary');
data = Buffer.from(objectGUID, 'binary');
} else {
data = objectGUID;
}
+4 -4
View File
@@ -5672,9 +5672,9 @@ __metadata:
"@backstage/plugin-catalog-common": "workspace:^"
"@backstage/plugin-catalog-node": "workspace:^"
"@backstage/types": "workspace:^"
"@types/ldapjs": ^2.2.0
"@types/ldapjs": ^2.2.5
"@types/lodash": ^4.14.151
ldapjs: ^2.2.0
ldapjs: ^2.3.3
lodash: ^4.17.21
uuid: ^9.0.0
winston: ^3.2.1
@@ -19193,7 +19193,7 @@ __metadata:
languageName: node
linkType: hard
"@types/ldapjs@npm:^2.2.0":
"@types/ldapjs@npm:^2.2.5":
version: 2.2.5
resolution: "@types/ldapjs@npm:2.2.5"
dependencies:
@@ -33551,7 +33551,7 @@ __metadata:
languageName: node
linkType: hard
"ldapjs@npm:^2.2.0":
"ldapjs@npm:^2.3.3":
version: 2.3.3
resolution: "ldapjs@npm:2.3.3"
dependencies: