From f77c481d4ab4a7d80bf182849b66ad21b5721bea Mon Sep 17 00:00:00 2001 From: benjdlambert Date: Thu, 1 May 2025 14:40:05 +0200 Subject: [PATCH 1/5] feat: allow the ability to disable relations from one side of the relation graph Signed-off-by: benjdlambert --- .../catalog-backend-module-ldap/config.d.ts | 112 +++++++++++++++++- .../src/ldap/config.ts | 12 ++ .../src/ldap/read.test.ts | 97 +++++++++++++++ .../src/ldap/read.ts | 18 ++- 4 files changed, 232 insertions(+), 7 deletions(-) diff --git a/plugins/catalog-backend-module-ldap/config.d.ts b/plugins/catalog-backend-module-ldap/config.d.ts index 8bd8623891..5474108700 100644 --- a/plugins/catalog-backend-module-ldap/config.d.ts +++ b/plugins/catalog-backend-module-ldap/config.d.ts @@ -93,6 +93,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the memberOf attribute on the users to power the relations of users and groups + * + * @default false + */ + skipMemberOf?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -173,6 +184,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the memberOf attribute on the users to power the relations of users and groups + * + * @default false + */ + skipMemberOf?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -258,6 +280,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the member attributes on the groups to power the relations of users and groups + * + * @default false + */ + skipMembers?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -348,6 +381,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the member attributes on the groups to power the relations of users and groups + * + * @default false + */ + skipMembers?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -508,6 +552,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the memberOf attribute on the users to power the relations of users and groups + * + * @default false + */ + skipMemberOf?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -588,6 +643,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the memberOf attribute on the users to power the relations of users and groups + * + * @default false + */ + skipMemberOf?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -673,6 +739,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the member attributes on the groups to power the relations of users and groups + * + * @default false + */ + skipMembers?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -763,6 +840,17 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the member attributes on the groups to power the relations of users and groups + * + * @default false + */ + skipMembers?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -921,12 +1009,22 @@ export interface Config { pagePause?: boolean; }; }; + /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the memberOf attribute on the users to power the relations of users and groups + * + * @default false + */ + skipMemberOf?: boolean; + }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. * * This can be useful for example if you want to hard code a - * namespace or similar on the generated entities. */ set?: { [key: string]: JsonValue }; /** @@ -1006,6 +1104,18 @@ export interface Config { }; }; /** + * Additional parsing config + */ + parsing?: { + /** + * Whether to skip the member attributes on the groups to power the relations of users and groups + * + * @default false + */ + skipMembers?: boolean; + }; + /** + * @default false * JSON paths (on a.b.c form) and hard coded values to set on those * paths. * diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index 6fdf682b42..87951a9801 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -90,6 +90,12 @@ export type UserConfig = { // Only the scope, filter, attributes, and paged fields are supported. The // default is scope "one" and attributes "*" and "+". options: SearchOptions; + + // Additional parsing config + parsing?: { + // Whether to skip the memberOf attribute on the users to power the relations of users and groups + skipMemberOf?: boolean; + }; // JSON paths (on a.b.c form) and hard coded values to set on those paths set?: { [path: string]: JsonValue }; // Mappings from well known entity fields, to LDAP attribute names @@ -129,6 +135,12 @@ export type GroupConfig = { // The search options to use. // Only the scope, filter, attributes, and paged fields are supported. options: SearchOptions; + + // Additional parsing config + parsing?: { + // Whether to skip the members attribute on the groups to power the relations of users and groups + skipMembers?: boolean; + }; // JSON paths (on a.b.c form) and hard coded values to set on those paths set?: { [path: string]: JsonValue }; // Mappings from well known entity fields, to LDAP attribute names diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts index 4e4f4f7cfd..f1070ad1f0 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts @@ -210,6 +210,55 @@ describe('readLdapUsers', () => { ); }); + it('should allow skipping memberOf', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn(searchEntry({ memberOf: ['x', 'y', 'z'] })); + }); + + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + uid: ['uid-value'], + description: ['description-value'], + cn: ['cn-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + customDN: ['dn-value'], + customUUID: ['uuid-value'], + }), + ); + }); + const config: UserConfig[] = [ + { + dn: 'ddd', + options: {}, + parsing: { + skipMemberOf: true, + }, + map: { + rdn: 'uid', + name: 'uid', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + memberOf: 'memberOf', + }, + }, + ]; + + const vendorConfig: VendorConfig = { + dnAttributeName: 'customDN', + uuidAttributeName: 'customUUID', + }; + + const { userMemberOf } = await readLdapUsers(client, config, vendorConfig); + expect(userMemberOf.size).toBe(0); + }); + it('transfers all attributes from Microsoft Active Directory', async () => { client.getVendor.mockResolvedValue(ActiveDirectoryVendor); client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { @@ -729,6 +778,54 @@ describe('readLdapGroups', () => { ); }); + it('should allow skipping members', async () => { + client.getVendor.mockResolvedValue(DefaultLdapVendor); + client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { + await fn( + searchEntry({ + cn: ['cn-value'], + description: ['description-value'], + tt: ['type-value'], + mail: ['mail-value'], + avatarUrl: ['avatarUrl-value'], + memberOf: ['x', 'y', 'z'], + member: ['e', 'f', 'g'], + customDN: ['dn-value'], + customUUID: ['uuid-value'], + }), + ); + }); + const config: GroupConfig[] = [ + { + dn: 'ddd', + options: {}, + parsing: { + skipMembers: true, + }, + map: { + rdn: 'cn', + name: 'cn', + description: 'description', + displayName: 'cn', + email: 'mail', + picture: 'avatarUrl', + type: 'tt', + memberOf: 'memberOf', + members: 'member', + }, + }, + ]; + + const vendorConfig: VendorConfig = { + dnAttributeName: 'customDN', + uuidAttributeName: 'customUUID', + }; + + const { groupMember } = await readLdapGroups(client, config, vendorConfig); + + expect(groupMember.size).toBe(0); + }); + it('can process a list of GroupConfigs', async () => { client.getVendor.mockResolvedValue(DefaultLdapVendor); client.searchStreaming.mockImplementation(async (_dn, _opts, fn) => { diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.ts index 9b9041913d..aadaaae7cb 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.ts @@ -143,9 +143,12 @@ export async function readLdapUsers( return; } - mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { - ensureItems(userMemberOf, myDn, vs); - }); + if (!cfg.parsing?.skipMemberOf) { + mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { + ensureItems(userMemberOf, myDn, vs); + }); + } + entities.push(entity); }); } @@ -277,9 +280,12 @@ export async function readLdapGroups( mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => { ensureItems(groupMemberOf, myDn, vs); }); - mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { - ensureItems(groupMember, myDn, vs); - }); + + if (!cfg.parsing?.skipMembers) { + mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { + ensureItems(groupMember, myDn, vs); + }); + } groups.push(entity); }); From f07b0adafa4b22e3a3f828008ea334ad08f68564 Mon Sep 17 00:00:00 2001 From: benjdlambert Date: Thu, 1 May 2025 14:46:07 +0200 Subject: [PATCH 2/5] chore: add changeset Signed-off-by: benjdlambert Signed-off-by: benjdlambert --- .changeset/yellow-rats-argue.md | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .changeset/yellow-rats-argue.md diff --git a/.changeset/yellow-rats-argue.md b/.changeset/yellow-rats-argue.md new file mode 100644 index 0000000000..16f5468cb8 --- /dev/null +++ b/.changeset/yellow-rats-argue.md @@ -0,0 +1,38 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': patch +--- + +Added the ability to configure disabling one side of the relations tree with LDAP. + +Groups have a `member` attribute and users have a `memberOf` attribute, however these often can drift out of sync, leaving weird states in the Catalog as we collate these results together and deduplicate them. + +You can chose to optionally disable one side of these relationships, or even both by providing config in `app-config.yaml` under either the `GroupConfig` or `UserConfig`: + +```yaml +catalog: + providers: + ldapOrg: + default: + target: ldaps://ds.example.net + bind: + dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net + secret: ${LDAP_SECRET} + users: + - dn: ou=people,ou=example,dc=example,dc=net + options: + filter: (uid=*) + parsing: + # this defaults to false, to disable use the following: + skipMemberOf: true + groups: + - dn: ou=access,ou=groups,ou=example,dc=example,dc=net + options: + filter: (&(objectClass=some-group-class)(!(groupType=email))) + map: + description: l + set: + metadata.customField: 'hello' + parsing: + # this defaults to false, to disable use the following: + skipMember: true +``` From 2c0dd741e9d7bbec3fd462642af9ba9411a2d2a6 Mon Sep 17 00:00:00 2001 From: benjdlambert Date: Fri, 2 May 2025 09:35:00 +0200 Subject: [PATCH 3/5] chore: fixing api-report Signed-off-by: benjdlambert --- plugins/catalog-backend-module-ldap/report.api.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/catalog-backend-module-ldap/report.api.md b/plugins/catalog-backend-module-ldap/report.api.md index 16546cb773..9554f0ff19 100644 --- a/plugins/catalog-backend-module-ldap/report.api.md +++ b/plugins/catalog-backend-module-ldap/report.api.md @@ -52,6 +52,9 @@ export function defaultUserTransformer( export type GroupConfig = { dn: string; options: SearchOptions; + parsing?: { + skipMembers?: boolean; + }; set?: { [path: string]: JsonValue; }; @@ -249,6 +252,9 @@ export type TLSConfig = { export type UserConfig = { dn: string; options: SearchOptions; + parsing?: { + skipMemberOf?: boolean; + }; set?: { [path: string]: JsonValue; }; From e527d469989ee3bf48cac57e9b59b138bb5e3d99 Mon Sep 17 00:00:00 2001 From: benjdlambert Date: Tue, 6 May 2025 11:46:53 +0200 Subject: [PATCH 4/5] chore: refactor to set memberOf or member as null Signed-off-by: benjdlambert --- .../catalog-backend-module-ldap/config.d.ts | 141 ++---------------- .../src/ldap/config.ts | 6 +- .../src/ldap/read.test.ts | 11 +- 3 files changed, 22 insertions(+), 136 deletions(-) diff --git a/plugins/catalog-backend-module-ldap/config.d.ts b/plugins/catalog-backend-module-ldap/config.d.ts index 5474108700..f9b49eabee 100644 --- a/plugins/catalog-backend-module-ldap/config.d.ts +++ b/plugins/catalog-backend-module-ldap/config.d.ts @@ -93,17 +93,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the memberOf attribute on the users to power the relations of users and groups - * - * @default false - */ - skipMemberOf?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -152,7 +141,7 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.memberOf field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; }; } | Array<{ @@ -184,17 +173,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the memberOf attribute on the users to power the relations of users and groups - * - * @default false - */ - skipMemberOf?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -243,7 +221,7 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.memberOf field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; }; }>; @@ -280,17 +258,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the member attributes on the groups to power the relations of users and groups - * - * @default false - */ - skipMembers?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -344,12 +311,12 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.parent field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; /** * The name of the attribute that shall be used for the values of * the spec.children field of the entity. Defaults to "member". */ - members?: string; + members?: string | null; }; } | Array<{ @@ -381,17 +348,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the member attributes on the groups to power the relations of users and groups - * - * @default false - */ - skipMembers?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -445,12 +401,12 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.parent field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; /** * The name of the attribute that shall be used for the values of * the spec.children field of the entity. Defaults to "member". */ - members?: string; + members?: string | null; }; }>; /** @@ -552,17 +508,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the memberOf attribute on the users to power the relations of users and groups - * - * @default false - */ - skipMemberOf?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -611,7 +556,7 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.memberOf field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; }; } | Array<{ @@ -643,17 +588,7 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the memberOf attribute on the users to power the relations of users and groups - * - * @default false - */ - skipMemberOf?: boolean; - }; + /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -702,7 +637,7 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.memberOf field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; }; }>; @@ -739,17 +674,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the member attributes on the groups to power the relations of users and groups - * - * @default false - */ - skipMembers?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -803,12 +727,12 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.parent field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; /** * The name of the attribute that shall be used for the values of * the spec.children field of the entity. Defaults to "member". */ - members?: string; + members?: string | null; }; } | Array<{ @@ -840,17 +764,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the member attributes on the groups to power the relations of users and groups - * - * @default false - */ - skipMembers?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -904,12 +817,12 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.parent field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; /** * The name of the attribute that shall be used for the values of * the spec.children field of the entity. Defaults to "member". */ - members?: string; + members?: string | null; }; }>; @@ -1009,17 +922,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the memberOf attribute on the users to power the relations of users and groups - * - * @default false - */ - skipMemberOf?: boolean; - }; /** * JSON paths (on a.b.c form) and hard coded values to set on those * paths. @@ -1067,7 +969,7 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.memberOf field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; }; }; @@ -1103,17 +1005,6 @@ export interface Config { pagePause?: boolean; }; }; - /** - * Additional parsing config - */ - parsing?: { - /** - * Whether to skip the member attributes on the groups to power the relations of users and groups - * - * @default false - */ - skipMembers?: boolean; - }; /** * @default false * JSON paths (on a.b.c form) and hard coded values to set on those @@ -1168,12 +1059,12 @@ export interface Config { * The name of the attribute that shall be used for the values of * the spec.parent field of the entity. Defaults to "memberOf". */ - memberOf?: string; + memberOf?: string | null; /** * The name of the attribute that shall be used for the values of * the spec.children field of the entity. Defaults to "member". */ - members?: string; + members?: string | null; }; }; /** diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index 87951a9801..95e45f3d5f 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -120,7 +120,7 @@ export type UserConfig = { picture?: string; // The name of the attribute that shall be used for the values of the // spec.memberOf field of the entity. Defaults to "memberOf". - memberOf: string; + memberOf: string | null; }; }; @@ -168,10 +168,10 @@ export type GroupConfig = { picture?: string; // The name of the attribute that shall be used for the values of the // spec.parent field of the entity. Defaults to "memberOf". - memberOf: string; + memberOf: string | null; // The name of the attribute that shall be used for the values of the // spec.children field of the entity. Defaults to "member". - members: string; + members: string | null; }; }; diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts index f1070ad1f0..374cc2afd0 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.test.ts @@ -235,9 +235,7 @@ describe('readLdapUsers', () => { { dn: 'ddd', options: {}, - parsing: { - skipMemberOf: true, - }, + map: { rdn: 'uid', name: 'uid', @@ -245,7 +243,7 @@ describe('readLdapUsers', () => { displayName: 'cn', email: 'mail', picture: 'avatarUrl', - memberOf: 'memberOf', + memberOf: null, }, }, ]; @@ -799,9 +797,6 @@ describe('readLdapGroups', () => { { dn: 'ddd', options: {}, - parsing: { - skipMembers: true, - }, map: { rdn: 'cn', name: 'cn', @@ -811,7 +806,7 @@ describe('readLdapGroups', () => { picture: 'avatarUrl', type: 'tt', memberOf: 'memberOf', - members: 'member', + members: null, }, }, ]; From 0b41d0dd2cff3c7454667e1eb6d62bcce3315e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 16 Jun 2025 14:43:37 +0200 Subject: [PATCH 5/5] allow nulls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/yellow-rats-argue.md | 16 ++++++++-------- .../catalog-backend-module-ldap/report.api.md | 12 +++--------- .../src/ldap/config.ts | 10 ---------- .../src/ldap/read.ts | 18 +++++++----------- 4 files changed, 18 insertions(+), 38 deletions(-) diff --git a/.changeset/yellow-rats-argue.md b/.changeset/yellow-rats-argue.md index 16f5468cb8..321498fd37 100644 --- a/.changeset/yellow-rats-argue.md +++ b/.changeset/yellow-rats-argue.md @@ -4,9 +4,9 @@ Added the ability to configure disabling one side of the relations tree with LDAP. -Groups have a `member` attribute and users have a `memberOf` attribute, however these often can drift out of sync, leaving weird states in the Catalog as we collate these results together and deduplicate them. +Groups have a `member` attribute and users have a `memberOf` attribute, however these can drift out of sync in some LDAP installations, leaving weird states in the Catalog as we collate these results together and deduplicate them. -You can chose to optionally disable one side of these relationships, or even both by providing config in `app-config.yaml` under either the `GroupConfig` or `UserConfig`: +You can chose to optionally disable one side of these relationships, or even both by setting the respective mapping to `null` in your `app-config.yaml` for your groups and/or users: ```yaml catalog: @@ -21,9 +21,9 @@ catalog: - dn: ou=people,ou=example,dc=example,dc=net options: filter: (uid=*) - parsing: - # this defaults to false, to disable use the following: - skipMemberOf: true + map: + # this ensures that outgoing memberships from users is ignored + memberOf: null groups: - dn: ou=access,ou=groups,ou=example,dc=example,dc=net options: @@ -32,7 +32,7 @@ catalog: description: l set: metadata.customField: 'hello' - parsing: - # this defaults to false, to disable use the following: - skipMember: true + map: + # this ensures that outgoing memberships from groups is ignored + members: null ``` diff --git a/plugins/catalog-backend-module-ldap/report.api.md b/plugins/catalog-backend-module-ldap/report.api.md index 9554f0ff19..8357a9ae38 100644 --- a/plugins/catalog-backend-module-ldap/report.api.md +++ b/plugins/catalog-backend-module-ldap/report.api.md @@ -52,9 +52,6 @@ export function defaultUserTransformer( export type GroupConfig = { dn: string; options: SearchOptions; - parsing?: { - skipMembers?: boolean; - }; set?: { [path: string]: JsonValue; }; @@ -66,8 +63,8 @@ export type GroupConfig = { displayName: string; email?: string; picture?: string; - memberOf: string; - members: string; + memberOf: string | null; + members: string | null; }; }; @@ -252,9 +249,6 @@ export type TLSConfig = { export type UserConfig = { dn: string; options: SearchOptions; - parsing?: { - skipMemberOf?: boolean; - }; set?: { [path: string]: JsonValue; }; @@ -265,7 +259,7 @@ export type UserConfig = { displayName: string; email: string; picture?: string; - memberOf: string; + memberOf: string | null; }; }; diff --git a/plugins/catalog-backend-module-ldap/src/ldap/config.ts b/plugins/catalog-backend-module-ldap/src/ldap/config.ts index 95e45f3d5f..8c7fd0dda5 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/config.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/config.ts @@ -91,11 +91,6 @@ export type UserConfig = { // default is scope "one" and attributes "*" and "+". options: SearchOptions; - // Additional parsing config - parsing?: { - // Whether to skip the memberOf attribute on the users to power the relations of users and groups - skipMemberOf?: boolean; - }; // JSON paths (on a.b.c form) and hard coded values to set on those paths set?: { [path: string]: JsonValue }; // Mappings from well known entity fields, to LDAP attribute names @@ -136,11 +131,6 @@ export type GroupConfig = { // Only the scope, filter, attributes, and paged fields are supported. options: SearchOptions; - // Additional parsing config - parsing?: { - // Whether to skip the members attribute on the groups to power the relations of users and groups - skipMembers?: boolean; - }; // JSON paths (on a.b.c form) and hard coded values to set on those paths set?: { [path: string]: JsonValue }; // Mappings from well known entity fields, to LDAP attribute names diff --git a/plugins/catalog-backend-module-ldap/src/ldap/read.ts b/plugins/catalog-backend-module-ldap/src/ldap/read.ts index aadaaae7cb..a3f3ce1e75 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/read.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/read.ts @@ -143,11 +143,9 @@ export async function readLdapUsers( return; } - if (!cfg.parsing?.skipMemberOf) { - mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { - ensureItems(userMemberOf, myDn, vs); - }); - } + mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => { + ensureItems(userMemberOf, myDn, vs); + }); entities.push(entity); }); @@ -281,11 +279,9 @@ export async function readLdapGroups( ensureItems(groupMemberOf, myDn, vs); }); - if (!cfg.parsing?.skipMembers) { - mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { - ensureItems(groupMember, myDn, vs); - }); - } + mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => { + ensureItems(groupMember, myDn, vs); + }); groups.push(entity); }); @@ -355,7 +351,7 @@ export async function readLdapOrg( function mapReferencesAttr( entry: SearchEntry, vendor: LdapVendor, - attributeName: string | undefined, + attributeName: string | undefined | null, setter: (sourceDn: string, targets: string[]) => void, ) { if (attributeName) {