@oandriie/backstage-plugin-keycloak-backend
Version:
A Backend backend plugin for Keycloak
220 lines (212 loc) • 7.6 kB
TypeScript
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
import { SchedulerServiceTaskScheduleDefinition, SchedulerServiceTaskRunner, SchedulerService, LoggerService } from '@backstage/backend-plugin-api';
import { Config } from '@backstage/config';
import { EntityProvider, EntityProviderConnection } from '@backstage/plugin-catalog-node';
import { GroupEntity, UserEntity } from '@backstage/catalog-model';
import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation';
import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation';
interface GroupRepresentationWithParent extends GroupRepresentation {
parentId?: string;
parent?: string;
members?: string[];
}
interface GroupRepresentationWithParentAndEntity extends GroupRepresentationWithParent {
entity: GroupEntity;
}
interface UserRepresentationWithEntity extends UserRepresentation {
entity: UserEntity;
}
/**
* 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<UserEntity | undefined>} 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<UserEntity | undefined>;
/**
* 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<GroupEntity | undefined>} 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<GroupEntity | undefined>;
/**
* 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?: SchedulerServiceTaskScheduleDefinition;
/**
* 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.
* @remarks
*
* You can pass in the result of
* {@link @backstage/backend-plugin-api#SchedulerService.createScheduledTaskRunner}
* to enable automatic scheduling of tasks.
*/
schedule?: SchedulerServiceTaskRunner;
/**
* Scheduler used to schedule refreshes based on
* the schedule config.
*/
scheduler?: SchedulerService;
/**
* 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(deps: {
config: Config;
logger: LoggerService;
}, options: ({
schedule: SchedulerServiceTaskRunner;
} | {
scheduler: SchedulerService;
}) & {
userTransformer?: UserTransformer;
groupTransformer?: GroupTransformer;
}): KeycloakOrgEntityProvider[];
constructor(options: {
id: string;
provider: KeycloakProviderConfig;
logger: LoggerService;
taskRunner: SchedulerServiceTaskRunner;
userTransformer?: UserTransformer;
groupTransformer?: GroupTransformer;
});
getProviderName(): string;
connect(connection: EntityProviderConnection): Promise<void>;
/**
* Runs one complete ingestion loop. Call this method regularly at some
* appropriate cadence.
*/
read(options?: {
logger?: LoggerService;
}): Promise<void>;
schedule(taskRunner: SchedulerServiceTaskRunner): 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;
/**
* An extension point that exposes the ability to implement user and group transformer functions for keycloak.
*
* @public
*/
declare const keycloakTransformerExtensionPoint: _backstage_backend_plugin_api.ExtensionPoint<KeycloakTransformerExtensionPoint>;
/**
* The interface for {@link keycloakTransformerExtensionPoint}.
*
* @public
*/
type KeycloakTransformerExtensionPoint = {
setUserTransformer(userTransformer: UserTransformer): void;
setGroupTransformer(groupTransformer: GroupTransformer): void;
};
/**
* Registers the `KeycloakEntityProvider` with the catalog processing extension point.
*
* @alpha
*/
declare const catalogModuleKeycloakEntityProvider: _backstage_backend_plugin_api.BackendFeature;
export { type GroupRepresentationWithParent, type GroupRepresentationWithParentAndEntity, type GroupTransformer, KeycloakOrgEntityProvider, type KeycloakOrgEntityProviderOptions, type KeycloakTransformerExtensionPoint, type UserRepresentationWithEntity, type UserTransformer, catalogModuleKeycloakEntityProvider as default, keycloakTransformerExtensionPoint, noopGroupTransformer, noopUserTransformer, sanitizeEmailTransformer };