backend-plugin-api: remove identity and token manager services

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-08-21 15:31:15 +02:00
parent 337a4704a6
commit 1780a67bc5
47 changed files with 86 additions and 507 deletions
-16
View File
@@ -4,9 +4,7 @@
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
import { IdentityService } from '@backstage/backend-plugin-api';
import { ServiceFactory } from '@backstage/backend-plugin-api';
import { TokenManagerService } from '@backstage/backend-plugin-api';
// @public (undocumented)
export interface Backend {
@@ -34,18 +32,4 @@ export interface CreateSpecializedBackendOptions {
// (undocumented)
defaultServiceFactories: ServiceFactory[];
}
// @public @deprecated (undocumented)
export const identityServiceFactory: ServiceFactory<
IdentityService,
'plugin',
'singleton'
>;
// @public @deprecated (undocumented)
export const tokenManagerServiceFactory: ServiceFactory<
TokenManagerService,
'plugin',
'singleton'
>;
```
-1
View File
@@ -21,4 +21,3 @@
*/
export * from './wiring';
export * from './services/implementations';
@@ -1,35 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
coreServices,
createServiceFactory,
} from '@backstage/backend-plugin-api';
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
/**
* @public
* @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
*/
export const identityServiceFactory = createServiceFactory({
service: coreServices.identity,
deps: {
discovery: coreServices.discovery,
},
async factory({ discovery }) {
return DefaultIdentityClient.create({ discovery });
},
});
@@ -1,17 +0,0 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { identityServiceFactory } from './identityServiceFactory';
@@ -1,18 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './identity';
export * from './tokenManager';
@@ -1,17 +0,0 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { tokenManagerServiceFactory } from './tokenManagerServiceFactory';
@@ -1,33 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { tokenManagerServiceFactory } from './tokenManagerServiceFactory';
import { ServiceFactoryTester } from '@backstage/backend-test-utils';
describe('tokenManagerFactory', () => {
it('should create a disabled manager without configuration', async () => {
const tokenManager = await ServiceFactoryTester.from(
tokenManagerServiceFactory,
).getSubject();
await expect(tokenManager.authenticate('abc')).rejects.toThrow(
'no legacy keys are configured',
);
await expect(tokenManager.getToken()).rejects.toThrow(
'no legacy keys are configured',
);
});
});
@@ -1,42 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
coreServices,
createServiceFactory,
} from '@backstage/backend-plugin-api';
import { ServerTokenManager } from '@backstage/backend-common';
/**
* @public
* @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
*/
export const tokenManagerServiceFactory = createServiceFactory({
service: coreServices.tokenManager,
deps: {
config: coreServices.rootConfig,
logger: coreServices.rootLogger,
},
createRootContext({ config, logger }) {
return ServerTokenManager.fromConfig(config, {
logger,
allowDisabledTokenManager: true,
});
},
async factory(_deps, tokenManager) {
return tokenManager;
},
});
+7 -4
View File
@@ -22,7 +22,6 @@ import Docker from 'dockerode';
import { ErrorRequestHandler } from 'express';
import express from 'express';
import { HttpAuthService } from '@backstage/backend-plugin-api';
import { IdentityService } from '@backstage/backend-plugin-api';
import { isChildPath as isChildPath_2 } from '@backstage/backend-plugin-api';
import { isDatabaseConflictError as isDatabaseConflictError_2 } from '@backstage/backend-plugin-api';
import { KubeConfig } from '@kubernetes/client-node';
@@ -44,7 +43,6 @@ import { Router } from 'express';
import { SchedulerService } from '@backstage/backend-plugin-api';
import { Server } from 'http';
import { ServiceRef } from '@backstage/backend-plugin-api';
import { TokenManagerService } from '@backstage/backend-plugin-api';
import { TransportStreamOptions } from 'winston-transport';
import { UrlReaderService } from '@backstage/backend-plugin-api';
import { UserInfoService } from '@backstage/backend-plugin-api';
@@ -101,7 +99,7 @@ export function createLegacyAuthAdapters<
auth?: AuthService;
httpAuth?: HttpAuthService;
userInfo?: UserInfoService;
identity?: IdentityService;
identity?: LegacyIdentityService;
tokenManager?: TokenManager;
discovery: PluginEndpointDiscovery;
},
@@ -547,7 +545,12 @@ export interface StatusCheckHandlerOptions {
}
// @public @deprecated (undocumented)
export type TokenManager = TokenManagerService;
export interface TokenManager {
authenticate(token: string): Promise<void>;
getToken(): Promise<{
token: string;
}>;
}
// @public @deprecated
export function useHotCleanup(
@@ -14,18 +14,28 @@
* limitations under the License.
*/
import { mockServices } from '@backstage/backend-test-utils';
import { createLegacyAuthAdapters } from './createLegacyAuthAdapters';
import { Request } from 'express';
import { TokenManager } from '../../deprecated';
const mockTokenManager: TokenManager = {
async getToken(): Promise<{ token: string }> {
return { token: 'mock-token' };
},
async authenticate(token: string): Promise<void> {
if (token !== 'mock-token') {
throw new Error('Invalid token');
}
},
};
describe('createLegacyAuthAdapters', () => {
it('should pass through auth if only auth is provided', () => {
const auth = {};
const ret = createLegacyAuthAdapters({
auth: auth as any,
tokenManager: mockServices.tokenManager(),
tokenManager: mockTokenManager,
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret.auth).toBe(auth);
@@ -35,9 +45,8 @@ describe('createLegacyAuthAdapters', () => {
const httpAuth = {};
const ret = createLegacyAuthAdapters({
httpAuth: httpAuth as any,
tokenManager: mockServices.tokenManager(),
tokenManager: mockTokenManager,
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret.httpAuth).toBe(httpAuth);
@@ -49,9 +58,8 @@ describe('createLegacyAuthAdapters', () => {
const ret = createLegacyAuthAdapters({
auth: auth as any,
httpAuth: httpAuth as any,
tokenManager: mockServices.tokenManager(),
tokenManager: mockTokenManager,
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret.auth).toBe(auth);
@@ -64,9 +72,8 @@ describe('createLegacyAuthAdapters', () => {
const ret = createLegacyAuthAdapters({
auth: auth as any,
userInfo: userInfo as any,
tokenManager: mockServices.tokenManager(),
tokenManager: mockTokenManager,
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret.auth).toBe(auth);
@@ -77,9 +84,8 @@ describe('createLegacyAuthAdapters', () => {
const ret = createLegacyAuthAdapters({
auth: undefined,
httpAuth: undefined,
tokenManager: mockServices.tokenManager(),
tokenManager: mockTokenManager,
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret).toEqual({
@@ -94,7 +100,6 @@ describe('createLegacyAuthAdapters', () => {
auth: undefined,
httpAuth: undefined,
discovery: {} as any,
identity: mockServices.identity(),
});
const credentials = await httpAuth.credentials({
@@ -116,13 +121,12 @@ describe('createLegacyAuthAdapters', () => {
auth: undefined,
httpAuth: undefined,
tokenManager: {
...mockServices.tokenManager(),
...mockTokenManager,
async getToken() {
return { token: 'new-token' };
},
},
discovery: {} as any,
identity: mockServices.identity(),
});
const credentials = await httpAuth.credentials({
@@ -23,8 +23,6 @@ import {
BackstageUserInfo,
BackstageUserPrincipal,
HttpAuthService,
IdentityService,
TokenManagerService,
UserInfoService,
} from '@backstage/backend-plugin-api';
import { AuthenticationError, NotAllowedError } from '@backstage/errors';
@@ -44,11 +42,12 @@ import {
import { decodeJwt } from 'jose';
import { TokenManager, PluginEndpointDiscovery } from '../../deprecated';
import { JsonObject } from '@backstage/types';
import { LegacyIdentityService } from '../legacy';
class AuthCompat implements AuthService {
constructor(
private readonly identity: IdentityService,
private readonly tokenManager?: TokenManagerService,
private readonly identity: LegacyIdentityService,
private readonly tokenManager?: TokenManager,
) {}
isPrincipal<TType extends keyof BackstagePrincipalTypes>(
@@ -299,7 +298,7 @@ export function createLegacyAuthAdapters<
auth?: AuthService;
httpAuth?: HttpAuthService;
userInfo?: UserInfoService;
identity?: IdentityService;
identity?: LegacyIdentityService;
tokenManager?: TokenManager;
discovery: PluginEndpointDiscovery;
},
@@ -14,10 +14,25 @@
* limitations under the License.
*/
import { TokenManagerService } from '@backstage/backend-plugin-api';
/**
* @public
* @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
*/
export type TokenManager = TokenManagerService;
export interface TokenManager {
/**
* Fetches a valid token.
*
* @remarks
*
* Tokens are valid for roughly one hour; the actual deadline is set in the
* payload `exp` claim. Never hold on to tokens for reuse; always ask for a
* new one for each outgoing request. This ensures that you always get a
* valid, fresh one.
*/
getToken(): Promise<{ token: string }>;
/**
* Validates a given token.
*/
authenticate(token: string): Promise<void>;
}
@@ -14,12 +14,7 @@
* limitations under the License.
*/
import {
Backend,
createSpecializedBackend,
identityServiceFactory,
tokenManagerServiceFactory,
} from '@backstage/backend-app-api';
import { Backend, createSpecializedBackend } from '@backstage/backend-app-api';
import { authServiceFactory } from '@backstage/backend-defaults/auth';
import { cacheServiceFactory } from '@backstage/backend-defaults/cache';
import { databaseServiceFactory } from '@backstage/backend-defaults/database';
@@ -47,7 +42,6 @@ export const defaultServiceFactories = [
discoveryServiceFactory,
httpAuthServiceFactory,
httpRouterServiceFactory,
identityServiceFactory,
lifecycleServiceFactory,
loggerServiceFactory,
permissionsServiceFactory,
@@ -56,7 +50,6 @@ export const defaultServiceFactories = [
rootLifecycleServiceFactory,
rootLoggerServiceFactory,
schedulerServiceFactory,
tokenManagerServiceFactory,
userInfoServiceFactory,
urlReaderServiceFactory,
eventsServiceFactory,
@@ -19,7 +19,6 @@ import {
mockServices,
registerMswTestHooks,
} from '@backstage/backend-test-utils';
import { tokenManagerServiceFactory } from '@backstage/backend-app-api';
import { authServiceFactory } from './authServiceFactory';
import { base64url, decodeJwt } from 'jose';
import { discoveryServiceFactory } from '../discovery';
@@ -32,7 +31,6 @@ const server = setupServer();
// TODO: Ship discovery mock service in the service factory tester
const mockDeps = [
discoveryServiceFactory,
tokenManagerServiceFactory,
mockServices.rootConfig.factory({
data: {
backend: {
@@ -35,13 +35,11 @@ export const permissionsServiceFactory = createServiceFactory({
auth: coreServices.auth,
config: coreServices.rootConfig,
discovery: coreServices.discovery,
tokenManager: coreServices.tokenManager,
},
async factory({ auth, config, discovery, tokenManager }) {
async factory({ auth, config, discovery }) {
return ServerPermissionClient.fromConfig(config, {
auth,
discovery,
tokenManager,
});
},
});
-16
View File
@@ -12,7 +12,6 @@ import { Duration } from 'luxon';
import { EvaluatorRequestOptions } from '@backstage/plugin-permission-common';
import { Handler } from 'express';
import { HumanDuration } from '@backstage/types';
import { IdentityApi } from '@backstage/plugin-auth-node';
import { isChildPath } from '@backstage/cli-common';
import { JsonObject } from '@backstage/types';
import { JsonValue } from '@backstage/types';
@@ -194,11 +193,7 @@ export namespace coreServices {
const rootLifecycle: ServiceRef<RootLifecycleService, 'root', 'singleton'>;
const rootLogger: ServiceRef<RootLoggerService, 'root', 'singleton'>;
const scheduler: ServiceRef<SchedulerService, 'plugin', 'singleton'>;
const // @deprecated
tokenManager: ServiceRef<TokenManagerService, 'plugin', 'singleton'>;
const urlReader: ServiceRef<UrlReaderService, 'plugin', 'singleton'>;
const // @deprecated
identity: ServiceRef<IdentityService, 'plugin', 'singleton'>;
}
// @public
@@ -383,9 +378,6 @@ export interface HttpRouterServiceAuthPolicy {
path: string;
}
// @public @deprecated
export interface IdentityService extends IdentityApi {}
export { isChildPath };
// @public
@@ -657,14 +649,6 @@ export interface ServiceRefOptions<
scope?: TScope;
}
// @public @deprecated
export interface TokenManagerService {
authenticate(token: string): Promise<void>;
getToken(): Promise<{
token: string;
}>;
}
// @public
export interface UrlReaderService {
readTree(
@@ -1,27 +0,0 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { IdentityApi } from '@backstage/plugin-auth-node';
/**
* This is the legacy service for identity handling in Backstage. Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
*
* See the {@link https://backstage.io/docs/backend-system/core-services/identity | service documentation} for more details.
*
* @public
* @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
*/
export interface IdentityService extends IdentityApi {}
@@ -1,42 +0,0 @@
/*
* Copyright 2022 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This is the legacy service for creating and validating tokens. Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
*
* See the {@link https://backstage.io/docs/backend-system/core-services/token-manager | service documentation} for more details.
*
* @public
* @deprecated Please {@link https://backstage.io/docs/tutorials/auth-service-migration | migrate} to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead.
*/
export interface TokenManagerService {
/**
* Fetches a valid token.
*
* @remarks
*
* Tokens are valid for roughly one hour; the actual deadline is set in the
* payload `exp` claim. Never hold on to tokens for reuse; always ask for a
* new one for each outgoing request. This ensures that you always get a
* valid, fresh one.
*/
getToken(): Promise<{ token: string }>;
/**
* Validates a given token.
*/
authenticate(token: string): Promise<void>;
}
@@ -239,20 +239,6 @@ export namespace coreServices {
import('./SchedulerService').SchedulerService
>({ id: 'core.scheduler' });
/**
* Deprecated service authentication service, use the `auth` service instead.
*
* See {@link TokenManagerService}
* and {@link https://backstage.io/docs/backend-system/core-services/token-manager | the service docs}
* for more information.
*
* @public
* @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
*/
export const tokenManager = createServiceRef<
import('./TokenManagerService').TokenManagerService
>({ id: 'core.tokenManager' });
/**
* Reading content from external systems.
*
@@ -265,18 +251,4 @@ export namespace coreServices {
export const urlReader = createServiceRef<
import('./UrlReaderService').UrlReaderService
>({ id: 'core.urlReader' });
/**
* Deprecated user authentication service, use the `auth` service instead.
*
* See {@link IdentityService}
* and {@link https://backstage.io/docs/backend-system/core-services/identity | the service docs}
* for more information.
*
* @public
* @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead
*/
export const identity = createServiceRef<
import('./IdentityService').IdentityService
>({ id: 'core.identity' });
}
@@ -64,7 +64,6 @@ export type {
SchedulerServiceTaskScheduleDefinition,
SchedulerServiceTaskScheduleDefinitionConfig,
} from './SchedulerService';
export type { TokenManagerService } from './TokenManagerService';
export type {
UrlReaderServiceReadTreeOptions,
UrlReaderServiceReadTreeResponse,
@@ -78,4 +77,3 @@ export type {
UrlReaderService,
} from './UrlReaderService';
export type { BackstageUserInfo, UserInfoService } from './UserInfoService';
export type { IdentityService } from './IdentityService';
-24
View File
@@ -23,7 +23,6 @@ import { ExtendedHttpServer } from '@backstage/backend-defaults/rootHttpRouter';
import { ExtensionPoint } from '@backstage/backend-plugin-api';
import { HttpAuthService } from '@backstage/backend-plugin-api';
import { HttpRouterService } from '@backstage/backend-plugin-api';
import { IdentityService } from '@backstage/backend-plugin-api';
import { JsonObject } from '@backstage/types';
import Keyv from 'keyv';
import { Knex } from 'knex';
@@ -39,7 +38,6 @@ import { RootLoggerService } from '@backstage/backend-plugin-api';
import { SchedulerService } from '@backstage/backend-plugin-api';
import { ServiceFactory } from '@backstage/backend-plugin-api';
import { ServiceRef } from '@backstage/backend-plugin-api';
import { TokenManagerService } from '@backstage/backend-plugin-api';
import { UrlReaderService } from '@backstage/backend-plugin-api';
import { UserInfoService } from '@backstage/backend-plugin-api';
@@ -217,17 +215,6 @@ export namespace mockServices {
) => ServiceMock<HttpRouterService>;
}
// (undocumented)
export function identity(): IdentityService;
// (undocumented)
export namespace identity {
const // (undocumented)
factory: () => ServiceFactory<IdentityService, 'plugin', 'singleton'>;
const // (undocumented)
mock: (
partialImpl?: Partial<IdentityService> | undefined,
) => ServiceMock<IdentityService>;
}
// (undocumented)
export namespace lifecycle {
const // (undocumented)
factory: () => ServiceFactory<LifecycleService, 'plugin', 'singleton'>;
@@ -324,17 +311,6 @@ export namespace mockServices {
) => ServiceMock<SchedulerService>;
}
// (undocumented)
export function tokenManager(): TokenManagerService;
// (undocumented)
export namespace tokenManager {
const // (undocumented)
factory: () => ServiceFactory<TokenManagerService, 'plugin', 'singleton'>;
const // (undocumented)
mock: (
partialImpl?: Partial<TokenManagerService> | undefined,
) => ServiceMock<TokenManagerService>;
}
// (undocumented)
export namespace urlReader {
const // (undocumented)
factory: () => ServiceFactory<UrlReaderService, 'plugin', 'singleton'>;
@@ -1,35 +0,0 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { IdentityService } from '@backstage/backend-plugin-api';
import {
IdentityApiGetIdentityRequest,
BackstageIdentityResponse,
} from '@backstage/plugin-auth-node';
export class MockIdentityService implements IdentityService {
getIdentity(
_options: IdentityApiGetIdentityRequest,
): Promise<BackstageIdentityResponse | undefined> {
return Promise.resolve({
token: 'mock-token',
identity: {
type: 'user',
userEntityRef: 'user:default/mock-user',
ownershipEntityRefs: [],
},
});
}
}
@@ -35,12 +35,10 @@ import {
BackstageUserInfo,
DiscoveryService,
HttpAuthService,
IdentityService,
LoggerService,
RootConfigService,
ServiceFactory,
ServiceRef,
TokenManagerService,
UserInfoService,
coreServices,
createServiceFactory,
@@ -53,7 +51,6 @@ import {
import { JsonObject } from '@backstage/types';
import { MockAuthService } from './MockAuthService';
import { MockHttpAuthService } from './MockHttpAuthService';
import { MockIdentityService } from './MockIdentityService';
import { MockRootLoggerService } from './MockRootLoggerService';
import { MockUserInfoService } from './MockUserInfoService';
import { mockCredentials } from './mockCredentials';
@@ -167,46 +164,6 @@ export namespace mockServices {
}));
}
export function tokenManager(): TokenManagerService {
return {
async getToken(): Promise<{ token: string }> {
return { token: 'mock-token' };
},
async authenticate(token: string): Promise<void> {
if (token !== 'mock-token') {
throw new Error('Invalid token');
}
},
};
}
export namespace tokenManager {
export const factory = () =>
createServiceFactory({
service: coreServices.tokenManager,
deps: {},
factory: () => tokenManager(),
});
export const mock = simpleMock(coreServices.tokenManager, () => ({
authenticate: jest.fn(),
getToken: jest.fn(),
}));
}
export function identity(): IdentityService {
return new MockIdentityService();
}
export namespace identity {
export const factory = () =>
createServiceFactory({
service: coreServices.identity,
deps: {},
factory: () => identity(),
});
export const mock = simpleMock(coreServices.identity, () => ({
getIdentity: jest.fn(),
}));
}
export function auth(options?: {
pluginId?: string;
disableDefaultAuthPolicy?: boolean;
@@ -198,13 +198,12 @@ describe('TestBackend', () => {
rootLifecycle: coreServices.rootLifecycle,
rootLogger: coreServices.rootLogger,
scheduler: coreServices.scheduler,
tokenManager: coreServices.tokenManager,
urlReader: coreServices.urlReader,
auth: coreServices.auth,
httpAuth: coreServices.httpAuth,
},
async init(deps) {
expect(Object.keys(deps)).toHaveLength(17);
expect(Object.keys(deps)).toHaveLength(16);
expect(Object.values(deps)).not.toContain(undefined);
},
});
@@ -72,7 +72,6 @@ export const defaultServiceFactories = [
mockServices.database.factory(),
mockServices.httpAuth.factory(),
mockServices.httpRouter.factory(),
mockServices.identity.factory(),
mockServices.lifecycle.factory(),
mockServices.logger.factory(),
mockServices.permissions.factory(),
@@ -80,7 +79,6 @@ export const defaultServiceFactories = [
mockServices.rootLifecycle.factory(),
mockServices.rootLogger.factory(),
mockServices.scheduler.factory(),
mockServices.tokenManager.factory(),
mockServices.userInfo.factory(),
mockServices.urlReader.factory(),
mockServices.events.factory(),
+2 -3
View File
@@ -41,7 +41,6 @@ import { RootConfigService } from '@backstage/backend-plugin-api';
import { SignInInfo as SignInInfo_2 } from '@backstage/plugin-auth-node';
import { SignInResolver as SignInResolver_2 } from '@backstage/plugin-auth-node';
import { TokenManager } from '@backstage/backend-common';
import { TokenManagerService } from '@backstage/backend-plugin-api';
import { TokenParams as TokenParams_2 } from '@backstage/plugin-auth-node';
import { UserEntity } from '@backstage/catalog-model';
import { WebMessageResponse as WebMessageResponse_2 } from '@backstage/plugin-auth-node';
@@ -126,7 +125,7 @@ export type BitbucketServerOAuthResult = {
export class CatalogIdentityClient {
constructor(options: {
catalogApi: CatalogApi;
tokenManager: TokenManager;
tokenManager?: TokenManager;
discovery: DiscoveryService;
auth?: AuthService;
httpAuth?: HttpAuthService;
@@ -673,7 +672,7 @@ export interface RouterOptions {
// (undocumented)
tokenFactoryAlgorithm?: string;
// (undocumented)
tokenManager: TokenManagerService;
tokenManager?: TokenManager;
}
// @public (undocumented)
-3
View File
@@ -65,7 +65,6 @@ export const authPlugin = createBackendPlugin({
config: coreServices.rootConfig,
database: coreServices.database,
discovery: coreServices.discovery,
tokenManager: coreServices.tokenManager,
auth: coreServices.auth,
httpAuth: coreServices.httpAuth,
catalogApi: catalogServiceRef,
@@ -76,7 +75,6 @@ export const authPlugin = createBackendPlugin({
config,
database,
discovery,
tokenManager,
auth,
httpAuth,
catalogApi,
@@ -86,7 +84,6 @@ export const authPlugin = createBackendPlugin({
config,
database,
discovery,
tokenManager,
auth,
httpAuth,
catalogApi,
@@ -45,7 +45,7 @@ export class CatalogIdentityClient {
constructor(options: {
catalogApi: CatalogApi;
tokenManager: TokenManager;
tokenManager?: TokenManager;
discovery: DiscoveryService;
auth?: AuthService;
httpAuth?: HttpAuthService;
@@ -34,7 +34,6 @@ describe('CatalogAuthResolverContext', () => {
logger: mockServices.logger.mock(),
catalogApi: mockCatalogApi as CatalogApi,
tokenIssuer: {} as TokenIssuer,
tokenManager: mockServices.tokenManager(),
discovery: {} as DiscoveryService,
auth: mockServices.auth(),
httpAuth: mockServices.httpAuth(),
@@ -66,7 +66,7 @@ export class CatalogAuthResolverContext implements AuthResolverContext {
logger: LoggerService;
catalogApi: CatalogApi;
tokenIssuer: TokenIssuer;
tokenManager: TokenManager;
tokenManager?: TokenManager;
discovery: DiscoveryService;
auth: AuthService;
httpAuth: HttpAuthService;
+1 -1
View File
@@ -50,7 +50,7 @@ export function bindProviderRouters(
discovery: PluginEndpointDiscovery;
auth: AuthService;
httpAuth: HttpAuthService;
tokenManager: TokenManager;
tokenManager?: TokenManager;
tokenIssuer: TokenIssuer;
ownershipResolver?: AuthOwnershipResolver;
catalogApi?: CatalogApi;
+5 -3
View File
@@ -24,11 +24,13 @@ import {
HttpAuthService,
LoggerService,
RootConfigService,
TokenManagerService,
} from '@backstage/backend-plugin-api';
import { defaultAuthProviderFactories } from '../providers';
import { AuthOwnershipResolver } from '@backstage/plugin-auth-node';
import { createLegacyAuthAdapters } from '@backstage/backend-common';
import {
TokenManager,
createLegacyAuthAdapters,
} from '@backstage/backend-common';
import { NotFoundError } from '@backstage/errors';
import { CatalogApi } from '@backstage/catalog-client';
import {
@@ -56,7 +58,7 @@ export interface RouterOptions {
database: DatabaseService;
config: RootConfigService;
discovery: DiscoveryService;
tokenManager: TokenManagerService;
tokenManager?: TokenManager;
auth?: AuthService;
httpAuth?: HttpAuthService;
tokenFactoryAlgorithm?: string;
@@ -40,23 +40,13 @@ export const catalogModuleBitbucketCloudEntityProvider = createBackendModule({
events: eventsServiceRef,
logger: coreServices.logger,
scheduler: coreServices.scheduler,
tokenManager: coreServices.tokenManager,
},
async init({
catalog,
catalogApi,
config,
events,
logger,
scheduler,
tokenManager,
}) {
async init({ catalog, catalogApi, config, events, logger, scheduler }) {
const providers = BitbucketCloudEntityProvider.fromConfig(config, {
catalogApi,
events,
logger,
scheduler,
tokenManager,
});
catalog.addEntityProvider(providers);
@@ -5,7 +5,7 @@
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
import express from 'express';
import { IdentityApi } from '@backstage/plugin-auth-node';
import { HttpAuthService } from '@backstage/backend-plugin-api';
import { LoggerService } from '@backstage/backend-plugin-api';
// @public
@@ -18,7 +18,7 @@ export default exampleTodoListPlugin;
// @public
export interface RouterOptions {
// (undocumented)
identity: IdentityApi;
httpAuth: HttpAuthService;
// (undocumented)
logger: LoggerService;
}
@@ -30,14 +30,14 @@ export const exampleTodoListPlugin = createBackendPlugin({
register(env) {
env.registerInit({
deps: {
identity: coreServices.identity,
httpAuth: coreServices.httpAuth,
logger: coreServices.logger,
httpRouter: coreServices.httpRouter,
},
async init({ identity, logger, httpRouter }) {
async init({ httpAuth, logger, httpRouter }) {
httpRouter.use(
await createRouter({
identity,
httpAuth,
logger,
}),
);
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
import express from 'express';
import request from 'supertest';
@@ -27,7 +26,7 @@ describe('createRouter', () => {
beforeAll(async () => {
const router = await createRouter({
logger: mockServices.logger.mock(),
identity: {} as DefaultIdentityClient,
httpAuth: mockServices.httpAuth.mock(),
});
app = express().use(router);
});
@@ -19,8 +19,7 @@ import express from 'express';
import Router from 'express-promise-router';
import { add, getAll, update } from './todos';
import { InputError } from '@backstage/errors';
import { IdentityApi } from '@backstage/plugin-auth-node';
import { LoggerService } from '@backstage/backend-plugin-api';
import { HttpAuthService, LoggerService } from '@backstage/backend-plugin-api';
/**
* Dependencies of the todo-list router
@@ -29,7 +28,7 @@ import { LoggerService } from '@backstage/backend-plugin-api';
*/
export interface RouterOptions {
logger: LoggerService;
identity: IdentityApi;
httpAuth: HttpAuthService;
}
/**
@@ -44,7 +43,7 @@ export interface RouterOptions {
export async function createRouter(
options: RouterOptions,
): Promise<express.Router> {
const { logger, identity } = options;
const { logger, httpAuth } = options;
const router = Router();
router.use(express.json());
@@ -59,16 +58,16 @@ export async function createRouter(
});
router.post('/todos', async (req, res) => {
let author: string | undefined = undefined;
const user = await identity.getIdentity({ request: req });
author = user?.identity.userEntityRef;
const credentials = await httpAuth.credentials(req, { allow: ['user'] });
if (!isTodoCreateRequest(req.body)) {
throw new InputError('Invalid payload');
}
const todo = add({ title: req.body.title, author });
const todo = add({
title: req.body.title,
author: credentials.principal.userEntityRef,
});
res.json(todo);
});
+2 -2
View File
@@ -29,7 +29,7 @@ import { PermissionsServiceRequestOptions } from '@backstage/backend-plugin-api'
import { PolicyDecision } from '@backstage/plugin-permission-common';
import { QueryPermissionRequest } from '@backstage/plugin-permission-common';
import { ResourcePermission } from '@backstage/plugin-permission-common';
import { TokenManagerService } from '@backstage/backend-plugin-api';
import { TokenManager } from '@backstage/backend-common';
import { z } from 'zod';
// @public
@@ -290,7 +290,7 @@ export class ServerPermissionClient implements PermissionsService {
config: Config,
options: {
discovery: DiscoveryService;
tokenManager: TokenManagerService;
tokenManager?: TokenManager;
auth?: AuthService;
},
): ServerPermissionClient;
@@ -82,7 +82,6 @@ describe('ServerPermissionClient', () => {
it('should bypass the permission backend if permissions are disabled', async () => {
const client = ServerPermissionClient.fromConfig(new ConfigReader({}), {
discovery,
tokenManager: mockServices.tokenManager.mock(),
auth: mockServices.auth(),
});
@@ -101,7 +100,6 @@ describe('ServerPermissionClient', () => {
it('should bypass the permission backend if permissions are enabled and request has valid server credentials', async () => {
const client = ServerPermissionClient.fromConfig(config, {
discovery,
tokenManager: mockServices.tokenManager.mock(),
auth: mockServices.auth(),
});
@@ -115,7 +113,6 @@ describe('ServerPermissionClient', () => {
it('should call the permission backend if permissions are enabled and request does not have valid server credentials', async () => {
const client = ServerPermissionClient.fromConfig(config, {
discovery,
tokenManager: mockServices.tokenManager.mock(),
auth: mockServices.auth(),
});
@@ -156,7 +153,6 @@ describe('ServerPermissionClient', () => {
it('should bypass the permission backend if permissions are disabled', async () => {
const client = ServerPermissionClient.fromConfig(new ConfigReader({}), {
discovery,
tokenManager: mockServices.tokenManager.mock(),
auth: mockServices.auth(),
});
@@ -173,7 +169,6 @@ describe('ServerPermissionClient', () => {
it('should bypass the permission backend if permissions are enabled and request has valid server credentials', async () => {
const client = ServerPermissionClient.fromConfig(config, {
discovery,
tokenManager: mockServices.tokenManager.mock(),
auth: mockServices.auth(),
});
@@ -190,7 +185,6 @@ describe('ServerPermissionClient', () => {
it('should call the permission backend if permissions are enabled and request does not have valid server credentials', async () => {
const client = ServerPermissionClient.fromConfig(config, {
discovery,
tokenManager: mockServices.tokenManager.mock(),
auth: mockServices.auth(),
});
@@ -223,7 +217,6 @@ describe('ServerPermissionClient', () => {
}),
{
discovery,
tokenManager: mockServices.tokenManager(),
auth: mockServices.auth(),
},
);
@@ -14,7 +14,10 @@
* limitations under the License.
*/
import { createLegacyAuthAdapters } from '@backstage/backend-common';
import {
TokenManager,
createLegacyAuthAdapters,
} from '@backstage/backend-common';
import {
AuthService,
BackstageCredentials,
@@ -22,7 +25,6 @@ import {
DiscoveryService,
PermissionsService,
PermissionsServiceRequestOptions,
TokenManagerService,
} from '@backstage/backend-plugin-api';
import { Config } from '@backstage/config';
import {
@@ -51,7 +53,8 @@ export class ServerPermissionClient implements PermissionsService {
config: Config,
options: {
discovery: DiscoveryService;
tokenManager: TokenManagerService;
/** @deprecated This option will be removed in the future, provide a the auth option instead */
tokenManager?: TokenManager;
auth?: AuthService;
},
) {
@@ -62,6 +65,7 @@ export class ServerPermissionClient implements PermissionsService {
if (
permissionEnabled &&
tokenManager &&
(tokenManager as any).isInsecureServerTokenManager
) {
throw new Error(
@@ -80,7 +80,6 @@ export default createBackendModule({
auth: coreServices.auth,
config: coreServices.rootConfig,
discovery: coreServices.discovery,
tokenManager: coreServices.tokenManager,
scheduler: coreServices.scheduler,
indexRegistry: searchIndexRegistryExtensionPoint,
catalog: catalogServiceRef,
@@ -89,7 +88,6 @@ export default createBackendModule({
auth,
config,
discovery,
tokenManager,
scheduler,
indexRegistry,
catalog,
@@ -102,7 +100,6 @@ export default createBackendModule({
auth,
entityTransformer,
discovery,
tokenManager,
catalogClient: catalog,
}),
});
@@ -43,7 +43,6 @@ export default createBackendModule({
logger: coreServices.logger,
discovery: coreServices.discovery,
scheduler: coreServices.scheduler,
tokenManager: coreServices.tokenManager,
auth: coreServices.auth,
indexRegistry: searchIndexRegistryExtensionPoint,
},
@@ -52,7 +51,6 @@ export default createBackendModule({
logger,
discovery,
scheduler,
tokenManager,
auth,
indexRegistry,
}) {
@@ -74,7 +72,6 @@ export default createBackendModule({
discovery,
logger,
auth,
tokenManager,
}),
});
},
@@ -78,7 +78,6 @@ export default createBackendModule({
auth: coreServices.auth,
httpAuth: coreServices.httpAuth,
discovery: coreServices.discovery,
tokenManager: coreServices.tokenManager,
scheduler: coreServices.scheduler,
catalog: catalogServiceRef,
indexRegistry: searchIndexRegistryExtensionPoint,
@@ -89,7 +88,6 @@ export default createBackendModule({
auth,
httpAuth,
discovery,
tokenManager,
scheduler,
catalog,
indexRegistry,
@@ -110,7 +108,6 @@ export default createBackendModule({
schedule: scheduler.createScheduledTaskRunner(schedule),
factory: DefaultTechDocsCollatorFactory.fromConfig(config, {
discovery,
tokenManager,
auth,
httpAuth,
logger,
+1 -1
View File
@@ -28,7 +28,7 @@ export interface RouterOptions {
// (undocumented)
events: EventsService;
// (undocumented)
identity: IdentityApi;
identity?: IdentityApi;
// (undocumented)
lifecycle?: LifecycleService;
// (undocumented)
-3
View File
@@ -34,7 +34,6 @@ export const signalsPlugin = createBackendPlugin({
logger: coreServices.logger,
config: coreServices.rootConfig,
lifecycle: coreServices.rootLifecycle,
identity: coreServices.identity,
discovery: coreServices.discovery,
userInfo: coreServices.userInfo,
auth: coreServices.auth,
@@ -45,7 +44,6 @@ export const signalsPlugin = createBackendPlugin({
logger,
config,
lifecycle,
identity,
discovery,
userInfo,
auth,
@@ -55,7 +53,6 @@ export const signalsPlugin = createBackendPlugin({
await createRouter({
logger,
config,
identity,
lifecycle,
discovery,
userInfo,
@@ -40,7 +40,7 @@ import { Config } from '@backstage/config';
export interface RouterOptions {
logger: LoggerService;
events: EventsService;
identity: IdentityApi;
identity?: IdentityApi;
discovery: PluginEndpointDiscovery;
config: Config;
lifecycle?: LifecycleService;
@@ -15,9 +15,7 @@
*/
import { createBackend } from '@backstage/backend-defaults';
import { mockServices } from '@backstage/backend-test-utils';
const backend = createBackend();
backend.add(mockServices.identity.factory());
backend.add(import('../src/alpha'));
backend.start();