@backstage/plugin-catalog-backend-module-ldap 0.11.6-next.1 → 0.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @backstage/plugin-catalog-backend-module-ldap
2
2
 
3
+ ## 0.11.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 087d51d: Export LDAP vendor types and instances for testing custom transformers
8
+ - f07b0ad: Added the ability to configure disabling one side of the relations tree with LDAP.
9
+
10
+ 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.
11
+
12
+ 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:
13
+
14
+ ```yaml
15
+ catalog:
16
+ providers:
17
+ ldapOrg:
18
+ default:
19
+ target: ldaps://ds.example.net
20
+ bind:
21
+ dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net
22
+ secret: ${LDAP_SECRET}
23
+ users:
24
+ - dn: ou=people,ou=example,dc=example,dc=net
25
+ options:
26
+ filter: (uid=*)
27
+ map:
28
+ # this ensures that outgoing memberships from users is ignored
29
+ memberOf: null
30
+ groups:
31
+ - dn: ou=access,ou=groups,ou=example,dc=example,dc=net
32
+ options:
33
+ filter: (&(objectClass=some-group-class)(!(groupType=email)))
34
+ map:
35
+ description: l
36
+ set:
37
+ metadata.customField: 'hello'
38
+ map:
39
+ # this ensures that outgoing memberships from groups is ignored
40
+ members: null
41
+ ```
42
+
43
+ - Updated dependencies
44
+ - @backstage/plugin-catalog-node@1.17.1
45
+ - @backstage/backend-plugin-api@1.4.0
46
+ - @backstage/catalog-model@1.7.4
47
+ - @backstage/config@1.3.2
48
+ - @backstage/errors@1.2.7
49
+ - @backstage/types@1.2.1
50
+ - @backstage/plugin-catalog-common@1.1.4
51
+
3
52
  ## 0.11.6-next.1
4
53
 
5
54
  ### Patch Changes
package/config.d.ts CHANGED
@@ -141,7 +141,7 @@ export interface Config {
141
141
  * The name of the attribute that shall be used for the values of
142
142
  * the spec.memberOf field of the entity. Defaults to "memberOf".
143
143
  */
144
- memberOf?: string;
144
+ memberOf?: string | null;
145
145
  };
146
146
  }
147
147
  | Array<{
@@ -221,7 +221,7 @@ export interface Config {
221
221
  * The name of the attribute that shall be used for the values of
222
222
  * the spec.memberOf field of the entity. Defaults to "memberOf".
223
223
  */
224
- memberOf?: string;
224
+ memberOf?: string | null;
225
225
  };
226
226
  }>;
227
227
 
@@ -311,12 +311,12 @@ export interface Config {
311
311
  * The name of the attribute that shall be used for the values of
312
312
  * the spec.parent field of the entity. Defaults to "memberOf".
313
313
  */
314
- memberOf?: string;
314
+ memberOf?: string | null;
315
315
  /**
316
316
  * The name of the attribute that shall be used for the values of
317
317
  * the spec.children field of the entity. Defaults to "member".
318
318
  */
319
- members?: string;
319
+ members?: string | null;
320
320
  };
321
321
  }
322
322
  | Array<{
@@ -401,12 +401,12 @@ export interface Config {
401
401
  * The name of the attribute that shall be used for the values of
402
402
  * the spec.parent field of the entity. Defaults to "memberOf".
403
403
  */
404
- memberOf?: string;
404
+ memberOf?: string | null;
405
405
  /**
406
406
  * The name of the attribute that shall be used for the values of
407
407
  * the spec.children field of the entity. Defaults to "member".
408
408
  */
409
- members?: string;
409
+ members?: string | null;
410
410
  };
411
411
  }>;
412
412
  /**
@@ -556,7 +556,7 @@ export interface Config {
556
556
  * The name of the attribute that shall be used for the values of
557
557
  * the spec.memberOf field of the entity. Defaults to "memberOf".
558
558
  */
559
- memberOf?: string;
559
+ memberOf?: string | null;
560
560
  };
561
561
  }
562
562
  | Array<{
@@ -588,6 +588,7 @@ export interface Config {
588
588
  pagePause?: boolean;
589
589
  };
590
590
  };
591
+
591
592
  /**
592
593
  * JSON paths (on a.b.c form) and hard coded values to set on those
593
594
  * paths.
@@ -636,7 +637,7 @@ export interface Config {
636
637
  * The name of the attribute that shall be used for the values of
637
638
  * the spec.memberOf field of the entity. Defaults to "memberOf".
638
639
  */
639
- memberOf?: string;
640
+ memberOf?: string | null;
640
641
  };
641
642
  }>;
642
643
 
@@ -726,12 +727,12 @@ export interface Config {
726
727
  * The name of the attribute that shall be used for the values of
727
728
  * the spec.parent field of the entity. Defaults to "memberOf".
728
729
  */
729
- memberOf?: string;
730
+ memberOf?: string | null;
730
731
  /**
731
732
  * The name of the attribute that shall be used for the values of
732
733
  * the spec.children field of the entity. Defaults to "member".
733
734
  */
734
- members?: string;
735
+ members?: string | null;
735
736
  };
736
737
  }
737
738
  | Array<{
@@ -816,12 +817,12 @@ export interface Config {
816
817
  * The name of the attribute that shall be used for the values of
817
818
  * the spec.parent field of the entity. Defaults to "memberOf".
818
819
  */
819
- memberOf?: string;
820
+ memberOf?: string | null;
820
821
  /**
821
822
  * The name of the attribute that shall be used for the values of
822
823
  * the spec.children field of the entity. Defaults to "member".
823
824
  */
824
- members?: string;
825
+ members?: string | null;
825
826
  };
826
827
  }>;
827
828
 
@@ -926,7 +927,6 @@ export interface Config {
926
927
  * paths.
927
928
  *
928
929
  * This can be useful for example if you want to hard code a
929
- * namespace or similar on the generated entities.
930
930
  */
931
931
  set?: { [key: string]: JsonValue };
932
932
  /**
@@ -969,7 +969,7 @@ export interface Config {
969
969
  * The name of the attribute that shall be used for the values of
970
970
  * the spec.memberOf field of the entity. Defaults to "memberOf".
971
971
  */
972
- memberOf?: string;
972
+ memberOf?: string | null;
973
973
  };
974
974
  };
975
975
 
@@ -1006,6 +1006,7 @@ export interface Config {
1006
1006
  };
1007
1007
  };
1008
1008
  /**
1009
+ * @default false
1009
1010
  * JSON paths (on a.b.c form) and hard coded values to set on those
1010
1011
  * paths.
1011
1012
  *
@@ -1058,12 +1059,12 @@ export interface Config {
1058
1059
  * The name of the attribute that shall be used for the values of
1059
1060
  * the spec.parent field of the entity. Defaults to "memberOf".
1060
1061
  */
1061
- memberOf?: string;
1062
+ memberOf?: string | null;
1062
1063
  /**
1063
1064
  * The name of the attribute that shall be used for the values of
1064
1065
  * the spec.children field of the entity. Defaults to "member".
1065
1066
  */
1066
- members?: string;
1067
+ members?: string | null;
1067
1068
  };
1068
1069
  };
1069
1070
  /**
package/dist/index.cjs.js CHANGED
@@ -4,17 +4,21 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var LdapOrgEntityProvider = require('./processors/LdapOrgEntityProvider.cjs.js');
6
6
  var LdapOrgReaderProcessor = require('./processors/LdapOrgReaderProcessor.cjs.js');
7
+ var index = require('./ldap/index.cjs.js');
8
+ var module$1 = require('./module.cjs.js');
7
9
  var client = require('./ldap/client.cjs.js');
8
10
  var util = require('./ldap/util.cjs.js');
9
11
  var config = require('./ldap/config.cjs.js');
10
12
  var constants = require('./ldap/constants.cjs.js');
11
13
  var read = require('./ldap/read.cjs.js');
12
- var module$1 = require('./module.cjs.js');
13
14
 
14
15
 
15
16
 
16
17
  exports.LdapOrgEntityProvider = LdapOrgEntityProvider.LdapOrgEntityProvider;
17
18
  exports.LdapOrgReaderProcessor = LdapOrgReaderProcessor.LdapOrgReaderProcessor;
19
+ exports.vendors = index.vendors;
20
+ exports.default = module$1.catalogModuleLdapOrgEntityProvider;
21
+ exports.ldapOrgEntityProviderTransformsExtensionPoint = module$1.ldapOrgEntityProviderTransformsExtensionPoint;
18
22
  exports.LdapClient = client.LdapClient;
19
23
  exports.mapStringAttr = util.mapStringAttr;
20
24
  exports.readLdapLegacyConfig = config.readLdapLegacyConfig;
@@ -25,6 +29,4 @@ exports.LDAP_UUID_ANNOTATION = constants.LDAP_UUID_ANNOTATION;
25
29
  exports.defaultGroupTransformer = read.defaultGroupTransformer;
26
30
  exports.defaultUserTransformer = read.defaultUserTransformer;
27
31
  exports.readLdapOrg = read.readLdapOrg;
28
- exports.default = module$1.catalogModuleLdapOrgEntityProvider;
29
- exports.ldapOrgEntityProviderTransformsExtensionPoint = module$1.ldapOrgEntityProviderTransformsExtensionPoint;
30
32
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -3,11 +3,34 @@ import { EntityProvider, EntityProviderConnection, CatalogProcessor, CatalogProc
3
3
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
4
4
  import { SchedulerServiceTaskScheduleDefinition, LoggerService, SchedulerServiceTaskRunner, SchedulerService } from '@backstage/backend-plugin-api';
5
5
  import { JsonValue } from '@backstage/types';
6
- import { SearchOptions, SearchEntry, Client } from 'ldapjs';
6
+ import { SearchEntry, SearchOptions, Client } from 'ldapjs';
7
7
  import { UserEntity, GroupEntity } from '@backstage/catalog-model';
8
8
  import { LocationSpec } from '@backstage/plugin-catalog-common';
9
9
  import { UserTransformer as UserTransformer$1, GroupTransformer as GroupTransformer$1 } from '@backstage/plugin-catalog-backend-module-ldap';
10
10
 
11
+ /**
12
+ * An LDAP Vendor handles unique nuances between different vendors.
13
+ *
14
+ * @public
15
+ */
16
+ type LdapVendor = {
17
+ /**
18
+ * The attribute name that holds the distinguished name (DN) for an entry.
19
+ */
20
+ dnAttributeName: string;
21
+ /**
22
+ * The attribute name that holds a universal unique identifier for an entry.
23
+ */
24
+ uuidAttributeName: string;
25
+ /**
26
+ * Decode ldap entry values for a given attribute name to their string representation.
27
+ *
28
+ * @param entry - The ldap entry
29
+ * @param name - The attribute to decode
30
+ */
31
+ decodeStringAttribute: (entry: SearchEntry, name: string) => string[];
32
+ };
33
+
11
34
  /**
12
35
  * The configuration parameters for a single LDAP provider.
13
36
  *
@@ -60,7 +83,7 @@ type UserConfig = {
60
83
  displayName: string;
61
84
  email: string;
62
85
  picture?: string;
63
- memberOf: string;
86
+ memberOf: string | null;
64
87
  };
65
88
  };
66
89
  /**
@@ -82,8 +105,8 @@ type GroupConfig = {
82
105
  displayName: string;
83
106
  email?: string;
84
107
  picture?: string;
85
- memberOf: string;
86
- members: string;
108
+ memberOf: string | null;
109
+ members: string | null;
87
110
  };
88
111
  };
89
112
  /**
@@ -122,29 +145,6 @@ declare function readLdapLegacyConfig(config: Config): LdapProviderConfig[];
122
145
  */
123
146
  declare function readProviderConfigs(config: Config): LdapProviderConfig[];
124
147
 
125
- /**
126
- * An LDAP Vendor handles unique nuances between different vendors.
127
- *
128
- * @public
129
- */
130
- type LdapVendor = {
131
- /**
132
- * The attribute name that holds the distinguished name (DN) for an entry.
133
- */
134
- dnAttributeName: string;
135
- /**
136
- * The attribute name that holds a universal unique identifier for an entry.
137
- */
138
- uuidAttributeName: string;
139
- /**
140
- * Decode ldap entry values for a given attribute name to their string representation.
141
- *
142
- * @param entry - The ldap entry
143
- * @param name - The attribute to decode
144
- */
145
- decodeStringAttribute: (entry: SearchEntry, name: string) => string[];
146
- };
147
-
148
148
  /**
149
149
  * Basic wrapper for the `ldapjs` library.
150
150
  *
@@ -303,6 +303,20 @@ declare function readLdapOrg(client: LdapClient, userConfig: UserConfig[], group
303
303
  groups: GroupEntity[];
304
304
  }>;
305
305
 
306
+ /**
307
+ * An LDAP Vendor types.
308
+ *
309
+ * @public
310
+ */
311
+ declare const vendors: {
312
+ readonly activeDirectory: LdapVendor;
313
+ readonly aeDir: LdapVendor;
314
+ readonly freeIpa: LdapVendor;
315
+ readonly googleLdap: LdapVendor;
316
+ readonly lldap: LdapVendor;
317
+ readonly default: LdapVendor;
318
+ };
319
+
306
320
  /**
307
321
  * Options for {@link LdapOrgEntityProvider}.
308
322
  *
@@ -483,4 +497,4 @@ declare const ldapOrgEntityProviderTransformsExtensionPoint: _backstage_backend_
483
497
  */
484
498
  declare const catalogModuleLdapOrgEntityProvider: _backstage_backend_plugin_api.BackendFeature;
485
499
 
486
- export { type BindConfig, type GroupConfig, type GroupTransformer, LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, LDAP_UUID_ANNOTATION, LdapClient, LdapOrgEntityProvider, type LdapOrgEntityProviderLegacyOptions, type LdapOrgEntityProviderOptions, type LdapOrgEntityProviderTransformsExtensionPoint, LdapOrgReaderProcessor, type LdapProviderConfig, type LdapVendor, type TLSConfig, type UserConfig, type UserTransformer, type VendorConfig, catalogModuleLdapOrgEntityProvider as default, defaultGroupTransformer, defaultUserTransformer, ldapOrgEntityProviderTransformsExtensionPoint, mapStringAttr, readLdapLegacyConfig, readLdapOrg, readProviderConfigs };
500
+ export { type BindConfig, type GroupConfig, type GroupTransformer, LDAP_DN_ANNOTATION, LDAP_RDN_ANNOTATION, LDAP_UUID_ANNOTATION, LdapClient, LdapOrgEntityProvider, type LdapOrgEntityProviderLegacyOptions, type LdapOrgEntityProviderOptions, type LdapOrgEntityProviderTransformsExtensionPoint, LdapOrgReaderProcessor, type LdapProviderConfig, type LdapVendor, type TLSConfig, type UserConfig, type UserTransformer, type VendorConfig, catalogModuleLdapOrgEntityProvider as default, defaultGroupTransformer, defaultUserTransformer, ldapOrgEntityProviderTransformsExtensionPoint, mapStringAttr, readLdapLegacyConfig, readLdapOrg, readProviderConfigs, vendors };
@@ -1 +1 @@
1
- {"version":3,"file":"config.cjs.js","sources":["../../src/ldap/config.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SchedulerServiceTaskScheduleDefinition,\n readSchedulerServiceTaskScheduleDefinitionFromConfig,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { JsonValue } from '@backstage/types';\nimport { SearchOptions } from 'ldapjs';\nimport mergeWith from 'lodash/mergeWith';\nimport { trimEnd } from 'lodash';\nimport { RecursivePartial } from './util';\n\n/**\n * The configuration parameters for a single LDAP provider.\n *\n * @public\n */\nexport type LdapProviderConfig = {\n // The id of the\n id: string;\n // The prefix of the target that this matches on, e.g.\n // \"ldaps://ds.example.net\", with no trailing slash.\n target: string;\n // TLS settings\n tls?: TLSConfig;\n // The settings to use for the bind command. If none are specified, the bind\n // command is not issued.\n bind?: BindConfig;\n // The settings that govern the reading and interpretation of users\n users: UserConfig[];\n // The settings that govern the reading and interpretation of groups\n groups: GroupConfig[];\n // Schedule configuration for refresh tasks.\n schedule?: SchedulerServiceTaskScheduleDefinition;\n // Configuration for overriding the vendor-specific default attribute names.\n vendor?: VendorConfig;\n};\n\n/**\n * TLS settings\n *\n * @public\n */\nexport type TLSConfig = {\n // Node TLS rejectUnauthorized\n rejectUnauthorized?: boolean;\n // A file containing private keys in PEM format\n keys?: string;\n // A file containing cert chains in PEM format\n certs?: string;\n};\n\n/**\n * The settings to use for the a command.\n *\n * @public\n */\nexport type BindConfig = {\n // The DN of the user to auth as, e.g.\n // uid=ldap-robot,ou=robots,ou=example,dc=example,dc=net\n dn: string;\n // The secret of the user to auth as (its password)\n secret: string;\n};\n\n/**\n * The settings that govern the reading and interpretation of users.\n *\n * @public\n */\nexport type UserConfig = {\n // The DN under which users are stored.\n dn: string;\n // The search options to use.\n // Only the scope, filter, attributes, and paged fields are supported. The\n // default is scope \"one\" and attributes \"*\" and \"+\".\n options: SearchOptions;\n // JSON paths (on a.b.c form) and hard coded values to set on those paths\n set?: { [path: string]: JsonValue };\n // Mappings from well known entity fields, to LDAP attribute names\n map: {\n // The name of the attribute that holds the relative distinguished name of\n // each entry. Defaults to \"uid\".\n rdn: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.name field of the entity. Defaults to \"uid\".\n name: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.description field of the entity.\n description?: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.displayName field of the entity. Defaults to \"cn\".\n displayName: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.email field of the entity. Defaults to \"mail\".\n email: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.picture field of the entity.\n picture?: string;\n // The name of the attribute that shall be used for the values of the\n // spec.memberOf field of the entity. Defaults to \"memberOf\".\n memberOf: string;\n };\n};\n\n/**\n * The settings that govern the reading and interpretation of groups.\n *\n * @public\n */\nexport type GroupConfig = {\n // The DN under which groups are stored.\n dn: string;\n // The search options to use.\n // Only the scope, filter, attributes, and paged fields are supported.\n options: SearchOptions;\n // JSON paths (on a.b.c form) and hard coded values to set on those paths\n set?: { [path: string]: JsonValue };\n // Mappings from well known entity fields, to LDAP attribute names\n map: {\n // The name of the attribute that holds the relative distinguished name of\n // each entry. Defaults to \"cn\".\n rdn: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.name field of the entity. Defaults to \"cn\".\n name: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.description field of the entity. Defaults to \"description\".\n description: string;\n // The name of the attribute that shall be used for the value of the\n // spec.type field of the entity. Defaults to \"groupType\".\n type: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.displayName field of the entity. Defaults to \"cn\".\n displayName: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.email field of the entity.\n email?: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.picture field of the entity.\n picture?: string;\n // The name of the attribute that shall be used for the values of the\n // spec.parent field of the entity. Defaults to \"memberOf\".\n memberOf: string;\n // The name of the attribute that shall be used for the values of the\n // spec.children field of the entity. Defaults to \"member\".\n members: string;\n };\n};\n\n/**\n * Configuration for LDAP vendor-specific attributes.\n *\n * Allows custom attribute names for distinguished names (DN) and\n * universally unique identifiers (UUID) in LDAP directories.\n *\n * @public\n */\nexport type VendorConfig = {\n /**\n * Attribute name for the distinguished name (DN) of an entry,\n */\n dnAttributeName?: string;\n\n /**\n * Attribute name for the unique identifier (UUID) of an entry,\n */\n uuidAttributeName?: string;\n};\n\nconst defaultUserConfig = {\n options: {\n scope: 'one',\n attributes: ['*', '+'],\n },\n map: {\n rdn: 'uid',\n name: 'uid',\n displayName: 'cn',\n email: 'mail',\n memberOf: 'memberOf',\n },\n};\n\nconst defaultGroupConfig = {\n options: {\n scope: 'one',\n attributes: ['*', '+'],\n },\n map: {\n rdn: 'cn',\n name: 'cn',\n description: 'description',\n displayName: 'cn',\n type: 'groupType',\n memberOf: 'memberOf',\n members: 'member',\n },\n};\n\nfunction freeze<T>(data: T): T {\n return JSON.parse(JSON.stringify(data), (_key, value) => {\n if (typeof value === 'object' && value !== null) {\n Object.freeze(value);\n }\n return value;\n });\n}\n\nfunction readTlsConfig(\n c: Config | undefined,\n): LdapProviderConfig['tls'] | undefined {\n if (!c) {\n return undefined;\n }\n return {\n rejectUnauthorized: c.getOptionalBoolean('rejectUnauthorized'),\n keys: c.getOptionalString('keys'),\n certs: c.getOptionalString('certs'),\n };\n}\n\nfunction readBindConfig(\n c: Config | undefined,\n): LdapProviderConfig['bind'] | undefined {\n if (!c) {\n return undefined;\n }\n return {\n dn: c.getString('dn'),\n secret: c.getString('secret'),\n };\n}\n\nfunction readVendorConfig(\n c: Config | undefined,\n): LdapProviderConfig['vendor'] | undefined {\n if (!c) {\n return undefined;\n }\n return {\n dnAttributeName: c.getOptionalString('dnAttributeName'),\n uuidAttributeName: c.getOptionalString('uuidAttributeName'),\n };\n}\n\nfunction readOptionsConfig(c: Config | undefined): SearchOptions {\n if (!c) {\n return {};\n }\n\n const paged = readOptionsPagedConfig(c);\n\n return {\n scope: c.getOptionalString('scope') as SearchOptions['scope'],\n filter: formatFilter(c.getOptionalString('filter')),\n attributes: c.getOptionalStringArray('attributes'),\n sizeLimit: c.getOptionalNumber('sizeLimit'),\n timeLimit: c.getOptionalNumber('timeLimit'),\n derefAliases: c.getOptionalNumber('derefAliases'),\n typesOnly: c.getOptionalBoolean('typesOnly'),\n ...(paged !== undefined ? { paged } : undefined),\n };\n}\n\nfunction readOptionsPagedConfig(c: Config): SearchOptions['paged'] {\n const pagedConfig = c.getOptional('paged');\n if (pagedConfig === undefined) {\n return undefined;\n }\n\n if (pagedConfig === true || pagedConfig === false) {\n return pagedConfig;\n }\n\n const pageSize = c.getOptionalNumber('paged.pageSize');\n const pagePause = c.getOptionalBoolean('paged.pagePause');\n return {\n ...(pageSize !== undefined ? { pageSize } : undefined),\n ...(pagePause !== undefined ? { pagePause } : undefined),\n };\n}\n\nfunction readSetConfig(\n c: Config | undefined,\n): { [path: string]: JsonValue } | undefined {\n if (!c) {\n return undefined;\n }\n return c.get();\n}\n\nfunction readUserMapConfig(c: Config | undefined): Partial<UserConfig['map']> {\n if (!c) {\n return {};\n }\n\n return {\n rdn: c.getOptionalString('rdn'),\n name: c.getOptionalString('name'),\n description: c.getOptionalString('description'),\n displayName: c.getOptionalString('displayName'),\n email: c.getOptionalString('email'),\n picture: c.getOptionalString('picture'),\n memberOf: c.getOptionalString('memberOf'),\n };\n}\n\nfunction readGroupMapConfig(\n c: Config | undefined,\n): Partial<GroupConfig['map']> {\n if (!c) {\n return {};\n }\n\n return {\n rdn: c.getOptionalString('rdn'),\n name: c.getOptionalString('name'),\n description: c.getOptionalString('description'),\n type: c.getOptionalString('type'),\n displayName: c.getOptionalString('displayName'),\n email: c.getOptionalString('email'),\n picture: c.getOptionalString('picture'),\n memberOf: c.getOptionalString('memberOf'),\n members: c.getOptionalString('members'),\n };\n}\n\nfunction readUserConfig(\n c: Config | Config[] | undefined,\n): RecursivePartial<LdapProviderConfig['users']> {\n if (!c) {\n return [];\n }\n if (Array.isArray(c)) {\n return c.map(it => readSingleUserConfig(it));\n }\n return [readSingleUserConfig(c)];\n}\n\nfunction readSingleUserConfig(c: Config): RecursivePartial<UserConfig> {\n return {\n dn: c.getString('dn'),\n options: readOptionsConfig(c.getOptionalConfig('options')),\n set: readSetConfig(c.getOptionalConfig('set')),\n map: readUserMapConfig(c.getOptionalConfig('map')),\n };\n}\n\nfunction readGroupConfig(\n c: Config | Config[] | undefined,\n): RecursivePartial<LdapProviderConfig['groups']> {\n if (!c) {\n return [];\n }\n if (Array.isArray(c)) {\n return c.map(it => readSingleGroupConfig(it));\n }\n return [readSingleGroupConfig(c)];\n}\n\nfunction readSingleGroupConfig(c: Config): RecursivePartial<GroupConfig> {\n return {\n dn: c.getString('dn'),\n options: readOptionsConfig(c.getOptionalConfig('options')),\n set: readSetConfig(c.getOptionalConfig('set')),\n map: readGroupMapConfig(c.getOptionalConfig('map')),\n };\n}\n\nfunction formatFilter(filter?: string): string | undefined {\n // Remove extra whitespace between blocks to support multiline filters from the configuration\n return filter?.replace(/\\s*(\\(|\\))/g, '$1')?.trim();\n}\n\n/**\n * Parses configuration.\n *\n * @param config - The root of the LDAP config hierarchy\n *\n * @public\n * @deprecated This exists for backwards compatibility only and will be removed in the future.\n */\nexport function readLdapLegacyConfig(config: Config): LdapProviderConfig[] {\n const providerConfigs = config.getOptionalConfigArray('providers') ?? [];\n return providerConfigs.map(c => {\n const newConfig = {\n target: trimEnd(c.getString('target'), '/'),\n tls: readTlsConfig(c.getOptionalConfig('tls')),\n bind: readBindConfig(c.getOptionalConfig('bind')),\n users: readUserConfig(c.getConfig('users')).map(it => {\n return mergeWith({}, defaultUserConfig, it, replaceArraysIfPresent);\n }),\n groups: readGroupConfig(c.getConfig('groups')).map(it => {\n return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent);\n }),\n vendor: readVendorConfig(c.getOptionalConfig('vendor')),\n };\n\n return freeze(newConfig) as LdapProviderConfig;\n });\n}\n\n/**\n * Parses all configured providers.\n *\n * @param config - The root of the LDAP config hierarchy\n *\n * @public\n */\nexport function readProviderConfigs(config: Config): LdapProviderConfig[] {\n const providersConfig = config.getOptionalConfig('catalog.providers.ldapOrg');\n if (!providersConfig) {\n return [];\n }\n\n return providersConfig.keys().map(id => {\n const c = providersConfig.getConfig(id);\n const schedule = c.has('schedule')\n ? readSchedulerServiceTaskScheduleDefinitionFromConfig(\n c.getConfig('schedule'),\n )\n : undefined;\n\n const isUserList = Array.isArray(c.getOptional('users'));\n const isGroupList = Array.isArray(c.getOptional('groups'));\n\n const newConfig = {\n id,\n target: trimEnd(c.getString('target'), '/'),\n tls: readTlsConfig(c.getOptionalConfig('tls')),\n bind: readBindConfig(c.getOptionalConfig('bind')),\n users: readUserConfig(\n isUserList\n ? c.getOptionalConfigArray('users')\n : c.getOptionalConfig('users'),\n ).map(it => {\n return mergeWith({}, defaultUserConfig, it, replaceArraysIfPresent);\n }),\n groups: readGroupConfig(\n isGroupList\n ? c.getOptionalConfigArray('groups')\n : c.getOptionalConfig('groups'),\n ).map(it => {\n return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent);\n }),\n schedule,\n vendor: readVendorConfig(c.getOptionalConfig('vendor')),\n };\n\n return freeze(newConfig) as LdapProviderConfig;\n });\n}\n\nfunction replaceArraysIfPresent(_into: any, from: any) {\n // Replace arrays instead of merging, otherwise default behavior\n return Array.isArray(from) ? from : undefined;\n}\n"],"names":["trimEnd","mergeWith","readSchedulerServiceTaskScheduleDefinitionFromConfig"],"mappings":"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"}
1
+ {"version":3,"file":"config.cjs.js","sources":["../../src/ldap/config.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SchedulerServiceTaskScheduleDefinition,\n readSchedulerServiceTaskScheduleDefinitionFromConfig,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { JsonValue } from '@backstage/types';\nimport { SearchOptions } from 'ldapjs';\nimport mergeWith from 'lodash/mergeWith';\nimport { trimEnd } from 'lodash';\nimport { RecursivePartial } from './util';\n\n/**\n * The configuration parameters for a single LDAP provider.\n *\n * @public\n */\nexport type LdapProviderConfig = {\n // The id of the\n id: string;\n // The prefix of the target that this matches on, e.g.\n // \"ldaps://ds.example.net\", with no trailing slash.\n target: string;\n // TLS settings\n tls?: TLSConfig;\n // The settings to use for the bind command. If none are specified, the bind\n // command is not issued.\n bind?: BindConfig;\n // The settings that govern the reading and interpretation of users\n users: UserConfig[];\n // The settings that govern the reading and interpretation of groups\n groups: GroupConfig[];\n // Schedule configuration for refresh tasks.\n schedule?: SchedulerServiceTaskScheduleDefinition;\n // Configuration for overriding the vendor-specific default attribute names.\n vendor?: VendorConfig;\n};\n\n/**\n * TLS settings\n *\n * @public\n */\nexport type TLSConfig = {\n // Node TLS rejectUnauthorized\n rejectUnauthorized?: boolean;\n // A file containing private keys in PEM format\n keys?: string;\n // A file containing cert chains in PEM format\n certs?: string;\n};\n\n/**\n * The settings to use for the a command.\n *\n * @public\n */\nexport type BindConfig = {\n // The DN of the user to auth as, e.g.\n // uid=ldap-robot,ou=robots,ou=example,dc=example,dc=net\n dn: string;\n // The secret of the user to auth as (its password)\n secret: string;\n};\n\n/**\n * The settings that govern the reading and interpretation of users.\n *\n * @public\n */\nexport type UserConfig = {\n // The DN under which users are stored.\n dn: string;\n // The search options to use.\n // Only the scope, filter, attributes, and paged fields are supported. The\n // default is scope \"one\" and attributes \"*\" and \"+\".\n options: SearchOptions;\n\n // JSON paths (on a.b.c form) and hard coded values to set on those paths\n set?: { [path: string]: JsonValue };\n // Mappings from well known entity fields, to LDAP attribute names\n map: {\n // The name of the attribute that holds the relative distinguished name of\n // each entry. Defaults to \"uid\".\n rdn: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.name field of the entity. Defaults to \"uid\".\n name: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.description field of the entity.\n description?: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.displayName field of the entity. Defaults to \"cn\".\n displayName: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.email field of the entity. Defaults to \"mail\".\n email: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.picture field of the entity.\n picture?: string;\n // The name of the attribute that shall be used for the values of the\n // spec.memberOf field of the entity. Defaults to \"memberOf\".\n memberOf: string | null;\n };\n};\n\n/**\n * The settings that govern the reading and interpretation of groups.\n *\n * @public\n */\nexport type GroupConfig = {\n // The DN under which groups are stored.\n dn: string;\n // The search options to use.\n // Only the scope, filter, attributes, and paged fields are supported.\n options: SearchOptions;\n\n // JSON paths (on a.b.c form) and hard coded values to set on those paths\n set?: { [path: string]: JsonValue };\n // Mappings from well known entity fields, to LDAP attribute names\n map: {\n // The name of the attribute that holds the relative distinguished name of\n // each entry. Defaults to \"cn\".\n rdn: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.name field of the entity. Defaults to \"cn\".\n name: string;\n // The name of the attribute that shall be used for the value of the\n // metadata.description field of the entity. Defaults to \"description\".\n description: string;\n // The name of the attribute that shall be used for the value of the\n // spec.type field of the entity. Defaults to \"groupType\".\n type: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.displayName field of the entity. Defaults to \"cn\".\n displayName: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.email field of the entity.\n email?: string;\n // The name of the attribute that shall be used for the value of the\n // spec.profile.picture field of the entity.\n picture?: string;\n // The name of the attribute that shall be used for the values of the\n // spec.parent field of the entity. Defaults to \"memberOf\".\n memberOf: string | null;\n // The name of the attribute that shall be used for the values of the\n // spec.children field of the entity. Defaults to \"member\".\n members: string | null;\n };\n};\n\n/**\n * Configuration for LDAP vendor-specific attributes.\n *\n * Allows custom attribute names for distinguished names (DN) and\n * universally unique identifiers (UUID) in LDAP directories.\n *\n * @public\n */\nexport type VendorConfig = {\n /**\n * Attribute name for the distinguished name (DN) of an entry,\n */\n dnAttributeName?: string;\n\n /**\n * Attribute name for the unique identifier (UUID) of an entry,\n */\n uuidAttributeName?: string;\n};\n\nconst defaultUserConfig = {\n options: {\n scope: 'one',\n attributes: ['*', '+'],\n },\n map: {\n rdn: 'uid',\n name: 'uid',\n displayName: 'cn',\n email: 'mail',\n memberOf: 'memberOf',\n },\n};\n\nconst defaultGroupConfig = {\n options: {\n scope: 'one',\n attributes: ['*', '+'],\n },\n map: {\n rdn: 'cn',\n name: 'cn',\n description: 'description',\n displayName: 'cn',\n type: 'groupType',\n memberOf: 'memberOf',\n members: 'member',\n },\n};\n\nfunction freeze<T>(data: T): T {\n return JSON.parse(JSON.stringify(data), (_key, value) => {\n if (typeof value === 'object' && value !== null) {\n Object.freeze(value);\n }\n return value;\n });\n}\n\nfunction readTlsConfig(\n c: Config | undefined,\n): LdapProviderConfig['tls'] | undefined {\n if (!c) {\n return undefined;\n }\n return {\n rejectUnauthorized: c.getOptionalBoolean('rejectUnauthorized'),\n keys: c.getOptionalString('keys'),\n certs: c.getOptionalString('certs'),\n };\n}\n\nfunction readBindConfig(\n c: Config | undefined,\n): LdapProviderConfig['bind'] | undefined {\n if (!c) {\n return undefined;\n }\n return {\n dn: c.getString('dn'),\n secret: c.getString('secret'),\n };\n}\n\nfunction readVendorConfig(\n c: Config | undefined,\n): LdapProviderConfig['vendor'] | undefined {\n if (!c) {\n return undefined;\n }\n return {\n dnAttributeName: c.getOptionalString('dnAttributeName'),\n uuidAttributeName: c.getOptionalString('uuidAttributeName'),\n };\n}\n\nfunction readOptionsConfig(c: Config | undefined): SearchOptions {\n if (!c) {\n return {};\n }\n\n const paged = readOptionsPagedConfig(c);\n\n return {\n scope: c.getOptionalString('scope') as SearchOptions['scope'],\n filter: formatFilter(c.getOptionalString('filter')),\n attributes: c.getOptionalStringArray('attributes'),\n sizeLimit: c.getOptionalNumber('sizeLimit'),\n timeLimit: c.getOptionalNumber('timeLimit'),\n derefAliases: c.getOptionalNumber('derefAliases'),\n typesOnly: c.getOptionalBoolean('typesOnly'),\n ...(paged !== undefined ? { paged } : undefined),\n };\n}\n\nfunction readOptionsPagedConfig(c: Config): SearchOptions['paged'] {\n const pagedConfig = c.getOptional('paged');\n if (pagedConfig === undefined) {\n return undefined;\n }\n\n if (pagedConfig === true || pagedConfig === false) {\n return pagedConfig;\n }\n\n const pageSize = c.getOptionalNumber('paged.pageSize');\n const pagePause = c.getOptionalBoolean('paged.pagePause');\n return {\n ...(pageSize !== undefined ? { pageSize } : undefined),\n ...(pagePause !== undefined ? { pagePause } : undefined),\n };\n}\n\nfunction readSetConfig(\n c: Config | undefined,\n): { [path: string]: JsonValue } | undefined {\n if (!c) {\n return undefined;\n }\n return c.get();\n}\n\nfunction readUserMapConfig(c: Config | undefined): Partial<UserConfig['map']> {\n if (!c) {\n return {};\n }\n\n return {\n rdn: c.getOptionalString('rdn'),\n name: c.getOptionalString('name'),\n description: c.getOptionalString('description'),\n displayName: c.getOptionalString('displayName'),\n email: c.getOptionalString('email'),\n picture: c.getOptionalString('picture'),\n memberOf: c.getOptionalString('memberOf'),\n };\n}\n\nfunction readGroupMapConfig(\n c: Config | undefined,\n): Partial<GroupConfig['map']> {\n if (!c) {\n return {};\n }\n\n return {\n rdn: c.getOptionalString('rdn'),\n name: c.getOptionalString('name'),\n description: c.getOptionalString('description'),\n type: c.getOptionalString('type'),\n displayName: c.getOptionalString('displayName'),\n email: c.getOptionalString('email'),\n picture: c.getOptionalString('picture'),\n memberOf: c.getOptionalString('memberOf'),\n members: c.getOptionalString('members'),\n };\n}\n\nfunction readUserConfig(\n c: Config | Config[] | undefined,\n): RecursivePartial<LdapProviderConfig['users']> {\n if (!c) {\n return [];\n }\n if (Array.isArray(c)) {\n return c.map(it => readSingleUserConfig(it));\n }\n return [readSingleUserConfig(c)];\n}\n\nfunction readSingleUserConfig(c: Config): RecursivePartial<UserConfig> {\n return {\n dn: c.getString('dn'),\n options: readOptionsConfig(c.getOptionalConfig('options')),\n set: readSetConfig(c.getOptionalConfig('set')),\n map: readUserMapConfig(c.getOptionalConfig('map')),\n };\n}\n\nfunction readGroupConfig(\n c: Config | Config[] | undefined,\n): RecursivePartial<LdapProviderConfig['groups']> {\n if (!c) {\n return [];\n }\n if (Array.isArray(c)) {\n return c.map(it => readSingleGroupConfig(it));\n }\n return [readSingleGroupConfig(c)];\n}\n\nfunction readSingleGroupConfig(c: Config): RecursivePartial<GroupConfig> {\n return {\n dn: c.getString('dn'),\n options: readOptionsConfig(c.getOptionalConfig('options')),\n set: readSetConfig(c.getOptionalConfig('set')),\n map: readGroupMapConfig(c.getOptionalConfig('map')),\n };\n}\n\nfunction formatFilter(filter?: string): string | undefined {\n // Remove extra whitespace between blocks to support multiline filters from the configuration\n return filter?.replace(/\\s*(\\(|\\))/g, '$1')?.trim();\n}\n\n/**\n * Parses configuration.\n *\n * @param config - The root of the LDAP config hierarchy\n *\n * @public\n * @deprecated This exists for backwards compatibility only and will be removed in the future.\n */\nexport function readLdapLegacyConfig(config: Config): LdapProviderConfig[] {\n const providerConfigs = config.getOptionalConfigArray('providers') ?? [];\n return providerConfigs.map(c => {\n const newConfig = {\n target: trimEnd(c.getString('target'), '/'),\n tls: readTlsConfig(c.getOptionalConfig('tls')),\n bind: readBindConfig(c.getOptionalConfig('bind')),\n users: readUserConfig(c.getConfig('users')).map(it => {\n return mergeWith({}, defaultUserConfig, it, replaceArraysIfPresent);\n }),\n groups: readGroupConfig(c.getConfig('groups')).map(it => {\n return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent);\n }),\n vendor: readVendorConfig(c.getOptionalConfig('vendor')),\n };\n\n return freeze(newConfig) as LdapProviderConfig;\n });\n}\n\n/**\n * Parses all configured providers.\n *\n * @param config - The root of the LDAP config hierarchy\n *\n * @public\n */\nexport function readProviderConfigs(config: Config): LdapProviderConfig[] {\n const providersConfig = config.getOptionalConfig('catalog.providers.ldapOrg');\n if (!providersConfig) {\n return [];\n }\n\n return providersConfig.keys().map(id => {\n const c = providersConfig.getConfig(id);\n const schedule = c.has('schedule')\n ? readSchedulerServiceTaskScheduleDefinitionFromConfig(\n c.getConfig('schedule'),\n )\n : undefined;\n\n const isUserList = Array.isArray(c.getOptional('users'));\n const isGroupList = Array.isArray(c.getOptional('groups'));\n\n const newConfig = {\n id,\n target: trimEnd(c.getString('target'), '/'),\n tls: readTlsConfig(c.getOptionalConfig('tls')),\n bind: readBindConfig(c.getOptionalConfig('bind')),\n users: readUserConfig(\n isUserList\n ? c.getOptionalConfigArray('users')\n : c.getOptionalConfig('users'),\n ).map(it => {\n return mergeWith({}, defaultUserConfig, it, replaceArraysIfPresent);\n }),\n groups: readGroupConfig(\n isGroupList\n ? c.getOptionalConfigArray('groups')\n : c.getOptionalConfig('groups'),\n ).map(it => {\n return mergeWith({}, defaultGroupConfig, it, replaceArraysIfPresent);\n }),\n schedule,\n vendor: readVendorConfig(c.getOptionalConfig('vendor')),\n };\n\n return freeze(newConfig) as LdapProviderConfig;\n });\n}\n\nfunction replaceArraysIfPresent(_into: any, from: any) {\n // Replace arrays instead of merging, otherwise default behavior\n return Array.isArray(from) ? from : undefined;\n}\n"],"names":["trimEnd","mergeWith","readSchedulerServiceTaskScheduleDefinitionFromConfig"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ var vendors$1 = require('./vendors.cjs.js');
4
+ require('@backstage/errors');
5
+ require('fs/promises');
6
+ require('ldapjs');
7
+ require('lodash');
8
+ require('tls');
9
+ require('@backstage/backend-plugin-api');
10
+ require('lodash/mergeWith');
11
+ require('@backstage/catalog-model');
12
+ require('lodash/set');
13
+ require('lodash/cloneDeep');
14
+
15
+ const vendors = {
16
+ activeDirectory: vendors$1.ActiveDirectoryVendor,
17
+ aeDir: vendors$1.AEDirVendor,
18
+ freeIpa: vendors$1.FreeIpaVendor,
19
+ googleLdap: vendors$1.GoogleLdapVendor,
20
+ lldap: vendors$1.LLDAPVendor,
21
+ default: vendors$1.DefaultLdapVendor
22
+ };
23
+
24
+ exports.vendors = vendors;
25
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":["../../src/ldap/index.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ActiveDirectoryVendor,\n AEDirVendor,\n DefaultLdapVendor,\n FreeIpaVendor,\n GoogleLdapVendor,\n LdapVendor,\n LLDAPVendor,\n} from './vendors';\n\nexport { LdapClient } from './client';\nexport { mapStringAttr } from './util';\nexport { readProviderConfigs, readLdapLegacyConfig } from './config';\nexport type {\n LdapProviderConfig,\n GroupConfig,\n UserConfig,\n BindConfig,\n TLSConfig,\n VendorConfig,\n} from './config';\nexport type { LdapVendor } from './vendors';\nexport {\n LDAP_DN_ANNOTATION,\n LDAP_RDN_ANNOTATION,\n LDAP_UUID_ANNOTATION,\n} from './constants';\nexport {\n defaultGroupTransformer,\n defaultUserTransformer,\n readLdapOrg,\n} from './read';\nexport type { GroupTransformer, UserTransformer } from './types';\n/**\n * An LDAP Vendor types.\n *\n * @public\n */\nexport const vendors = {\n activeDirectory: ActiveDirectoryVendor as LdapVendor,\n aeDir: AEDirVendor as LdapVendor,\n freeIpa: FreeIpaVendor as LdapVendor,\n googleLdap: GoogleLdapVendor as LdapVendor,\n lldap: LLDAPVendor as LdapVendor,\n default: DefaultLdapVendor as LdapVendor,\n} as const;\n"],"names":["ActiveDirectoryVendor","AEDirVendor","FreeIpaVendor","GoogleLdapVendor","LLDAPVendor","DefaultLdapVendor"],"mappings":";;;;;;;;;;;;;;AAqDO,MAAM,OAAU,GAAA;AAAA,EACrB,eAAiB,EAAAA,+BAAA;AAAA,EACjB,KAAO,EAAAC,qBAAA;AAAA,EACP,OAAS,EAAAC,uBAAA;AAAA,EACT,UAAY,EAAAC,0BAAA;AAAA,EACZ,KAAO,EAAAC,qBAAA;AAAA,EACP,OAAS,EAAAC;AACX;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"read.cjs.js","sources":["../../src/ldap/read.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GroupEntity,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { SearchEntry } from 'ldapjs';\nimport lodashSet from 'lodash/set';\nimport cloneDeep from 'lodash/cloneDeep';\nimport { buildOrgHierarchy } from './org';\nimport { LdapClient } from './client';\nimport { GroupConfig, UserConfig, VendorConfig } from './config';\nimport {\n LDAP_DN_ANNOTATION,\n LDAP_RDN_ANNOTATION,\n LDAP_UUID_ANNOTATION,\n} from './constants';\nimport { LdapVendor } from './vendors';\nimport { GroupTransformer, UserTransformer } from './types';\nimport { mapStringAttr } from './util';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * User entity.\n *\n * @public\n */\nexport async function defaultUserTransformer(\n vendor: LdapVendor,\n config: UserConfig,\n entry: SearchEntry,\n): Promise<UserEntity | undefined> {\n const { set, map } = config;\n\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'User',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n profile: {},\n memberOf: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `User syncing failed: missing '${map.name}' attribute, consider applying a user filter to skip processing users with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads users out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The user data configuration\n * @param opts - Additional options\n */\nexport async function readLdapUsers(\n client: LdapClient,\n userConfig: UserConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: { transformer?: UserTransformer },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n userMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n}> {\n if (userConfig.length === 0) {\n return { users: [], userMemberOf: new Map() };\n }\n const entities: UserEntity[] = [];\n const userMemberOf: Map<string, Set<string>> = new Map();\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n const transformer = opts?.transformer ?? defaultUserTransformer;\n\n for (const cfg of userConfig) {\n const { dn, options, map } = cfg;\n await client.searchStreaming(dn, options, async user => {\n const entity = await transformer(vendor, cfg, user);\n\n if (!entity) {\n return;\n }\n\n mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(userMemberOf, myDn, vs);\n });\n entities.push(entity);\n });\n }\n\n return { users: entities, userMemberOf };\n}\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * Group entity.\n *\n * @public\n */\nexport async function defaultGroupTransformer(\n vendor: LdapVendor,\n config: GroupConfig,\n entry: SearchEntry,\n): Promise<GroupEntity | undefined> {\n const { set, map } = config;\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Group',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n type: 'unknown',\n profile: {},\n children: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `Group syncing failed: missing '${map.name}' attribute, consider applying a group filter to skip processing groups with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.type, v => {\n entity.spec.type = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The group data configuration\n * @param opts - Additional options\n */\nexport async function readLdapGroups(\n client: LdapClient,\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: {\n transformer?: GroupTransformer;\n },\n): Promise<{\n groups: GroupEntity[]; // With all relations empty\n groupMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n groupMember: Map<string, Set<string>>; // DN -> DN or UUID of groups & users\n}> {\n if (groupConfig.length === 0) {\n return { groups: [], groupMemberOf: new Map(), groupMember: new Map() };\n }\n const groups: GroupEntity[] = [];\n const groupMemberOf: Map<string, Set<string>> = new Map();\n const groupMember: Map<string, Set<string>> = new Map();\n\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n\n const transformer = opts?.transformer ?? defaultGroupTransformer;\n\n for (const cfg of groupConfig) {\n const { dn, map, options } = cfg;\n\n await client.searchStreaming(dn, options, async entry => {\n if (!entry) {\n return;\n }\n\n const entity = await transformer(vendor, cfg, entry);\n\n if (!entity) {\n return;\n }\n\n mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(groupMemberOf, myDn, vs);\n });\n mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => {\n ensureItems(groupMember, myDn, vs);\n });\n\n groups.push(entity);\n });\n }\n\n return {\n groups,\n groupMemberOf,\n groupMember,\n };\n}\n\n/**\n * Reads users and groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param userConfig - The user data configuration\n * @param groupConfig - The group data configuration\n * @param options - Additional options\n *\n * @public\n */\nexport async function readLdapOrg(\n client: LdapClient,\n userConfig: UserConfig[],\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n options: {\n groupTransformer?: GroupTransformer;\n userTransformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[];\n groups: GroupEntity[];\n}> {\n // Invokes the above \"raw\" read functions and stitches together the results\n // with all relations etc filled in.\n\n const { users, userMemberOf } = await readLdapUsers(\n client,\n userConfig,\n vendorConfig,\n {\n transformer: options?.userTransformer,\n },\n );\n const { groups, groupMemberOf, groupMember } = await readLdapGroups(\n client,\n groupConfig,\n vendorConfig,\n { transformer: options?.groupTransformer },\n );\n\n resolveRelations(groups, users, userMemberOf, groupMemberOf, groupMember);\n users.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n groups.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n\n return { users, groups };\n}\n\n//\n// Helpers\n//\n\n// Maps a multi-valued attribute of references to other objects, to a consumer\nfunction mapReferencesAttr(\n entry: SearchEntry,\n vendor: LdapVendor,\n attributeName: string | undefined,\n setter: (sourceDn: string, targets: string[]) => void,\n) {\n if (attributeName) {\n const values = vendor.decodeStringAttribute(entry, attributeName);\n const dn = vendor.decodeStringAttribute(entry, vendor.dnAttributeName);\n if (values && dn && dn.length === 1) {\n setter(dn[0], values);\n }\n }\n}\n\n// Inserts a number of values in a key-values mapping\nfunction ensureItems(\n target: Map<string, Set<string>>,\n key: string,\n values: string[],\n) {\n if (key) {\n let set = target.get(key);\n if (!set) {\n set = new Set();\n target.set(key, set);\n }\n for (const value of values) {\n if (value) {\n set!.add(value);\n }\n }\n }\n}\n\n/**\n * Helper function which dual searches the user/group maps first for original value, then for lowercased value.\n * @param map - The map of DN's user or group as the key usually multicased.\n * @param searchValue - The DN/memberOf search criteria which could potentially not match the map DN by case.\n * @returns The value/result of the search criteria dual searching.\n */\nfunction getValueFromMapWithInsensitiveKey(\n map: Map<string, any>,\n searchValue: string,\n) {\n const result = map.get(searchValue);\n return result ? result : map.get(searchValue.toLocaleLowerCase('en-US'));\n}\n\n/**\n * Takes groups and entities with empty relations, and fills in the various\n * relations that were returned by the readers, and forms the org hierarchy.\n *\n * @param groups - Group entities with empty relations; modified in place\n * @param users - User entities with empty relations; modified in place\n * @param userMemberOf - For a user DN, the set of group DNs or UUIDs that the\n * user is a member of\n * @param groupMemberOf - For a group DN, the set of group DNs or UUIDs that\n * the group is a member of (parents in the hierarchy)\n * @param groupMember - For a group DN, the set of group DNs or UUIDs that are\n * members of the group (children in the hierarchy)\n */\nexport function resolveRelations(\n groups: GroupEntity[],\n users: UserEntity[],\n userMemberOf: Map<string, Set<string>>,\n groupMemberOf: Map<string, Set<string>>,\n groupMember: Map<string, Set<string>>,\n) {\n // Build reference lookup tables - all of the relations that are output from\n // the above calls can be expressed as either DNs or UUIDs so we need to be\n // able to find by both, as well as the entity reference. Note that we expect them to not\n // collide here - this is a reasonable assumption as long as the fields are\n // the supported forms.\n const userMap: Map<string, UserEntity> = new Map(); // by entityRef, dn, uuid\n const groupMap: Map<string, GroupEntity> = new Map(); // by entityRef, dn, uuid\n for (const user of users) {\n userMap.set(stringifyEntityRef(user), user);\n userMap.set(user.metadata.annotations![LDAP_DN_ANNOTATION], user);\n userMap.set(\n user.metadata.annotations![LDAP_DN_ANNOTATION]?.toLocaleLowerCase(\n 'en-US',\n ),\n user,\n );\n userMap.set(user.metadata.annotations![LDAP_RDN_ANNOTATION], user);\n userMap.set(user.metadata.annotations![LDAP_UUID_ANNOTATION], user);\n }\n for (const group of groups) {\n groupMap.set(stringifyEntityRef(group), group);\n groupMap.set(group.metadata.annotations![LDAP_DN_ANNOTATION], group);\n groupMap.set(\n group.metadata.annotations![LDAP_DN_ANNOTATION]?.toLocaleLowerCase(\n 'en-US',\n ),\n group,\n );\n groupMap.set(group.metadata.annotations![LDAP_RDN_ANNOTATION], group);\n groupMap.set(group.metadata.annotations![LDAP_UUID_ANNOTATION], group);\n }\n\n // This can happen e.g. if entryUUID wasn't returned by the server\n userMap.delete('');\n groupMap.delete('');\n userMap.delete(undefined!);\n groupMap.delete(undefined!);\n\n // Fill in all of the immediate relations, now keyed on the entity reference. We\n // keep all parents at this point, whether the target model can support more\n // than one or not (it gets filtered farther down). And group children are\n // only groups in here.\n const newUserMemberOf: Map<string, Set<string>> = new Map();\n const newGroupParents: Map<string, Set<string>> = new Map();\n const newGroupChildren: Map<string, Set<string>> = new Map();\n\n // Resolve and store in the intermediaries. It may seem redundant that the\n // input data has both parent and children directions, as well as both\n // user->group and group->user - the reason is that different LDAP schemas\n // express relations in different directions. Some may have a user memberOf\n // overlay, some don't, for example.\n for (const [userN, groupsN] of userMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n for (const groupN of groupsN) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n ensureItems(newUserMemberOf, stringifyEntityRef(user), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, parentsN] of groupMemberOf.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const parentN of parentsN) {\n const parentGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n parentN,\n );\n if (parentGroup) {\n ensureItems(newGroupParents, stringifyEntityRef(group), [\n stringifyEntityRef(parentGroup),\n ]);\n ensureItems(newGroupChildren, stringifyEntityRef(parentGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, membersN] of groupMember.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const memberN of membersN) {\n // Group members can be both users and groups in the input model, so\n // try both\n const memberUser = getValueFromMapWithInsensitiveKey(userMap, memberN);\n if (memberUser) {\n ensureItems(newUserMemberOf, stringifyEntityRef(memberUser), [\n stringifyEntityRef(group),\n ]);\n } else {\n const memberGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n memberN,\n );\n if (memberGroup) {\n ensureItems(newGroupChildren, stringifyEntityRef(group), [\n stringifyEntityRef(memberGroup),\n ]);\n ensureItems(newGroupParents, stringifyEntityRef(memberGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n }\n\n // Write down the relations again into the actual entities\n for (const [userN, groupsN] of newUserMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n user.spec.memberOf = Array.from(groupsN).sort();\n }\n }\n for (const [groupN, parentsN] of newGroupParents.entries()) {\n if (parentsN.size === 1) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.parent = parentsN.values().next().value;\n }\n }\n }\n for (const [groupN, childrenN] of newGroupChildren.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.children = Array.from(childrenN).sort();\n }\n }\n\n // Fill out the rest of the hierarchy\n buildOrgHierarchy(groups);\n}\n"],"names":["lodashSet","cloneDeep","mapStringAttr","InputError","LDAP_RDN_ANNOTATION","LDAP_UUID_ANNOTATION","LDAP_DN_ANNOTATION","stringifyEntityRef","buildOrgHierarchy"],"mappings":"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"}
1
+ {"version":3,"file":"read.cjs.js","sources":["../../src/ldap/read.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n GroupEntity,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { SearchEntry } from 'ldapjs';\nimport lodashSet from 'lodash/set';\nimport cloneDeep from 'lodash/cloneDeep';\nimport { buildOrgHierarchy } from './org';\nimport { LdapClient } from './client';\nimport { GroupConfig, UserConfig, VendorConfig } from './config';\nimport {\n LDAP_DN_ANNOTATION,\n LDAP_RDN_ANNOTATION,\n LDAP_UUID_ANNOTATION,\n} from './constants';\nimport { LdapVendor } from './vendors';\nimport { GroupTransformer, UserTransformer } from './types';\nimport { mapStringAttr } from './util';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * User entity.\n *\n * @public\n */\nexport async function defaultUserTransformer(\n vendor: LdapVendor,\n config: UserConfig,\n entry: SearchEntry,\n): Promise<UserEntity | undefined> {\n const { set, map } = config;\n\n const entity: UserEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'User',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n profile: {},\n memberOf: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `User syncing failed: missing '${map.name}' attribute, consider applying a user filter to skip processing users with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads users out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The user data configuration\n * @param opts - Additional options\n */\nexport async function readLdapUsers(\n client: LdapClient,\n userConfig: UserConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: { transformer?: UserTransformer },\n): Promise<{\n users: UserEntity[]; // With all relations empty\n userMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n}> {\n if (userConfig.length === 0) {\n return { users: [], userMemberOf: new Map() };\n }\n const entities: UserEntity[] = [];\n const userMemberOf: Map<string, Set<string>> = new Map();\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n const transformer = opts?.transformer ?? defaultUserTransformer;\n\n for (const cfg of userConfig) {\n const { dn, options, map } = cfg;\n await client.searchStreaming(dn, options, async user => {\n const entity = await transformer(vendor, cfg, user);\n\n if (!entity) {\n return;\n }\n\n mapReferencesAttr(user, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(userMemberOf, myDn, vs);\n });\n\n entities.push(entity);\n });\n }\n\n return { users: entities, userMemberOf };\n}\n\n/**\n * The default implementation of the transformation from an LDAP entry to a\n * Group entity.\n *\n * @public\n */\nexport async function defaultGroupTransformer(\n vendor: LdapVendor,\n config: GroupConfig,\n entry: SearchEntry,\n): Promise<GroupEntity | undefined> {\n const { set, map } = config;\n const entity: GroupEntity = {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Group',\n metadata: {\n name: '',\n annotations: {},\n },\n spec: {\n type: 'unknown',\n profile: {},\n children: [],\n },\n };\n\n if (set) {\n for (const [path, value] of Object.entries(set)) {\n lodashSet(entity, path, cloneDeep(value));\n }\n }\n\n mapStringAttr(entry, vendor, map.name, v => {\n entity.metadata.name = v;\n });\n\n if (!entity.metadata.name) {\n throw new InputError(\n `Group syncing failed: missing '${map.name}' attribute, consider applying a group filter to skip processing groups with incomplete data.`,\n );\n }\n\n mapStringAttr(entry, vendor, map.description, v => {\n entity.metadata.description = v;\n });\n mapStringAttr(entry, vendor, map.rdn, v => {\n entity.metadata.annotations![LDAP_RDN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.uuidAttributeName, v => {\n entity.metadata.annotations![LDAP_UUID_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, vendor.dnAttributeName, v => {\n entity.metadata.annotations![LDAP_DN_ANNOTATION] = v;\n });\n mapStringAttr(entry, vendor, map.type, v => {\n entity.spec.type = v;\n });\n mapStringAttr(entry, vendor, map.displayName, v => {\n entity.spec.profile!.displayName = v;\n });\n mapStringAttr(entry, vendor, map.email, v => {\n entity.spec.profile!.email = v;\n });\n mapStringAttr(entry, vendor, map.picture, v => {\n entity.spec.profile!.picture = v;\n });\n\n return entity;\n}\n\n/**\n * Reads groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param config - The group data configuration\n * @param opts - Additional options\n */\nexport async function readLdapGroups(\n client: LdapClient,\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n opts?: {\n transformer?: GroupTransformer;\n },\n): Promise<{\n groups: GroupEntity[]; // With all relations empty\n groupMemberOf: Map<string, Set<string>>; // DN -> DN or UUID of groups\n groupMember: Map<string, Set<string>>; // DN -> DN or UUID of groups & users\n}> {\n if (groupConfig.length === 0) {\n return { groups: [], groupMemberOf: new Map(), groupMember: new Map() };\n }\n const groups: GroupEntity[] = [];\n const groupMemberOf: Map<string, Set<string>> = new Map();\n const groupMember: Map<string, Set<string>> = new Map();\n\n const vendorDefaults = await client.getVendor();\n const vendor: LdapVendor = {\n dnAttributeName:\n vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,\n uuidAttributeName:\n vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,\n decodeStringAttribute: vendorDefaults.decodeStringAttribute,\n };\n\n const transformer = opts?.transformer ?? defaultGroupTransformer;\n\n for (const cfg of groupConfig) {\n const { dn, map, options } = cfg;\n\n await client.searchStreaming(dn, options, async entry => {\n if (!entry) {\n return;\n }\n\n const entity = await transformer(vendor, cfg, entry);\n\n if (!entity) {\n return;\n }\n\n mapReferencesAttr(entry, vendor, map.memberOf, (myDn, vs) => {\n ensureItems(groupMemberOf, myDn, vs);\n });\n\n mapReferencesAttr(entry, vendor, map.members, (myDn, vs) => {\n ensureItems(groupMember, myDn, vs);\n });\n\n groups.push(entity);\n });\n }\n\n return {\n groups,\n groupMemberOf,\n groupMember,\n };\n}\n\n/**\n * Reads users and groups out of an LDAP provider.\n *\n * @param client - The LDAP client\n * @param userConfig - The user data configuration\n * @param groupConfig - The group data configuration\n * @param options - Additional options\n *\n * @public\n */\nexport async function readLdapOrg(\n client: LdapClient,\n userConfig: UserConfig[],\n groupConfig: GroupConfig[],\n vendorConfig: VendorConfig | undefined,\n options: {\n groupTransformer?: GroupTransformer;\n userTransformer?: UserTransformer;\n logger: LoggerService;\n },\n): Promise<{\n users: UserEntity[];\n groups: GroupEntity[];\n}> {\n // Invokes the above \"raw\" read functions and stitches together the results\n // with all relations etc filled in.\n\n const { users, userMemberOf } = await readLdapUsers(\n client,\n userConfig,\n vendorConfig,\n {\n transformer: options?.userTransformer,\n },\n );\n const { groups, groupMemberOf, groupMember } = await readLdapGroups(\n client,\n groupConfig,\n vendorConfig,\n { transformer: options?.groupTransformer },\n );\n\n resolveRelations(groups, users, userMemberOf, groupMemberOf, groupMember);\n users.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n groups.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name));\n\n return { users, groups };\n}\n\n//\n// Helpers\n//\n\n// Maps a multi-valued attribute of references to other objects, to a consumer\nfunction mapReferencesAttr(\n entry: SearchEntry,\n vendor: LdapVendor,\n attributeName: string | undefined | null,\n setter: (sourceDn: string, targets: string[]) => void,\n) {\n if (attributeName) {\n const values = vendor.decodeStringAttribute(entry, attributeName);\n const dn = vendor.decodeStringAttribute(entry, vendor.dnAttributeName);\n if (values && dn && dn.length === 1) {\n setter(dn[0], values);\n }\n }\n}\n\n// Inserts a number of values in a key-values mapping\nfunction ensureItems(\n target: Map<string, Set<string>>,\n key: string,\n values: string[],\n) {\n if (key) {\n let set = target.get(key);\n if (!set) {\n set = new Set();\n target.set(key, set);\n }\n for (const value of values) {\n if (value) {\n set!.add(value);\n }\n }\n }\n}\n\n/**\n * Helper function which dual searches the user/group maps first for original value, then for lowercased value.\n * @param map - The map of DN's user or group as the key usually multicased.\n * @param searchValue - The DN/memberOf search criteria which could potentially not match the map DN by case.\n * @returns The value/result of the search criteria dual searching.\n */\nfunction getValueFromMapWithInsensitiveKey(\n map: Map<string, any>,\n searchValue: string,\n) {\n const result = map.get(searchValue);\n return result ? result : map.get(searchValue.toLocaleLowerCase('en-US'));\n}\n\n/**\n * Takes groups and entities with empty relations, and fills in the various\n * relations that were returned by the readers, and forms the org hierarchy.\n *\n * @param groups - Group entities with empty relations; modified in place\n * @param users - User entities with empty relations; modified in place\n * @param userMemberOf - For a user DN, the set of group DNs or UUIDs that the\n * user is a member of\n * @param groupMemberOf - For a group DN, the set of group DNs or UUIDs that\n * the group is a member of (parents in the hierarchy)\n * @param groupMember - For a group DN, the set of group DNs or UUIDs that are\n * members of the group (children in the hierarchy)\n */\nexport function resolveRelations(\n groups: GroupEntity[],\n users: UserEntity[],\n userMemberOf: Map<string, Set<string>>,\n groupMemberOf: Map<string, Set<string>>,\n groupMember: Map<string, Set<string>>,\n) {\n // Build reference lookup tables - all of the relations that are output from\n // the above calls can be expressed as either DNs or UUIDs so we need to be\n // able to find by both, as well as the entity reference. Note that we expect them to not\n // collide here - this is a reasonable assumption as long as the fields are\n // the supported forms.\n const userMap: Map<string, UserEntity> = new Map(); // by entityRef, dn, uuid\n const groupMap: Map<string, GroupEntity> = new Map(); // by entityRef, dn, uuid\n for (const user of users) {\n userMap.set(stringifyEntityRef(user), user);\n userMap.set(user.metadata.annotations![LDAP_DN_ANNOTATION], user);\n userMap.set(\n user.metadata.annotations![LDAP_DN_ANNOTATION]?.toLocaleLowerCase(\n 'en-US',\n ),\n user,\n );\n userMap.set(user.metadata.annotations![LDAP_RDN_ANNOTATION], user);\n userMap.set(user.metadata.annotations![LDAP_UUID_ANNOTATION], user);\n }\n for (const group of groups) {\n groupMap.set(stringifyEntityRef(group), group);\n groupMap.set(group.metadata.annotations![LDAP_DN_ANNOTATION], group);\n groupMap.set(\n group.metadata.annotations![LDAP_DN_ANNOTATION]?.toLocaleLowerCase(\n 'en-US',\n ),\n group,\n );\n groupMap.set(group.metadata.annotations![LDAP_RDN_ANNOTATION], group);\n groupMap.set(group.metadata.annotations![LDAP_UUID_ANNOTATION], group);\n }\n\n // This can happen e.g. if entryUUID wasn't returned by the server\n userMap.delete('');\n groupMap.delete('');\n userMap.delete(undefined!);\n groupMap.delete(undefined!);\n\n // Fill in all of the immediate relations, now keyed on the entity reference. We\n // keep all parents at this point, whether the target model can support more\n // than one or not (it gets filtered farther down). And group children are\n // only groups in here.\n const newUserMemberOf: Map<string, Set<string>> = new Map();\n const newGroupParents: Map<string, Set<string>> = new Map();\n const newGroupChildren: Map<string, Set<string>> = new Map();\n\n // Resolve and store in the intermediaries. It may seem redundant that the\n // input data has both parent and children directions, as well as both\n // user->group and group->user - the reason is that different LDAP schemas\n // express relations in different directions. Some may have a user memberOf\n // overlay, some don't, for example.\n for (const [userN, groupsN] of userMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n for (const groupN of groupsN) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n ensureItems(newUserMemberOf, stringifyEntityRef(user), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, parentsN] of groupMemberOf.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const parentN of parentsN) {\n const parentGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n parentN,\n );\n if (parentGroup) {\n ensureItems(newGroupParents, stringifyEntityRef(group), [\n stringifyEntityRef(parentGroup),\n ]);\n ensureItems(newGroupChildren, stringifyEntityRef(parentGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n for (const [groupN, membersN] of groupMember.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n for (const memberN of membersN) {\n // Group members can be both users and groups in the input model, so\n // try both\n const memberUser = getValueFromMapWithInsensitiveKey(userMap, memberN);\n if (memberUser) {\n ensureItems(newUserMemberOf, stringifyEntityRef(memberUser), [\n stringifyEntityRef(group),\n ]);\n } else {\n const memberGroup = getValueFromMapWithInsensitiveKey(\n groupMap,\n memberN,\n );\n if (memberGroup) {\n ensureItems(newGroupChildren, stringifyEntityRef(group), [\n stringifyEntityRef(memberGroup),\n ]);\n ensureItems(newGroupParents, stringifyEntityRef(memberGroup), [\n stringifyEntityRef(group),\n ]);\n }\n }\n }\n }\n }\n\n // Write down the relations again into the actual entities\n for (const [userN, groupsN] of newUserMemberOf.entries()) {\n const user = getValueFromMapWithInsensitiveKey(userMap, userN);\n if (user) {\n user.spec.memberOf = Array.from(groupsN).sort();\n }\n }\n for (const [groupN, parentsN] of newGroupParents.entries()) {\n if (parentsN.size === 1) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.parent = parentsN.values().next().value;\n }\n }\n }\n for (const [groupN, childrenN] of newGroupChildren.entries()) {\n const group = getValueFromMapWithInsensitiveKey(groupMap, groupN);\n if (group) {\n group.spec.children = Array.from(childrenN).sort();\n }\n }\n\n // Fill out the rest of the hierarchy\n buildOrgHierarchy(groups);\n}\n"],"names":["lodashSet","cloneDeep","mapStringAttr","InputError","LDAP_RDN_ANNOTATION","LDAP_UUID_ANNOTATION","LDAP_DN_ANNOTATION","stringifyEntityRef","buildOrgHierarchy"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend-module-ldap",
3
- "version": "0.11.6-next.1",
3
+ "version": "0.11.6",
4
4
  "description": "A Backstage catalog backend module that helps integrate towards LDAP",
5
5
  "backstage": {
6
6
  "role": "backend-plugin-module",
@@ -41,20 +41,20 @@
41
41
  "test": "backstage-cli package test"
42
42
  },
43
43
  "dependencies": {
44
- "@backstage/backend-plugin-api": "1.4.0-next.1",
45
- "@backstage/catalog-model": "1.7.4",
46
- "@backstage/config": "1.3.2",
47
- "@backstage/errors": "1.2.7",
48
- "@backstage/plugin-catalog-common": "1.1.4",
49
- "@backstage/plugin-catalog-node": "1.17.1-next.1",
50
- "@backstage/types": "1.2.1",
44
+ "@backstage/backend-plugin-api": "^1.4.0",
45
+ "@backstage/catalog-model": "^1.7.4",
46
+ "@backstage/config": "^1.3.2",
47
+ "@backstage/errors": "^1.2.7",
48
+ "@backstage/plugin-catalog-common": "^1.1.4",
49
+ "@backstage/plugin-catalog-node": "^1.17.1",
50
+ "@backstage/types": "^1.2.1",
51
51
  "@types/ldapjs": "^2.2.5",
52
52
  "ldapjs": "^2.3.3",
53
53
  "lodash": "^4.17.21",
54
54
  "uuid": "^11.0.0"
55
55
  },
56
56
  "devDependencies": {
57
- "@backstage/cli": "0.32.2-next.0",
57
+ "@backstage/cli": "^0.33.0",
58
58
  "@types/lodash": "^4.14.151"
59
59
  },
60
60
  "configSchema": "config.d.ts",