@red-hat-developer-hub/e2e-test-utils 2.1.11 → 2.1.14
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/dist/deployment/keycloak/deployment.d.ts +28 -1
- package/dist/deployment/keycloak/deployment.d.ts.map +1 -1
- package/dist/deployment/keycloak/deployment.js +210 -0
- package/dist/deployment/keycloak/index.d.ts +2 -1
- package/dist/deployment/keycloak/index.d.ts.map +1 -1
- package/dist/deployment/keycloak/index.js +1 -0
- package/dist/deployment/keycloak/types.d.ts +35 -0
- package/dist/deployment/keycloak/types.d.ts.map +1 -1
- package/dist/deployment/openldap/config/seed.ldif +102 -0
- package/dist/deployment/openldap/constants.d.ts +46 -0
- package/dist/deployment/openldap/constants.d.ts.map +1 -0
- package/dist/deployment/openldap/constants.js +65 -0
- package/dist/deployment/openldap/deployment.d.ts +31 -0
- package/dist/deployment/openldap/deployment.d.ts.map +1 -0
- package/dist/deployment/openldap/deployment.js +219 -0
- package/dist/deployment/openldap/index.d.ts +4 -0
- package/dist/deployment/openldap/index.d.ts.map +1 -0
- package/dist/deployment/openldap/index.js +2 -0
- package/dist/deployment/openldap/types.d.ts +34 -0
- package/dist/deployment/openldap/types.d.ts.map +1 -0
- package/dist/deployment/openldap/types.js +1 -0
- package/dist/playwright/global-setup.d.ts +5 -0
- package/dist/playwright/global-setup.d.ts.map +1 -1
- package/dist/playwright/global-setup.js +2 -4
- package/dist/playwright/helpers/common.d.ts +73 -2
- package/dist/playwright/helpers/common.d.ts.map +1 -1
- package/dist/playwright/helpers/common.js +159 -39
- package/dist/playwright/helpers/github-session.test.d.ts +2 -0
- package/dist/playwright/helpers/github-session.test.d.ts.map +1 -0
- package/dist/playwright/helpers/github-session.test.js +199 -0
- package/dist/playwright/tests/global-setup.test.d.ts +2 -0
- package/dist/playwright/tests/global-setup.test.d.ts.map +1 -0
- package/dist/playwright/tests/global-setup.test.js +68 -0
- package/dist/secrets/bitwarden.d.ts +34 -0
- package/dist/secrets/bitwarden.d.ts.map +1 -0
- package/dist/secrets/bitwarden.js +193 -0
- package/dist/secrets/cli.d.ts +11 -0
- package/dist/secrets/cli.d.ts.map +1 -0
- package/dist/secrets/cli.js +98 -0
- package/dist/secrets/command.d.ts +15 -0
- package/dist/secrets/command.d.ts.map +1 -0
- package/dist/secrets/command.js +30 -0
- package/dist/secrets/config.d.ts +33 -0
- package/dist/secrets/config.d.ts.map +1 -0
- package/dist/secrets/config.js +156 -0
- package/dist/secrets/environment.d.ts +10 -0
- package/dist/secrets/environment.d.ts.map +1 -0
- package/dist/secrets/environment.js +53 -0
- package/dist/secrets/exec.d.ts +18 -0
- package/dist/secrets/exec.d.ts.map +1 -0
- package/dist/secrets/exec.js +50 -0
- package/dist/secrets/index.d.ts +5 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +4 -0
- package/dist/secrets/tests/bitwarden.integration.test.d.ts +2 -0
- package/dist/secrets/tests/bitwarden.integration.test.d.ts.map +1 -0
- package/dist/secrets/tests/bitwarden.integration.test.js +50 -0
- package/dist/secrets/tests/bitwarden.test.d.ts +2 -0
- package/dist/secrets/tests/bitwarden.test.d.ts.map +1 -0
- package/dist/secrets/tests/bitwarden.test.js +418 -0
- package/dist/secrets/tests/cli.integration.test.d.ts +2 -0
- package/dist/secrets/tests/cli.integration.test.d.ts.map +1 -0
- package/dist/secrets/tests/cli.integration.test.js +70 -0
- package/dist/secrets/tests/cli.test.d.ts +2 -0
- package/dist/secrets/tests/cli.test.d.ts.map +1 -0
- package/dist/secrets/tests/cli.test.js +42 -0
- package/dist/secrets/tests/config.test.d.ts +2 -0
- package/dist/secrets/tests/config.test.d.ts.map +1 -0
- package/dist/secrets/tests/config.test.js +105 -0
- package/dist/secrets/tests/environment.test.d.ts +2 -0
- package/dist/secrets/tests/environment.test.d.ts.map +1 -0
- package/dist/secrets/tests/environment.test.js +119 -0
- package/dist/secrets/tests/exec.test.d.ts +2 -0
- package/dist/secrets/tests/exec.test.d.ts.map +1 -0
- package/dist/secrets/tests/exec.test.js +87 -0
- package/package.json +13 -2
- package/dist/utils/vault.d.ts +0 -16
- package/dist/utils/vault.d.ts.map +0 -1
- package/dist/utils/vault.js +0 -94
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KubernetesClientHelper } from "../../utils/kubernetes-client.js";
|
|
2
|
-
import type { KeycloakDeploymentOptions, KeycloakDeploymentConfig, KeycloakClientConfig, KeycloakUserConfig, KeycloakGroupConfig, KeycloakRealmConfig, KeycloakConnectionConfig } from "./types.js";
|
|
2
|
+
import type { KeycloakDeploymentOptions, KeycloakDeploymentConfig, KeycloakClientConfig, KeycloakUserConfig, KeycloakGroupConfig, KeycloakRealmConfig, KeycloakConnectionConfig, KeycloakLdapFederationConfig, KeycloakLdapMapperConfig, KeycloakProtocolMapperConfig, KeycloakLdapRealmOptions } from "./types.js";
|
|
3
3
|
export declare class KeycloakHelper {
|
|
4
4
|
k8sClient: KubernetesClientHelper;
|
|
5
5
|
deploymentConfig: KeycloakDeploymentConfig;
|
|
@@ -84,6 +84,32 @@ export declare class KeycloakHelper {
|
|
|
84
84
|
* Delete a realm
|
|
85
85
|
*/
|
|
86
86
|
deleteRealm(realm: string): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Create (or return existing) LDAP user federation component on a realm.
|
|
89
|
+
* Requires admin credentials via connect()/deploy().
|
|
90
|
+
*/
|
|
91
|
+
createLdapUserFederation(realm: string, config: KeycloakLdapFederationConfig): Promise<string>;
|
|
92
|
+
getLdapUserFederation(realm: string, name?: string): Promise<{
|
|
93
|
+
id: string;
|
|
94
|
+
name?: string;
|
|
95
|
+
} | undefined>;
|
|
96
|
+
updateLdapUserFederation(id: string, config: KeycloakLdapFederationConfig, realm: string): Promise<void>;
|
|
97
|
+
deleteLdapUserFederation(id: string, realm: string): Promise<void>;
|
|
98
|
+
createLdapMapper(realm: string, parentId: string, mapper: KeycloakLdapMapperConfig): Promise<string>;
|
|
99
|
+
listLdapMappers(realm: string, parentId: string): Promise<Array<{
|
|
100
|
+
id?: string;
|
|
101
|
+
name?: string;
|
|
102
|
+
}>>;
|
|
103
|
+
syncLdapUsers(federationId: string, action?: "triggerFullSync" | "triggerChangedUsersSync"): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Add an OIDC protocol mapper on a client (e.g. ldap_uuid user attribute → claim).
|
|
106
|
+
*/
|
|
107
|
+
addClientProtocolMapper(realm: string, clientId: string, mapper: KeycloakProtocolMapperConfig): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* One-shot: separate LDAP-fed realm + client + OpenLDAP federation + ldap_uuid claim.
|
|
110
|
+
* Connect as Keycloak admin first (username/password), not the RHDH service account.
|
|
111
|
+
*/
|
|
112
|
+
configureLdapRealm(options: KeycloakLdapRealmOptions): Promise<void>;
|
|
87
113
|
/**
|
|
88
114
|
* Teardown Keycloak deployment
|
|
89
115
|
*/
|
|
@@ -101,6 +127,7 @@ export declare class KeycloakHelper {
|
|
|
101
127
|
private _ensureAdminClient;
|
|
102
128
|
private _assignServiceAccountRoles;
|
|
103
129
|
private _addUserToGroup;
|
|
130
|
+
private _ldapFederationConfigToComponent;
|
|
104
131
|
private _isConflictError;
|
|
105
132
|
private _log;
|
|
106
133
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../../src/deployment/keycloak/deployment.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../../src/deployment/keycloak/deployment.ts"],"names":[],"mappings":"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"}
|
|
@@ -333,6 +333,188 @@ export class KeycloakHelper {
|
|
|
333
333
|
this._log(`Failed to delete realm ${realm}: ${error}`);
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Create (or return existing) LDAP user federation component on a realm.
|
|
338
|
+
* Requires admin credentials via connect()/deploy().
|
|
339
|
+
*/
|
|
340
|
+
async createLdapUserFederation(realm, config) {
|
|
341
|
+
await this._ensureAdminClient();
|
|
342
|
+
this._adminClient.setConfig({ realmName: realm });
|
|
343
|
+
const name = config.name ?? "openldap";
|
|
344
|
+
const existing = await this.getLdapUserFederation(realm, name);
|
|
345
|
+
if (existing?.id) {
|
|
346
|
+
this._log(`LDAP federation ${name} already exists (${existing.id})`);
|
|
347
|
+
await this.updateLdapUserFederation(existing.id, config, realm);
|
|
348
|
+
return existing.id;
|
|
349
|
+
}
|
|
350
|
+
const realmRep = await this._adminClient.realms.findOne({ realm });
|
|
351
|
+
if (!realmRep?.id) {
|
|
352
|
+
throw new Error(`Realm ${realm} not found`);
|
|
353
|
+
}
|
|
354
|
+
const { id } = await this._adminClient.components.create({
|
|
355
|
+
realm,
|
|
356
|
+
name,
|
|
357
|
+
providerId: "ldap",
|
|
358
|
+
providerType: "org.keycloak.storage.UserStorageProvider",
|
|
359
|
+
parentId: realmRep.id,
|
|
360
|
+
config: this._ldapFederationConfigToComponent(config),
|
|
361
|
+
});
|
|
362
|
+
this._log(`Created LDAP federation: ${name} (${id})`);
|
|
363
|
+
return id;
|
|
364
|
+
}
|
|
365
|
+
async getLdapUserFederation(realm, name) {
|
|
366
|
+
await this._ensureAdminClient();
|
|
367
|
+
this._adminClient.setConfig({ realmName: realm });
|
|
368
|
+
const components = await this._adminClient.components.find({
|
|
369
|
+
realm,
|
|
370
|
+
type: "org.keycloak.storage.UserStorageProvider",
|
|
371
|
+
});
|
|
372
|
+
const match = name
|
|
373
|
+
? components.find((c) => c.name === name && c.providerId === "ldap")
|
|
374
|
+
: components.find((c) => c.providerId === "ldap");
|
|
375
|
+
return match?.id ? { id: match.id, name: match.name } : undefined;
|
|
376
|
+
}
|
|
377
|
+
async updateLdapUserFederation(id, config, realm) {
|
|
378
|
+
await this._ensureAdminClient();
|
|
379
|
+
this._adminClient.setConfig({ realmName: realm });
|
|
380
|
+
const current = await this._adminClient.components.findOne({ id, realm });
|
|
381
|
+
if (!current) {
|
|
382
|
+
throw new Error(`LDAP federation component ${id} not found`);
|
|
383
|
+
}
|
|
384
|
+
await this._adminClient.components.update({ id, realm }, {
|
|
385
|
+
...current,
|
|
386
|
+
config: {
|
|
387
|
+
...current.config,
|
|
388
|
+
...this._ldapFederationConfigToComponent(config),
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
this._log(`Updated LDAP federation: ${id}`);
|
|
392
|
+
}
|
|
393
|
+
async deleteLdapUserFederation(id, realm) {
|
|
394
|
+
await this._ensureAdminClient();
|
|
395
|
+
await this._adminClient.components.del({ id, realm });
|
|
396
|
+
this._log(`Deleted LDAP federation: ${id}`);
|
|
397
|
+
}
|
|
398
|
+
async createLdapMapper(realm, parentId, mapper) {
|
|
399
|
+
await this._ensureAdminClient();
|
|
400
|
+
this._adminClient.setConfig({ realmName: realm });
|
|
401
|
+
const existing = await this.listLdapMappers(realm, parentId);
|
|
402
|
+
const found = existing.find((m) => m.name === mapper.name);
|
|
403
|
+
if (found?.id) {
|
|
404
|
+
this._log(`LDAP mapper ${mapper.name} already exists`);
|
|
405
|
+
return found.id;
|
|
406
|
+
}
|
|
407
|
+
const configEntries = {};
|
|
408
|
+
for (const [key, value] of Object.entries(mapper.config)) {
|
|
409
|
+
configEntries[key] = [value];
|
|
410
|
+
}
|
|
411
|
+
const { id } = await this._adminClient.components.create({
|
|
412
|
+
realm,
|
|
413
|
+
name: mapper.name,
|
|
414
|
+
parentId,
|
|
415
|
+
providerId: mapper.providerId,
|
|
416
|
+
providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper",
|
|
417
|
+
config: configEntries,
|
|
418
|
+
});
|
|
419
|
+
this._log(`Created LDAP mapper: ${mapper.name}`);
|
|
420
|
+
return id;
|
|
421
|
+
}
|
|
422
|
+
async listLdapMappers(realm, parentId) {
|
|
423
|
+
await this._ensureAdminClient();
|
|
424
|
+
return this._adminClient.components.find({
|
|
425
|
+
realm,
|
|
426
|
+
parent: parentId,
|
|
427
|
+
type: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper",
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
async syncLdapUsers(federationId, action = "triggerFullSync") {
|
|
431
|
+
await this._ensureAdminClient();
|
|
432
|
+
await this._adminClient.userStorageProvider.sync({
|
|
433
|
+
id: federationId,
|
|
434
|
+
action,
|
|
435
|
+
});
|
|
436
|
+
this._log(`Triggered LDAP sync (${action}) for ${federationId}`);
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Add an OIDC protocol mapper on a client (e.g. ldap_uuid user attribute → claim).
|
|
440
|
+
*/
|
|
441
|
+
async addClientProtocolMapper(realm, clientId, mapper) {
|
|
442
|
+
await this._ensureAdminClient();
|
|
443
|
+
this._adminClient.setConfig({ realmName: realm });
|
|
444
|
+
const clients = await this._adminClient.clients.find({ clientId });
|
|
445
|
+
if (clients.length === 0 || !clients[0].id) {
|
|
446
|
+
throw new Error(`Client ${clientId} not found in realm ${realm}`);
|
|
447
|
+
}
|
|
448
|
+
const id = clients[0].id;
|
|
449
|
+
const existing = await this._adminClient.clients.listProtocolMappers({
|
|
450
|
+
id,
|
|
451
|
+
realm,
|
|
452
|
+
});
|
|
453
|
+
if (existing.some((m) => m.name === mapper.name)) {
|
|
454
|
+
this._log(`Protocol mapper ${mapper.name} already exists on ${clientId}`);
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
await this._adminClient.clients.addProtocolMapper({ id, realm }, {
|
|
458
|
+
name: mapper.name,
|
|
459
|
+
protocol: mapper.protocol ?? "openid-connect",
|
|
460
|
+
protocolMapper: mapper.protocolMapper,
|
|
461
|
+
config: mapper.config,
|
|
462
|
+
});
|
|
463
|
+
this._log(`Added protocol mapper ${mapper.name} on client ${clientId}`);
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* One-shot: separate LDAP-fed realm + client + OpenLDAP federation + ldap_uuid claim.
|
|
467
|
+
* Connect as Keycloak admin first (username/password), not the RHDH service account.
|
|
468
|
+
*/
|
|
469
|
+
async configureLdapRealm(options) {
|
|
470
|
+
await this._ensureAdminClient();
|
|
471
|
+
const realmName = options.realm;
|
|
472
|
+
await this.createRealm({ realm: realmName, enabled: true });
|
|
473
|
+
const clientConfig = {
|
|
474
|
+
...DEFAULT_RHDH_CLIENT,
|
|
475
|
+
clientId: "rhdh-ldap-client",
|
|
476
|
+
clientSecret: "rhdh-ldap-client-secret",
|
|
477
|
+
name: "RHDH LDAP Client",
|
|
478
|
+
...options.client,
|
|
479
|
+
};
|
|
480
|
+
await this.createClient(realmName, clientConfig);
|
|
481
|
+
await this._assignServiceAccountRoles(realmName, clientConfig.clientId);
|
|
482
|
+
const federationId = await this.createLdapUserFederation(realmName, options.ldap);
|
|
483
|
+
// Map LDAP entryUUID into a Keycloak user attribute for the token claim.
|
|
484
|
+
/* eslint-disable @typescript-eslint/naming-convention -- Keycloak Admin API mapper config keys */
|
|
485
|
+
const ldapUuidMapperConfig = {
|
|
486
|
+
"user.model.attribute": "ldap_uuid",
|
|
487
|
+
"ldap.attribute": options.ldap.uuidLdapAttribute ?? "entryUUID",
|
|
488
|
+
"read.only": "true",
|
|
489
|
+
"always.read.value.from.ldap": "true",
|
|
490
|
+
"is.binary.attribute": "false",
|
|
491
|
+
};
|
|
492
|
+
const claim = options.ldapUuidClaim ?? "ldap_uuid";
|
|
493
|
+
const ldapUuidClaimConfig = {
|
|
494
|
+
"user.attribute": "ldap_uuid",
|
|
495
|
+
"claim.name": claim,
|
|
496
|
+
"jsonType.label": "String",
|
|
497
|
+
"id.token.claim": "true",
|
|
498
|
+
"access.token.claim": "true",
|
|
499
|
+
"userinfo.token.claim": "true",
|
|
500
|
+
};
|
|
501
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
502
|
+
await this.createLdapMapper(realmName, federationId, {
|
|
503
|
+
name: "ldap-uuid",
|
|
504
|
+
providerId: "user-attribute-ldap-mapper",
|
|
505
|
+
config: ldapUuidMapperConfig,
|
|
506
|
+
});
|
|
507
|
+
await this.addClientProtocolMapper(realmName, clientConfig.clientId, {
|
|
508
|
+
name: "ldap-uuid-claim",
|
|
509
|
+
protocolMapper: "oidc-usermodel-attribute-mapper",
|
|
510
|
+
config: ldapUuidClaimConfig,
|
|
511
|
+
});
|
|
512
|
+
await this.syncLdapUsers(federationId);
|
|
513
|
+
this.realm = realmName;
|
|
514
|
+
this.clientId = clientConfig.clientId;
|
|
515
|
+
this.clientSecret = clientConfig.clientSecret;
|
|
516
|
+
this._log(`Configured LDAP realm ${realmName}`);
|
|
517
|
+
}
|
|
336
518
|
/**
|
|
337
519
|
* Teardown Keycloak deployment
|
|
338
520
|
*/
|
|
@@ -475,6 +657,34 @@ spec:
|
|
|
475
657
|
this._log(` Warning: Group ${groupName} not found`);
|
|
476
658
|
}
|
|
477
659
|
}
|
|
660
|
+
_ldapFederationConfigToComponent(config) {
|
|
661
|
+
const bool = (v, fallback) => String(v ?? fallback);
|
|
662
|
+
return {
|
|
663
|
+
enabled: ["true"],
|
|
664
|
+
priority: ["0"],
|
|
665
|
+
vendor: [config.vendor ?? "other"],
|
|
666
|
+
connectionUrl: [config.connectionUrl],
|
|
667
|
+
bindDn: [config.bindDn],
|
|
668
|
+
bindCredential: [config.bindCredential],
|
|
669
|
+
usersDn: [config.usersDn],
|
|
670
|
+
usernameLDAPAttribute: [config.usernameLdapAttribute ?? "uid"],
|
|
671
|
+
rdnLDAPAttribute: [config.rdnLdapAttribute ?? "uid"],
|
|
672
|
+
uuidLDAPAttribute: [config.uuidLdapAttribute ?? "entryUUID"],
|
|
673
|
+
userObjectClasses: [
|
|
674
|
+
config.userObjectClasses ?? "inetOrgPerson, organizationalPerson",
|
|
675
|
+
],
|
|
676
|
+
editMode: [config.editMode ?? "READ_ONLY"],
|
|
677
|
+
importEnabled: [bool(config.importEnabled, true)],
|
|
678
|
+
pagination: [bool(config.pagination, true)],
|
|
679
|
+
searchScope: [config.searchScope ?? "1"],
|
|
680
|
+
trustEmail: [bool(config.trustEmail, true)],
|
|
681
|
+
authType: ["simple"],
|
|
682
|
+
syncRegistrations: ["false"],
|
|
683
|
+
useTruststoreSpi: ["ldapsOnly"],
|
|
684
|
+
connectionPooling: ["true"],
|
|
685
|
+
cachePolicy: ["DEFAULT"],
|
|
686
|
+
};
|
|
687
|
+
}
|
|
478
688
|
_isConflictError(error) {
|
|
479
689
|
const err = error;
|
|
480
690
|
return err.response?.status === 409 || err.status === 409;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { KeycloakHelper } from "./deployment.js";
|
|
2
|
-
export
|
|
2
|
+
export { DEFAULT_GROUPS, DEFAULT_KEYCLOAK_CONFIG, DEFAULT_USERS, } from "./constants.js";
|
|
3
|
+
export type { KeycloakUserConfig, KeycloakGroupConfig, KeycloakLdapFederationConfig, KeycloakLdapRealmOptions, KeycloakClientConfig, } from "./types.js";
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/deployment/keycloak/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/deployment/keycloak/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC5B,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
|
@@ -56,4 +56,39 @@ export type KeycloakConnectionConfig = {
|
|
|
56
56
|
username?: string;
|
|
57
57
|
password?: string;
|
|
58
58
|
};
|
|
59
|
+
export type KeycloakLdapFederationConfig = {
|
|
60
|
+
name?: string;
|
|
61
|
+
connectionUrl: string;
|
|
62
|
+
bindDn: string;
|
|
63
|
+
bindCredential: string;
|
|
64
|
+
usersDn: string;
|
|
65
|
+
usernameLdapAttribute?: string;
|
|
66
|
+
rdnLdapAttribute?: string;
|
|
67
|
+
uuidLdapAttribute?: string;
|
|
68
|
+
userObjectClasses?: string;
|
|
69
|
+
vendor?: string;
|
|
70
|
+
editMode?: string;
|
|
71
|
+
importEnabled?: boolean;
|
|
72
|
+
pagination?: boolean;
|
|
73
|
+
searchScope?: string;
|
|
74
|
+
trustEmail?: boolean;
|
|
75
|
+
};
|
|
76
|
+
export type KeycloakLdapMapperConfig = {
|
|
77
|
+
name: string;
|
|
78
|
+
providerId: string;
|
|
79
|
+
config: Record<string, string>;
|
|
80
|
+
};
|
|
81
|
+
export type KeycloakProtocolMapperConfig = {
|
|
82
|
+
name: string;
|
|
83
|
+
protocol?: string;
|
|
84
|
+
protocolMapper: string;
|
|
85
|
+
config: Record<string, string>;
|
|
86
|
+
};
|
|
87
|
+
export type KeycloakLdapRealmOptions = {
|
|
88
|
+
realm: string;
|
|
89
|
+
client?: Partial<KeycloakClientConfig>;
|
|
90
|
+
ldap: KeycloakLdapFederationConfig;
|
|
91
|
+
/** Protocol mapper claim name for LDAP UUID (default ldap_uuid). */
|
|
92
|
+
ldapUuidClaim?: string;
|
|
93
|
+
};
|
|
59
94
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/deployment/keycloak/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/deployment/keycloak/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Bootstrap tree for RHDH LDAP e2e (OpenLDAP / Bitnami).
|
|
2
|
+
# Loaded via LDAP_CUSTOM_LDIF_DIR=/ldifs — must include root + OUs.
|
|
3
|
+
|
|
4
|
+
dn: dc=rhdh,dc=test
|
|
5
|
+
objectClass: dcObject
|
|
6
|
+
objectClass: organization
|
|
7
|
+
o: RHDH Test
|
|
8
|
+
dc: rhdh
|
|
9
|
+
|
|
10
|
+
dn: ou=users,dc=rhdh,dc=test
|
|
11
|
+
objectClass: organizationalUnit
|
|
12
|
+
ou: users
|
|
13
|
+
|
|
14
|
+
dn: ou=groups,dc=rhdh,dc=test
|
|
15
|
+
objectClass: organizationalUnit
|
|
16
|
+
ou: groups
|
|
17
|
+
|
|
18
|
+
dn: uid=user1,ou=users,dc=rhdh,dc=test
|
|
19
|
+
objectClass: inetOrgPerson
|
|
20
|
+
objectClass: organizationalPerson
|
|
21
|
+
objectClass: person
|
|
22
|
+
objectClass: top
|
|
23
|
+
uid: user1
|
|
24
|
+
cn: User 1
|
|
25
|
+
sn: One
|
|
26
|
+
givenName: User
|
|
27
|
+
mail: user1@rhdh.test
|
|
28
|
+
userPassword: user1pass
|
|
29
|
+
|
|
30
|
+
dn: uid=user2,ou=users,dc=rhdh,dc=test
|
|
31
|
+
objectClass: inetOrgPerson
|
|
32
|
+
objectClass: organizationalPerson
|
|
33
|
+
objectClass: person
|
|
34
|
+
objectClass: top
|
|
35
|
+
uid: user2
|
|
36
|
+
cn: User 2
|
|
37
|
+
sn: Two
|
|
38
|
+
givenName: User
|
|
39
|
+
mail: user2@rhdh.test
|
|
40
|
+
userPassword: user1pass
|
|
41
|
+
|
|
42
|
+
dn: uid=user3,ou=users,dc=rhdh,dc=test
|
|
43
|
+
objectClass: inetOrgPerson
|
|
44
|
+
objectClass: organizationalPerson
|
|
45
|
+
objectClass: person
|
|
46
|
+
objectClass: top
|
|
47
|
+
uid: user3
|
|
48
|
+
cn: User 3
|
|
49
|
+
sn: Three
|
|
50
|
+
givenName: User
|
|
51
|
+
mail: user3@rhdh.test
|
|
52
|
+
userPassword: user1pass
|
|
53
|
+
|
|
54
|
+
dn: uid=rhdh-admin,ou=users,dc=rhdh,dc=test
|
|
55
|
+
objectClass: inetOrgPerson
|
|
56
|
+
objectClass: organizationalPerson
|
|
57
|
+
objectClass: person
|
|
58
|
+
objectClass: top
|
|
59
|
+
uid: rhdh-admin
|
|
60
|
+
cn: RHDH Admin
|
|
61
|
+
sn: Admin
|
|
62
|
+
givenName: RHDH
|
|
63
|
+
mail: rhdh-admin@rhdh.test
|
|
64
|
+
userPassword: user1pass
|
|
65
|
+
|
|
66
|
+
dn: cn=Admins,ou=groups,dc=rhdh,dc=test
|
|
67
|
+
objectClass: groupOfNames
|
|
68
|
+
objectClass: top
|
|
69
|
+
cn: Admins
|
|
70
|
+
member: uid=rhdh-admin,ou=users,dc=rhdh,dc=test
|
|
71
|
+
|
|
72
|
+
dn: cn=All_Users,ou=groups,dc=rhdh,dc=test
|
|
73
|
+
objectClass: groupOfNames
|
|
74
|
+
objectClass: top
|
|
75
|
+
cn: All_Users
|
|
76
|
+
member: uid=user1,ou=users,dc=rhdh,dc=test
|
|
77
|
+
member: uid=user2,ou=users,dc=rhdh,dc=test
|
|
78
|
+
|
|
79
|
+
dn: cn=SubAdmins,ou=groups,dc=rhdh,dc=test
|
|
80
|
+
objectClass: groupOfNames
|
|
81
|
+
objectClass: top
|
|
82
|
+
cn: SubAdmins
|
|
83
|
+
member: uid=rhdh-admin,ou=users,dc=rhdh,dc=test
|
|
84
|
+
|
|
85
|
+
# Nested groups: create leaves before parents so member DNs resolve.
|
|
86
|
+
dn: cn=testSubSubGroup,ou=groups,dc=rhdh,dc=test
|
|
87
|
+
objectClass: groupOfNames
|
|
88
|
+
objectClass: top
|
|
89
|
+
cn: testSubSubGroup
|
|
90
|
+
member: uid=user3,ou=users,dc=rhdh,dc=test
|
|
91
|
+
|
|
92
|
+
dn: cn=testSubGroup,ou=groups,dc=rhdh,dc=test
|
|
93
|
+
objectClass: groupOfNames
|
|
94
|
+
objectClass: top
|
|
95
|
+
cn: testSubGroup
|
|
96
|
+
member: cn=testSubSubGroup,ou=groups,dc=rhdh,dc=test
|
|
97
|
+
|
|
98
|
+
dn: cn=testGroup,ou=groups,dc=rhdh,dc=test
|
|
99
|
+
objectClass: groupOfNames
|
|
100
|
+
objectClass: top
|
|
101
|
+
cn: testGroup
|
|
102
|
+
member: cn=testSubGroup,ou=groups,dc=rhdh,dc=test
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { OpenLDAPDeploymentOptions } from "./types.js";
|
|
2
|
+
/** Default password shared by admin bind and seed user1 (matches ldap.spec pattern). */
|
|
3
|
+
export declare const DEFAULT_OPENLDAP_PASSWORD = "user1pass";
|
|
4
|
+
export declare const DEFAULT_OPENLDAP_CONFIG: {
|
|
5
|
+
releaseName: string;
|
|
6
|
+
adminUser: string;
|
|
7
|
+
adminPassword: string;
|
|
8
|
+
baseDn: string;
|
|
9
|
+
usersOu: string;
|
|
10
|
+
groupsOu: string;
|
|
11
|
+
port: number;
|
|
12
|
+
imageRepository: string;
|
|
13
|
+
imageTag: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const DEFAULT_CONFIG_PATHS: {
|
|
16
|
+
seedLdifFile: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const DEFAULT_USERS: readonly [{
|
|
19
|
+
readonly uid: "user1";
|
|
20
|
+
readonly cn: "User 1";
|
|
21
|
+
readonly sn: "One";
|
|
22
|
+
readonly mail: "user1@rhdh.test";
|
|
23
|
+
readonly password: "user1pass";
|
|
24
|
+
}, {
|
|
25
|
+
readonly uid: "user2";
|
|
26
|
+
readonly cn: "User 2";
|
|
27
|
+
readonly sn: "Two";
|
|
28
|
+
readonly mail: "user2@rhdh.test";
|
|
29
|
+
readonly password: "user1pass";
|
|
30
|
+
}, {
|
|
31
|
+
readonly uid: "user3";
|
|
32
|
+
readonly cn: "User 3";
|
|
33
|
+
readonly sn: "Three";
|
|
34
|
+
readonly mail: "user3@rhdh.test";
|
|
35
|
+
readonly password: "user1pass";
|
|
36
|
+
}, {
|
|
37
|
+
readonly uid: "rhdh-admin";
|
|
38
|
+
readonly cn: "RHDH Admin";
|
|
39
|
+
readonly sn: "Admin";
|
|
40
|
+
readonly mail: "rhdh-admin@rhdh.test";
|
|
41
|
+
readonly password: "user1pass";
|
|
42
|
+
}];
|
|
43
|
+
export declare function buildBindDn(options?: Pick<OpenLDAPDeploymentOptions, "adminUser" | "baseDn">): string;
|
|
44
|
+
export declare function buildUsersDn(options?: Pick<OpenLDAPDeploymentOptions, "usersOu" | "baseDn">): string;
|
|
45
|
+
export declare function buildGroupsDn(options?: Pick<OpenLDAPDeploymentOptions, "groupsOu" | "baseDn">): string;
|
|
46
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/deployment/openldap/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAK5D,wFAAwF;AACxF,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,eAAO,MAAM,uBAAuB;;;;;;;;;;CAWnC,CAAC;AAEF,eAAO,MAAM,oBAAoB;;CAKhC,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;EA6BhB,CAAC;AAEX,wBAAgB,WAAW,CACzB,OAAO,GAAE,IAAI,CAAC,yBAAyB,EAAE,WAAW,GAAG,QAAQ,CAAM,GACpE,MAAM,CAIR;AAED,wBAAgB,YAAY,CAC1B,OAAO,GAAE,IAAI,CAAC,yBAAyB,EAAE,SAAS,GAAG,QAAQ,CAAM,GAClE,MAAM,CAIR;AAED,wBAAgB,aAAa,CAC3B,OAAO,GAAE,IAAI,CAAC,yBAAyB,EAAE,UAAU,GAAG,QAAQ,CAAM,GACnE,MAAM,CAIR"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
// Navigate from dist/deployment/openldap/ to package root
|
|
3
|
+
const PACKAGE_ROOT = path.resolve(import.meta.dirname, "../../..");
|
|
4
|
+
/** Default password shared by admin bind and seed user1 (matches ldap.spec pattern). */
|
|
5
|
+
export const DEFAULT_OPENLDAP_PASSWORD = "user1pass";
|
|
6
|
+
export const DEFAULT_OPENLDAP_CONFIG = {
|
|
7
|
+
releaseName: "openldap",
|
|
8
|
+
adminUser: "admin",
|
|
9
|
+
adminPassword: DEFAULT_OPENLDAP_PASSWORD,
|
|
10
|
+
baseDn: "dc=rhdh,dc=test",
|
|
11
|
+
usersOu: "users",
|
|
12
|
+
groupsOu: "groups",
|
|
13
|
+
port: 1389,
|
|
14
|
+
// Bitnami public Helm chart for OpenLDAP was removed; use the Bitnami legacy image.
|
|
15
|
+
imageRepository: "bitnamilegacy/openldap",
|
|
16
|
+
imageTag: "2.6.10-debian-12-r4",
|
|
17
|
+
};
|
|
18
|
+
export const DEFAULT_CONFIG_PATHS = {
|
|
19
|
+
seedLdifFile: path.join(PACKAGE_ROOT, "dist/deployment/openldap/config/seed.ldif"),
|
|
20
|
+
};
|
|
21
|
+
export const DEFAULT_USERS = [
|
|
22
|
+
{
|
|
23
|
+
uid: "user1",
|
|
24
|
+
cn: "User 1",
|
|
25
|
+
sn: "One",
|
|
26
|
+
mail: "user1@rhdh.test",
|
|
27
|
+
password: DEFAULT_OPENLDAP_PASSWORD,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
uid: "user2",
|
|
31
|
+
cn: "User 2",
|
|
32
|
+
sn: "Two",
|
|
33
|
+
mail: "user2@rhdh.test",
|
|
34
|
+
password: DEFAULT_OPENLDAP_PASSWORD,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
uid: "user3",
|
|
38
|
+
cn: "User 3",
|
|
39
|
+
sn: "Three",
|
|
40
|
+
mail: "user3@rhdh.test",
|
|
41
|
+
password: DEFAULT_OPENLDAP_PASSWORD,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
uid: "rhdh-admin",
|
|
45
|
+
cn: "RHDH Admin",
|
|
46
|
+
sn: "Admin",
|
|
47
|
+
mail: "rhdh-admin@rhdh.test",
|
|
48
|
+
password: DEFAULT_OPENLDAP_PASSWORD,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
export function buildBindDn(options = {}) {
|
|
52
|
+
const adminUser = options.adminUser ?? DEFAULT_OPENLDAP_CONFIG.adminUser;
|
|
53
|
+
const baseDn = options.baseDn ?? DEFAULT_OPENLDAP_CONFIG.baseDn;
|
|
54
|
+
return `cn=${adminUser},${baseDn}`;
|
|
55
|
+
}
|
|
56
|
+
export function buildUsersDn(options = {}) {
|
|
57
|
+
const usersOu = options.usersOu ?? DEFAULT_OPENLDAP_CONFIG.usersOu;
|
|
58
|
+
const baseDn = options.baseDn ?? DEFAULT_OPENLDAP_CONFIG.baseDn;
|
|
59
|
+
return `ou=${usersOu},${baseDn}`;
|
|
60
|
+
}
|
|
61
|
+
export function buildGroupsDn(options = {}) {
|
|
62
|
+
const groupsOu = options.groupsOu ?? DEFAULT_OPENLDAP_CONFIG.groupsOu;
|
|
63
|
+
const baseDn = options.baseDn ?? DEFAULT_OPENLDAP_CONFIG.baseDn;
|
|
64
|
+
return `ou=${groupsOu},${baseDn}`;
|
|
65
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { KubernetesClientHelper } from "../../utils/kubernetes-client.js";
|
|
2
|
+
import type { OpenLDAPDeploymentOptions, OpenLDAPDeploymentConfig, OpenLDAPBindConfig } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Orchestrator-style OpenLDAP helper (Bitnami legacy image).
|
|
5
|
+
* Call from test.runOnce — not globalSetup. Deploys into the Playwright project namespace.
|
|
6
|
+
*/
|
|
7
|
+
export declare class OpenLDAPHelper {
|
|
8
|
+
k8sClient: KubernetesClientHelper;
|
|
9
|
+
deploymentConfig: OpenLDAPDeploymentConfig;
|
|
10
|
+
ldapUrl: string;
|
|
11
|
+
constructor(options?: OpenLDAPDeploymentOptions);
|
|
12
|
+
/**
|
|
13
|
+
* Deploy OpenLDAP into the given namespace (creates namespace if needed).
|
|
14
|
+
*/
|
|
15
|
+
deploy(namespace: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* True if the OpenLDAP service already exists in the configured namespace.
|
|
18
|
+
*/
|
|
19
|
+
isRunning(): Promise<boolean>;
|
|
20
|
+
/** Cluster-internal LDAP URL (Keycloak federation / RHDH ldapOrg). */
|
|
21
|
+
getServiceUrl(): string;
|
|
22
|
+
getBindConfig(): OpenLDAPBindConfig;
|
|
23
|
+
/** Export LDAP_* env vars for RHDH secrets / app-config substitution. */
|
|
24
|
+
exportEnv(): void;
|
|
25
|
+
waitUntilReady(timeout?: number): Promise<void>;
|
|
26
|
+
teardown(): Promise<void>;
|
|
27
|
+
private _buildDeploymentConfig;
|
|
28
|
+
private _applyManifests;
|
|
29
|
+
private _log;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=deployment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../../src/deployment/openldap/deployment.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAS1E,OAAO,KAAK,EACV,yBAAyB,EACzB,wBAAwB,EACxB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,qBAAa,cAAc;IAClB,SAAS,yBAAgC;IACzC,gBAAgB,EAAE,wBAAwB,CAAC;IAC3C,OAAO,SAAM;gBAER,OAAO,GAAE,yBAA8B;IAInD;;OAEG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9C;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAcnC,sEAAsE;IACtE,aAAa,IAAI,MAAM;IAUvB,aAAa,IAAI,kBAAkB;IAYnC,yEAAyE;IACzE,SAAS,IAAI,IAAI;IASX,cAAc,CAAC,OAAO,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAM/B,OAAO,CAAC,sBAAsB;YAoBhB,eAAe;IA0H7B,OAAO,CAAC,IAAI;CAGb"}
|