@backstage/plugin-catalog-backend-module-ldap 0.9.1-next.1 → 0.9.2-next.0

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,32 @@
1
1
  # @backstage/plugin-catalog-backend-module-ldap
2
2
 
3
+ ## 0.9.2-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 884a86c: Added a `dnCaseSensitive` flag to support LDAP servers with mixed-case attributes.
8
+ - Updated dependencies
9
+ - @backstage/plugin-catalog-node@1.14.0-next.0
10
+ - @backstage/backend-plugin-api@1.0.2-next.0
11
+ - @backstage/catalog-model@1.7.0
12
+ - @backstage/config@1.2.0
13
+ - @backstage/errors@1.2.4
14
+ - @backstage/types@1.1.1
15
+ - @backstage/plugin-catalog-common@1.1.0
16
+
17
+ ## 0.9.1
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies
22
+ - @backstage/plugin-catalog-node@1.13.1
23
+ - @backstage/backend-plugin-api@1.0.1
24
+ - @backstage/catalog-model@1.7.0
25
+ - @backstage/config@1.2.0
26
+ - @backstage/errors@1.2.4
27
+ - @backstage/types@1.1.1
28
+ - @backstage/plugin-catalog-common@1.1.0
29
+
3
30
  ## 0.9.1-next.1
4
31
 
5
32
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -103,6 +103,12 @@ type VendorConfig = {
103
103
  * Attribute name for the unique identifier (UUID) of an entry,
104
104
  */
105
105
  uuidAttributeName?: string;
106
+ /**
107
+ * Attribute to determine if we need to force the DN and members/memberOf values to be forced to same case.
108
+ * Some providers may provide lowercase members but multicase DN names which causes the group filtering to break.
109
+ * The default is off, but turning this on forces the inbound DN values and all member values to lowercase.
110
+ */
111
+ dnCaseSensitive?: boolean;
106
112
  };
107
113
  /**
108
114
  * Parses configuration.
@@ -136,6 +142,10 @@ type LdapVendor = {
136
142
  * The attribute name that holds a universal unique identifier for an entry.
137
143
  */
138
144
  uuidAttributeName: string;
145
+ /**
146
+ * The attribute that determines behaviour of the (dn,members,memberOf) for entries.
147
+ */
148
+ dnCaseSensitive?: boolean;
139
149
  /**
140
150
  * Decode ldap entry values for a given attribute name to their string representation.
141
151
  *
@@ -69,7 +69,8 @@ function readVendorConfig(c) {
69
69
  }
70
70
  return {
71
71
  dnAttributeName: c.getOptionalString("dnAttributeName"),
72
- uuidAttributeName: c.getOptionalString("uuidAttributeName")
72
+ uuidAttributeName: c.getOptionalString("uuidAttributeName"),
73
+ dnCaseSensitive: c.getOptionalBoolean("dnCaseSensitive")
73
74
  };
74
75
  }
75
76
  function readOptionsConfig(c) {
@@ -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 // 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 /**\n * Attribute to determine if we need to force the DN and members/memberOf values to be forced to same case.\n * Some providers may provide lowercase members but multicase DN names which causes the group filtering to break.\n * The default is off, but turning this on forces the inbound DN values and all member values to lowercase.\n */\n dnCaseSensitive?: boolean;\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 dnCaseSensitive: c.getOptionalBoolean('dnCaseSensitive'),\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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"}
@@ -44,7 +44,10 @@ async function defaultUserTransformer(vendor, config, entry) {
44
44
  entity.metadata.annotations[constants.LDAP_UUID_ANNOTATION] = v;
45
45
  });
46
46
  util.mapStringAttr(entry, vendor, vendor.dnAttributeName, (v) => {
47
- entity.metadata.annotations[constants.LDAP_DN_ANNOTATION] = v;
47
+ entity.metadata.annotations[constants.LDAP_DN_ANNOTATION] = getCaseSensitivityValue(
48
+ v,
49
+ vendor
50
+ );
48
51
  });
49
52
  util.mapStringAttr(entry, vendor, map.displayName, (v) => {
50
53
  entity.spec.profile.displayName = v;
@@ -67,6 +70,7 @@ async function readLdapUsers(client, userConfig, vendorConfig, opts) {
67
70
  const vendor = {
68
71
  dnAttributeName: vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,
69
72
  uuidAttributeName: vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,
73
+ dnCaseSensitive: vendorConfig?.dnCaseSensitive ?? vendorDefaults.dnCaseSensitive,
70
74
  decodeStringAttribute: vendorDefaults.decodeStringAttribute
71
75
  };
72
76
  const transformer = opts?.transformer ?? defaultUserTransformer;
@@ -118,7 +122,10 @@ async function defaultGroupTransformer(vendor, config, entry) {
118
122
  entity.metadata.annotations[constants.LDAP_UUID_ANNOTATION] = v;
119
123
  });
120
124
  util.mapStringAttr(entry, vendor, vendor.dnAttributeName, (v) => {
121
- entity.metadata.annotations[constants.LDAP_DN_ANNOTATION] = v;
125
+ entity.metadata.annotations[constants.LDAP_DN_ANNOTATION] = getCaseSensitivityValue(
126
+ v,
127
+ vendor
128
+ );
122
129
  });
123
130
  util.mapStringAttr(entry, vendor, map.type, (v) => {
124
131
  entity.spec.type = v;
@@ -145,6 +152,7 @@ async function readLdapGroups(client, groupConfig, vendorConfig, opts) {
145
152
  const vendor = {
146
153
  dnAttributeName: vendorConfig?.dnAttributeName ?? vendorDefaults.dnAttributeName,
147
154
  uuidAttributeName: vendorConfig?.uuidAttributeName ?? vendorDefaults.uuidAttributeName,
155
+ dnCaseSensitive: vendorConfig?.dnCaseSensitive ?? vendorDefaults.dnCaseSensitive,
148
156
  decodeStringAttribute: vendorDefaults.decodeStringAttribute
149
157
  };
150
158
  const transformer = opts?.transformer ?? defaultGroupTransformer;
@@ -198,10 +206,20 @@ function mapReferencesAttr(entry, vendor, attributeName, setter) {
198
206
  const values = vendor.decodeStringAttribute(entry, attributeName);
199
207
  const dn = vendor.decodeStringAttribute(entry, vendor.dnAttributeName);
200
208
  if (values && dn && dn.length === 1) {
201
- setter(dn[0], values);
209
+ if (vendor.dnCaseSensitive) {
210
+ setter(
211
+ dn[0].toLocaleLowerCase("en-US"),
212
+ values.map((v) => v.toLocaleLowerCase("en-US"))
213
+ );
214
+ } else {
215
+ setter(dn[0], values);
216
+ }
202
217
  }
203
218
  }
204
219
  }
220
+ function getCaseSensitivityValue(value, vendor) {
221
+ return value && vendor.dnCaseSensitive ? value.toLocaleLowerCase("en-US") : value;
222
+ }
205
223
  function ensureItems(target, key, values) {
206
224
  if (key) {
207
225
  let set = target.get(key);
@@ -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';\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 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 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 * 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(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(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 = userMap.get(userN);\n if (user) {\n for (const groupN of groupsN) {\n const group = groupMap.get(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 = groupMap.get(groupN);\n if (group) {\n for (const parentN of parentsN) {\n const parentGroup = groupMap.get(parentN);\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 = groupMap.get(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 = userMap.get(memberN);\n if (memberUser) {\n ensureItems(newUserMemberOf, stringifyEntityRef(memberUser), [\n stringifyEntityRef(group),\n ]);\n } else {\n const memberGroup = groupMap.get(memberN);\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 = userMap.get(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 = groupMap.get(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 = groupMap.get(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","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';\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 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] = getCaseSensitivityValue(\n v,\n vendor,\n );\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 dnCaseSensitive:\n vendorConfig?.dnCaseSensitive ?? vendorDefaults.dnCaseSensitive,\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 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] = getCaseSensitivityValue(\n v,\n vendor,\n );\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 dnCaseSensitive:\n vendorConfig?.dnCaseSensitive ?? vendorDefaults.dnCaseSensitive,\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 if (vendor.dnCaseSensitive) {\n setter(\n dn[0].toLocaleLowerCase('en-US'),\n values.map(v => v.toLocaleLowerCase('en-US')),\n );\n } else {\n setter(dn[0], values);\n }\n }\n }\n}\n\n/** Validates value exists and if required forced sensitivty value to lowercase */\nfunction getCaseSensitivityValue(value: string, vendor: LdapVendor) {\n return value && vendor.dnCaseSensitive\n ? value.toLocaleLowerCase('en-US')\n : value;\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 * 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(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(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 = userMap.get(userN);\n if (user) {\n for (const groupN of groupsN) {\n const group = groupMap.get(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 = groupMap.get(groupN);\n if (group) {\n for (const parentN of parentsN) {\n const parentGroup = groupMap.get(parentN);\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 = groupMap.get(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 = userMap.get(memberN);\n if (memberUser) {\n ensureItems(newUserMemberOf, stringifyEntityRef(memberUser), [\n stringifyEntityRef(group),\n ]);\n } else {\n const memberGroup = groupMap.get(memberN);\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 = userMap.get(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 = groupMap.get(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 = groupMap.get(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","LDAP_RDN_ANNOTATION","LDAP_UUID_ANNOTATION","LDAP_DN_ANNOTATION","stringifyEntityRef","buildOrgHierarchy"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vendors.cjs.js","sources":["../../src/ldap/vendors.ts"],"sourcesContent":["/*\n * Copyright 2021 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 { SearchEntry } from 'ldapjs';\n\n/**\n * An LDAP Vendor handles unique nuances between different vendors.\n *\n * @public\n */\nexport type LdapVendor = {\n /**\n * The attribute name that holds the distinguished name (DN) for an entry.\n */\n dnAttributeName: string;\n /**\n * The attribute name that holds a universal unique identifier for an entry.\n */\n uuidAttributeName: string;\n /**\n * Decode ldap entry values for a given attribute name to their string representation.\n *\n * @param entry - The ldap entry\n * @param name - The attribute to decode\n */\n decodeStringAttribute: (entry: SearchEntry, name: string) => string[];\n};\n\nexport const DefaultLdapVendor: LdapVendor = {\n dnAttributeName: 'entryDN',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const ActiveDirectoryVendor: LdapVendor = {\n dnAttributeName: 'distinguishedName',\n uuidAttributeName: 'objectGUID',\n decodeStringAttribute: (entry, name) => {\n const decoder = (value: string | Buffer) => {\n if (name === ActiveDirectoryVendor.uuidAttributeName) {\n return formatGUID(value);\n }\n return value.toString();\n };\n return decode(entry, name, decoder);\n },\n};\n\nexport const FreeIpaVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'ipaUniqueID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const AEDirVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\n// Decode an attribute to a consumer\nfunction decode(\n entry: SearchEntry,\n attributeName: string,\n decoder: (value: string | Buffer) => string,\n): string[] {\n const values = entry.raw[attributeName];\n if (Array.isArray(values)) {\n return values.map(v => {\n return decoder(v);\n });\n } else if (values) {\n return [decoder(values)];\n }\n return [];\n}\n\n// Formats a Microsoft Active Directory binary-encoded uuid to a readable string\n// See https://github.com/ldapjs/node-ldapjs/issues/297#issuecomment-137765214\nfunction formatGUID(objectGUID: string | Buffer): string {\n let data: Buffer;\n if (typeof objectGUID === 'string') {\n data = Buffer.from(objectGUID, 'binary');\n } else {\n data = objectGUID;\n }\n // GUID_FORMAT_D\n let template = '{3}{2}{1}{0}-{5}{4}-{7}{6}-{8}{9}-{10}{11}{12}{13}{14}{15}';\n\n // check each byte\n for (let i = 0; i < data.length; i++) {\n let dataStr = data[i].toString(16);\n dataStr = data[i] >= 16 ? dataStr : `0${dataStr}`;\n\n // insert that character into the template\n template = template.replace(`{${i}}`, dataStr);\n }\n return template;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vendors.cjs.js","sources":["../../src/ldap/vendors.ts"],"sourcesContent":["/*\n * Copyright 2021 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 { SearchEntry } from 'ldapjs';\n\n/**\n * An LDAP Vendor handles unique nuances between different vendors.\n *\n * @public\n */\nexport type LdapVendor = {\n /**\n * The attribute name that holds the distinguished name (DN) for an entry.\n */\n dnAttributeName: string;\n /**\n * The attribute name that holds a universal unique identifier for an entry.\n */\n uuidAttributeName: string;\n\n /**\n * The attribute that determines behaviour of the (dn,members,memberOf) for entries.\n */\n dnCaseSensitive?: boolean;\n\n /**\n * Decode ldap entry values for a given attribute name to their string representation.\n *\n * @param entry - The ldap entry\n * @param name - The attribute to decode\n */\n decodeStringAttribute: (entry: SearchEntry, name: string) => string[];\n};\n\nexport const DefaultLdapVendor: LdapVendor = {\n dnAttributeName: 'entryDN',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const ActiveDirectoryVendor: LdapVendor = {\n dnAttributeName: 'distinguishedName',\n uuidAttributeName: 'objectGUID',\n decodeStringAttribute: (entry, name) => {\n const decoder = (value: string | Buffer) => {\n if (name === ActiveDirectoryVendor.uuidAttributeName) {\n return formatGUID(value);\n }\n return value.toString();\n };\n return decode(entry, name, decoder);\n },\n};\n\nexport const FreeIpaVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'ipaUniqueID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\nexport const AEDirVendor: LdapVendor = {\n dnAttributeName: 'dn',\n uuidAttributeName: 'entryUUID',\n decodeStringAttribute: (entry, name) => {\n return decode(entry, name, value => {\n return value.toString();\n });\n },\n};\n\n// Decode an attribute to a consumer\nfunction decode(\n entry: SearchEntry,\n attributeName: string,\n decoder: (value: string | Buffer) => string,\n): string[] {\n const values = entry.raw[attributeName];\n if (Array.isArray(values)) {\n return values.map(v => {\n return decoder(v);\n });\n } else if (values) {\n return [decoder(values)];\n }\n return [];\n}\n\n// Formats a Microsoft Active Directory binary-encoded uuid to a readable string\n// See https://github.com/ldapjs/node-ldapjs/issues/297#issuecomment-137765214\nfunction formatGUID(objectGUID: string | Buffer): string {\n let data: Buffer;\n if (typeof objectGUID === 'string') {\n data = Buffer.from(objectGUID, 'binary');\n } else {\n data = objectGUID;\n }\n // GUID_FORMAT_D\n let template = '{3}{2}{1}{0}-{5}{4}-{7}{6}-{8}{9}-{10}{11}{12}{13}{14}{15}';\n\n // check each byte\n for (let i = 0; i < data.length; i++) {\n let dataStr = data[i].toString(16);\n dataStr = data[i] >= 16 ? dataStr : `0${dataStr}`;\n\n // insert that character into the template\n template = template.replace(`{${i}}`, dataStr);\n }\n return template;\n}\n"],"names":[],"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.9.1-next.1",
3
+ "version": "0.9.2-next.0",
4
4
  "description": "A Backstage catalog backend module that helps integrate towards LDAP",
5
5
  "backstage": {
6
6
  "role": "backend-plugin-module",
@@ -38,12 +38,12 @@
38
38
  "test": "backstage-cli package test"
39
39
  },
40
40
  "dependencies": {
41
- "@backstage/backend-plugin-api": "1.0.1-next.1",
41
+ "@backstage/backend-plugin-api": "1.0.2-next.0",
42
42
  "@backstage/catalog-model": "1.7.0",
43
43
  "@backstage/config": "1.2.0",
44
44
  "@backstage/errors": "1.2.4",
45
45
  "@backstage/plugin-catalog-common": "1.1.0",
46
- "@backstage/plugin-catalog-node": "1.13.1-next.1",
46
+ "@backstage/plugin-catalog-node": "1.14.0-next.0",
47
47
  "@backstage/types": "1.1.1",
48
48
  "@types/ldapjs": "^2.2.5",
49
49
  "ldapjs": "^2.3.3",
@@ -51,7 +51,7 @@
51
51
  "uuid": "^9.0.0"
52
52
  },
53
53
  "devDependencies": {
54
- "@backstage/cli": "0.28.0-next.2",
54
+ "@backstage/cli": "0.29.0-next.0",
55
55
  "@types/lodash": "^4.14.151"
56
56
  },
57
57
  "configSchema": "config.d.ts"