import { LoggerService } from '@backstage/backend-plugin-api'; import { TaskScheduleDefinition, TaskRunner, PluginTaskScheduler } from '@backstage/backend-tasks'; import { Config } from '@backstage/config'; import { EntityProvider, EntityProviderConnection } from '@backstage/plugin-catalog-node'; import { UserEntity, GroupEntity } from '@backstage/catalog-model'; import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation'; import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'; import { BackendDynamicPluginInstaller } from '@backstage/backend-dynamic-feature-service'; interface GroupRepresentationWithParent extends GroupRepresentation { parent?: string; members?: string[]; } interface GroupRepresentationWithParentAndEntity extends GroupRepresentationWithParent { entity: GroupEntity; } /** * Customize the ingested User entity * * @public * * @param {UserEntity} entity The output of the default parser * @param {UserRepresentation} user Keycloak user representation * @param {string} realm Realm name * @param {GroupRepresentationWithParentAndEntity[]} groups Data about available groups (can be used to create additional relationships) * * @returns {Promise} Resolve to a modified `UserEntity` object that will be ingested into the catalog or resolve to `undefined` to reject the entity */ type UserTransformer = (entity: UserEntity, user: UserRepresentation, realm: string, groups: GroupRepresentationWithParentAndEntity[]) => Promise; /** * Customize the ingested Group entity * * @public * * @param {GroupEntity} entity The output of the default parser * @param {GroupRepresentation} group Keycloak group representation * @param {string} realm Realm name * * @returns {Promise} Resolve to a modified `GroupEntity` object that will be ingested into the catalog or resolve to `undefined` to reject the entity */ type GroupTransformer = (entity: GroupEntity, group: GroupRepresentation, realm: string) => Promise; /** * The configuration parameters for a single Keycloak provider. * * @public */ type KeycloakProviderConfig = { /** * Identifier of the provider which will be used i.e. at the location key for ingested entities. */ id: string; /** * The Keycloak base URL */ baseUrl: string; /** * The username to use for authenticating requests * If specified, password must also be specified */ username?: string; /** * The password to use for authenticating requests * If specified, username must also be specified */ password?: string; /** * The clientId to use for authenticating requests * If specified, clientSecret must also be specified */ clientId?: string; /** * The clientSecret to use for authenticating requests * If specified, clientId must also be specified */ clientSecret?: string; /** * name of the Keycloak realm */ realm: string; /** * name of the Keycloak login realm */ loginRealm?: string; /** * Schedule configuration for refresh tasks. */ schedule?: TaskScheduleDefinition; /** * The number of users to query at a time. * @defaultValue 100 * @remarks * This is a performance optimization to avoid querying too many users at once. * @see https://www.keycloak.org/docs-api/11.0/rest-api/index.html#_users_resource */ userQuerySize?: number; /** * The number of groups to query at a time. * @defaultValue 100 * @remarks * This is a performance optimization to avoid querying too many groups at once. * @see https://www.keycloak.org/docs-api/11.0/rest-api/index.html#_groups_resource */ groupQuerySize?: number; }; /** * Options for {@link KeycloakOrgEntityProvider}. * * @public */ interface KeycloakOrgEntityProviderOptions { /** * A unique, stable identifier for this provider. * * @example "production" */ id: string; /** * The refresh schedule to use. * * @defaultValue "manual" * @remarks * * If you pass in 'manual', you are responsible for calling the `read` method * manually at some interval. * * But more commonly you will pass in the result of * {@link @backstage/backend-tasks#PluginTaskScheduler.createScheduledTaskRunner} * to enable automatic scheduling of tasks. */ schedule?: 'manual' | TaskRunner; /** * Scheduler used to schedule refreshes based on * the schedule config. */ scheduler?: PluginTaskScheduler; /** * The logger to use. */ logger: LoggerService; /** * The function that transforms a user entry in LDAP to an entity. */ userTransformer?: UserTransformer; /** * The function that transforms a group entry in LDAP to an entity. */ groupTransformer?: GroupTransformer; } /** * Ingests org data (users and groups) from GitHub. * * @public */ declare class KeycloakOrgEntityProvider implements EntityProvider { private options; private connection?; private scheduleFn?; static fromConfig(configRoot: Config, options: KeycloakOrgEntityProviderOptions): KeycloakOrgEntityProvider[]; constructor(options: { id: string; provider: KeycloakProviderConfig; logger: LoggerService; userTransformer?: UserTransformer; groupTransformer?: GroupTransformer; }); getProviderName(): string; connect(connection: EntityProviderConnection): Promise; /** * Runs one complete ingestion loop. Call this method regularly at some * appropriate cadence. */ read(options?: { logger?: LoggerService; }): Promise; schedule(taskRunner: TaskRunner): void; } declare const noopGroupTransformer: GroupTransformer; declare const noopUserTransformer: UserTransformer; /** * User transformer that sanitizes .metadata.name from email address to a valid name */ declare const sanitizeEmailTransformer: UserTransformer; declare const dynamicPluginInstaller: BackendDynamicPluginInstaller; export { type GroupTransformer, KeycloakOrgEntityProvider, type KeycloakOrgEntityProviderOptions, type UserTransformer, dynamicPluginInstaller, noopGroupTransformer, noopUserTransformer, sanitizeEmailTransformer };