@@ -3,12 +3,9 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
/// <reference types="express" />
|
||||
/// <reference types="jest" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="qs" />
|
||||
|
||||
import type { AuditorOptions } from '@backstage/backend-defaults/auditor';
|
||||
import { AuditorService } from '@backstage/backend-plugin-api';
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { Backend } from '@backstage/backend-app-api';
|
||||
@@ -37,6 +34,7 @@ import { ParamsDictionary } from 'express-serve-static-core';
|
||||
import { ParsedQs } from 'qs';
|
||||
import { PermissionsRegistryService } from '@backstage/backend-plugin-api';
|
||||
import { PermissionsService } from '@backstage/backend-plugin-api';
|
||||
import type { RootAuditorOptions } from '@backstage/backend-defaults/auditor';
|
||||
import { RootConfigService } from '@backstage/backend-plugin-api';
|
||||
import { RootHealthService } from '@backstage/backend-plugin-api';
|
||||
import { RootHttpRouterService } from '@backstage/backend-plugin-api';
|
||||
@@ -156,14 +154,14 @@ export function mockErrorHandler(): ErrorRequestHandler<
|
||||
// @public
|
||||
export namespace mockServices {
|
||||
export function auditor(
|
||||
options?: Omit<auditor.Options, 'plugin'> & {
|
||||
options?: auditor.Options & {
|
||||
pluginId?: string;
|
||||
},
|
||||
): AuditorService;
|
||||
// (undocumented)
|
||||
export namespace auditor {
|
||||
// (undocumented)
|
||||
export type Options = Omit<AuditorOptions, 'format' | 'transports'>;
|
||||
export type Options = RootAuditorOptions;
|
||||
const // (undocumented)
|
||||
factory: (
|
||||
options?: auditor.Options,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import type { ErrorLike } from '@backstage/errors';
|
||||
import { MockAuditorService } from './MockAuditorService';
|
||||
import { MockRootAuditorService } from './MockAuditorService';
|
||||
import { MockAuthService } from './MockAuthService';
|
||||
import { MockHttpAuthService } from './MockHttpAuthService';
|
||||
import { mockCredentials } from './mockCredentials';
|
||||
@@ -25,81 +25,21 @@ describe('MockAuditorService', () => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should error without plugin service', async () => {
|
||||
const auditor = MockAuditorService.create();
|
||||
await expect(
|
||||
auditor.createEvent({
|
||||
eventId: 'test-event',
|
||||
}),
|
||||
).rejects.toThrow(
|
||||
`The core service 'plugin' was not provided during the auditor's instantiation`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should error without auth service', async () => {
|
||||
const pluginId = 'test-plugin';
|
||||
|
||||
const auditor = MockAuditorService.create().child(
|
||||
{},
|
||||
{
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await expect(
|
||||
auditor.createEvent({
|
||||
eventId: 'test-event',
|
||||
}),
|
||||
).rejects.toThrow(
|
||||
`The core service 'auth' was not provided during the auditor's instantiation`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should error without httpAuth service', async () => {
|
||||
const pluginId = 'test-plugin';
|
||||
|
||||
const auditor = MockAuditorService.create().child(
|
||||
{},
|
||||
{
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
await expect(
|
||||
auditor.createEvent({
|
||||
eventId: 'test-event',
|
||||
}),
|
||||
).rejects.toThrow(
|
||||
`The core service 'httpAuth' was not provided during the auditor's instantiation`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should log', async () => {
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
|
||||
const pluginId = 'test-plugin';
|
||||
|
||||
const auditor = MockAuditorService.create().child(
|
||||
{},
|
||||
{
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
const auditor = MockRootAuditorService.create().forPlugin({
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
);
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
});
|
||||
|
||||
await auditor.createEvent({
|
||||
eventId: 'test-event',
|
||||
@@ -113,19 +53,16 @@ describe('MockAuditorService', () => {
|
||||
|
||||
const pluginId = 'test-plugin';
|
||||
|
||||
const auditor = MockAuditorService.create().child(
|
||||
{},
|
||||
{
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
const auditor = MockRootAuditorService.create().forPlugin({
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
);
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
});
|
||||
|
||||
await auditor.createEvent({
|
||||
eventId: 'test-event',
|
||||
@@ -139,19 +76,16 @@ describe('MockAuditorService', () => {
|
||||
|
||||
const pluginId = 'test-plugin';
|
||||
|
||||
const auditor = MockAuditorService.create().child(
|
||||
{},
|
||||
{
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
const auditor = MockRootAuditorService.create().forPlugin({
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
);
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
});
|
||||
|
||||
const auditorEvent = await auditor.createEvent({
|
||||
eventId: 'test-event',
|
||||
@@ -167,19 +101,16 @@ describe('MockAuditorService', () => {
|
||||
|
||||
const pluginId = 'test-plugin';
|
||||
|
||||
const auditor = MockAuditorService.create().child(
|
||||
{},
|
||||
{
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
const auditor = MockRootAuditorService.create().forPlugin({
|
||||
plugin: {
|
||||
getId: () => pluginId,
|
||||
},
|
||||
);
|
||||
auth: new MockAuthService({
|
||||
pluginId,
|
||||
disableDefaultAuthPolicy: false,
|
||||
}),
|
||||
httpAuth: new MockHttpAuthService(pluginId, mockCredentials.user()),
|
||||
});
|
||||
|
||||
const auditorEvent = await auditor.createEvent({
|
||||
eventId: 'test-event',
|
||||
|
||||
@@ -26,27 +26,47 @@ import type {
|
||||
HttpAuthService,
|
||||
PluginMetadataService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { ForwardedError, ServiceUnavailableError } from '@backstage/errors';
|
||||
import { ForwardedError } from '@backstage/errors';
|
||||
import type { JsonObject } from '@backstage/types';
|
||||
import type { Request } from 'express';
|
||||
import type { mockServices } from './mockServices';
|
||||
|
||||
export class MockAuditorService implements AuditorService {
|
||||
readonly #options: mockServices.auditor.Options & {
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
plugin?: PluginMetadataService;
|
||||
};
|
||||
private readonly impl: MockRootAuditorService;
|
||||
private readonly auth: AuthService;
|
||||
private readonly httpAuth: HttpAuthService;
|
||||
private readonly plugin: PluginMetadataService;
|
||||
|
||||
static create(options?: mockServices.auditor.Options): MockAuditorService {
|
||||
return new MockAuditorService(options ?? {});
|
||||
private constructor(
|
||||
impl: MockRootAuditorService,
|
||||
deps: {
|
||||
auth: AuthService;
|
||||
httpAuth: HttpAuthService;
|
||||
plugin: PluginMetadataService;
|
||||
},
|
||||
) {
|
||||
this.impl = impl;
|
||||
this.auth = deps.auth;
|
||||
this.httpAuth = deps.httpAuth;
|
||||
this.plugin = deps.plugin;
|
||||
}
|
||||
|
||||
static create(
|
||||
impl: MockRootAuditorService,
|
||||
deps: {
|
||||
auth: AuthService;
|
||||
httpAuth: HttpAuthService;
|
||||
plugin: PluginMetadataService;
|
||||
},
|
||||
): AuditorService {
|
||||
return new MockAuditorService(impl, deps);
|
||||
}
|
||||
|
||||
private async log<TMeta extends JsonObject>(
|
||||
options: AuditorEventOptions<TMeta>,
|
||||
): Promise<void> {
|
||||
const auditEvent = await this.reshapeAuditorEvent(options);
|
||||
this.#log(...auditEvent);
|
||||
this.impl.log(auditEvent);
|
||||
}
|
||||
|
||||
async createEvent<TMeta extends JsonObject>(
|
||||
@@ -89,57 +109,25 @@ export class MockAuditorService implements AuditorService {
|
||||
};
|
||||
}
|
||||
|
||||
child(
|
||||
meta: JsonObject,
|
||||
deps?: {
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
plugin?: PluginMetadataService;
|
||||
},
|
||||
): AuditorService {
|
||||
return new MockAuditorService({
|
||||
...this.#options,
|
||||
auth: deps?.auth,
|
||||
httpAuth: deps?.httpAuth,
|
||||
plugin: deps?.plugin,
|
||||
meta: {
|
||||
...this.#options.meta,
|
||||
...meta,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async getActorId(
|
||||
request?: Request<any, any, any, any, any>,
|
||||
): Promise<string | undefined> {
|
||||
if (!this.#options.auth) {
|
||||
throw new ServiceUnavailableError(
|
||||
`The core service 'auth' was not provided during the auditor's instantiation`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.#options.httpAuth) {
|
||||
throw new ServiceUnavailableError(
|
||||
`The core service 'httpAuth' was not provided during the auditor's instantiation`,
|
||||
);
|
||||
}
|
||||
|
||||
let credentials: BackstageCredentials =
|
||||
await this.#options.auth.getOwnServiceCredentials();
|
||||
await this.auth.getOwnServiceCredentials();
|
||||
|
||||
if (request) {
|
||||
try {
|
||||
credentials = await this.#options.httpAuth.credentials(request);
|
||||
credentials = await this.httpAuth.credentials(request);
|
||||
} catch (error) {
|
||||
throw new ForwardedError('Could not resolve credentials', error);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.#options.auth.isPrincipal(credentials, 'user')) {
|
||||
if (this.auth.isPrincipal(credentials, 'user')) {
|
||||
return credentials.principal.userEntityRef;
|
||||
}
|
||||
|
||||
if (this.#options.auth.isPrincipal(credentials, 'service')) {
|
||||
if (this.auth.isPrincipal(credentials, 'service')) {
|
||||
return credentials.principal.subject;
|
||||
}
|
||||
|
||||
@@ -151,14 +139,8 @@ export class MockAuditorService implements AuditorService {
|
||||
): Promise<AuditorEvent> {
|
||||
const { eventId, severityLevel = 'low', request, ...rest } = options;
|
||||
|
||||
if (!this.#options.plugin) {
|
||||
throw new ServiceUnavailableError(
|
||||
`The core service 'plugin' was not provided during the auditor's instantiation`,
|
||||
);
|
||||
}
|
||||
|
||||
const auditEvent: AuditorEvent = [
|
||||
`${this.#options.plugin.getId()}.${eventId}`,
|
||||
`${this.plugin.getId()}.${eventId}`,
|
||||
{
|
||||
severityLevel,
|
||||
actor: {
|
||||
@@ -179,15 +161,32 @@ export class MockAuditorService implements AuditorService {
|
||||
|
||||
return auditEvent;
|
||||
}
|
||||
}
|
||||
|
||||
private constructor(
|
||||
options: mockServices.auditor.Options & {
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
plugin?: PluginMetadataService;
|
||||
},
|
||||
) {
|
||||
this.#options = options;
|
||||
export class MockRootAuditorService {
|
||||
private readonly options: mockServices.auditor.Options;
|
||||
|
||||
private constructor(options?: mockServices.auditor.Options) {
|
||||
this.options = options ?? {};
|
||||
}
|
||||
|
||||
static create(
|
||||
options?: mockServices.auditor.Options,
|
||||
): MockRootAuditorService {
|
||||
return new MockRootAuditorService(options);
|
||||
}
|
||||
|
||||
async log(auditEvent: AuditorEvent): Promise<void> {
|
||||
this.#log(...auditEvent);
|
||||
}
|
||||
|
||||
forPlugin(deps: {
|
||||
auth: AuthService;
|
||||
httpAuth: HttpAuthService;
|
||||
plugin: PluginMetadataService;
|
||||
}): AuditorService {
|
||||
const impl = new MockRootAuditorService(this.options);
|
||||
return MockAuditorService.create(impl, deps);
|
||||
}
|
||||
|
||||
#log(message: string, meta?: AuditorEvent[1]) {
|
||||
|
||||
@@ -51,7 +51,7 @@ import {
|
||||
} from '@backstage/plugin-events-node';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { Knex } from 'knex';
|
||||
import { MockAuditorService } from './MockAuditorService';
|
||||
import { MockRootAuditorService } from './MockAuditorService';
|
||||
import { MockAuthService } from './MockAuthService';
|
||||
import { MockHttpAuthService } from './MockHttpAuthService';
|
||||
import { MockRootLoggerService } from './MockRootLoggerService';
|
||||
@@ -228,7 +228,7 @@ export namespace mockServices {
|
||||
* Creates a mock implementation of the `AuditorService`.
|
||||
*/
|
||||
export function auditor(
|
||||
options?: Omit<auditor.Options, 'plugin'> & {
|
||||
options?: auditor.Options & {
|
||||
pluginId?: string;
|
||||
},
|
||||
): AuditorService {
|
||||
@@ -247,18 +247,19 @@ export namespace mockServices {
|
||||
getId: () => pluginId,
|
||||
};
|
||||
|
||||
const auditorMock = MockAuditorService.create({
|
||||
const auditorMock = MockRootAuditorService.create({
|
||||
meta: options?.meta ? { ...options.meta, service } : { service },
|
||||
});
|
||||
|
||||
return auditorMock.child(
|
||||
{ pluginId },
|
||||
{ auth: mockAuth, httpAuth: mockHttpAuth, plugin: mockPlugin },
|
||||
);
|
||||
return auditorMock.forPlugin({
|
||||
auth: mockAuth,
|
||||
httpAuth: mockHttpAuth,
|
||||
plugin: mockPlugin,
|
||||
});
|
||||
}
|
||||
|
||||
export namespace auditor {
|
||||
export type Options = Omit<RootAuditorOptions, 'format' | 'transports'>;
|
||||
export type Options = RootAuditorOptions;
|
||||
|
||||
export const factory = (options?: auditor.Options) =>
|
||||
createServiceFactory({
|
||||
@@ -271,23 +272,19 @@ export namespace mockServices {
|
||||
createRootContext() {
|
||||
const service = 'backstage';
|
||||
|
||||
return MockAuditorService.create({
|
||||
return MockRootAuditorService.create({
|
||||
meta: options?.meta ? { ...options.meta, service } : { service },
|
||||
});
|
||||
},
|
||||
factory(
|
||||
{
|
||||
plugin,
|
||||
{ auth: mockAuth, httpAuth: mockHttpAuth, plugin: mockPlugin },
|
||||
rootAuditor,
|
||||
) {
|
||||
return rootAuditor.forPlugin({
|
||||
auth: mockAuth,
|
||||
httpAuth: mockHttpAuth,
|
||||
plugin: mockPlugin,
|
||||
},
|
||||
rootAuditor,
|
||||
) {
|
||||
return rootAuditor.child(
|
||||
{ plugin: plugin.getId() },
|
||||
{ auth: mockAuth, httpAuth: mockHttpAuth, plugin: mockPlugin },
|
||||
);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user