backend-common: update createLegacyAuthAdapters to work with a single service

Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Carl-Erik Bergström <cbergstrom@spotify.com>
Co-authored-by: blam <ben@blam.sh>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-02-14 00:13:36 +01:00
parent 3444a2c7c9
commit 54fa4997ee
3 changed files with 140 additions and 29 deletions
+29 -10
View File
@@ -235,16 +235,35 @@ export function createDatabaseClient(
): knexFactory.Knex<any, any[]>;
// @public (undocumented)
export function createLegacyAuthAdapters(options: {
auth?: AuthService;
httpAuth?: HttpAuthService;
identity?: IdentityService;
tokenManager?: TokenManager;
discovery: PluginEndpointDiscovery;
}): {
auth: AuthService;
httpAuth: HttpAuthService;
};
export function createLegacyAuthAdapters<
TOptions extends {
auth?: AuthService;
httpAuth?: HttpAuthService;
identity?: IdentityService;
tokenManager?: TokenManager;
discovery: PluginEndpointDiscovery;
},
TAdapters = TOptions extends {
auth?: AuthService;
}
? TOptions extends {
httpAuth?: HttpAuthService;
}
? {
auth: AuthService;
httpAuth: HttpAuthService;
}
: {
auth: AuthService;
}
: TOptions extends {
httpAuth?: HttpAuthService;
}
? {
httpAuth: HttpAuthService;
}
: 'error: at least one of auth and/or httpAuth must be provided',
>(options: TOptions): TAdapters;
// @public
export function createRootLogger(
@@ -0,0 +1,73 @@
/*
* Copyright 2024 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 { mockServices } from '@backstage/backend-test-utils';
import { createLegacyAuthAdapters } from './createLegacyAuthAdapters';
describe('createLegacyAuthAdapters', () => {
it('should pass through auth if only auth is provided', () => {
const auth = {};
const ret = createLegacyAuthAdapters({
auth: auth as any,
tokenManager: mockServices.tokenManager(),
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret.auth).toBe(auth);
});
it('should pass through httpAuth if only httpAuth is provided', () => {
const httpAuth = {};
const ret = createLegacyAuthAdapters({
httpAuth: httpAuth as any,
tokenManager: mockServices.tokenManager(),
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret.httpAuth).toBe(httpAuth);
});
it('should pass through both auth and httpAuth if both are provided', () => {
const auth = {};
const httpAuth = {};
const ret = createLegacyAuthAdapters({
auth: auth as any,
httpAuth: httpAuth as any,
tokenManager: mockServices.tokenManager(),
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret.auth).toBe(auth);
expect(ret.httpAuth).toBe(httpAuth);
});
it('should adapt both auth and httpAuth if neither are provided', () => {
const ret = createLegacyAuthAdapters({
auth: undefined,
httpAuth: undefined,
tokenManager: mockServices.tokenManager(),
discovery: {} as any,
identity: mockServices.identity(),
});
expect(ret).toEqual({
auth: expect.any(Object),
httpAuth: expect.any(Object),
});
});
});
@@ -210,29 +210,47 @@ class HttpAuthCompat implements HttpAuthService {
async issueUserCookie(_res: Response): Promise<void> {}
}
/** @public */
export function createLegacyAuthAdapters(options: {
auth?: AuthService;
httpAuth?: HttpAuthService;
identity?: IdentityService;
tokenManager?: TokenManager;
discovery: PluginEndpointDiscovery;
}): {
auth: AuthService;
httpAuth: HttpAuthService;
} {
/**
* An adapter that ensures presence of the auth and/or httpAuth services.
* @public
*/
export function createLegacyAuthAdapters<
TOptions extends {
auth?: AuthService;
httpAuth?: HttpAuthService;
identity?: IdentityService;
tokenManager?: TokenManager;
discovery: PluginEndpointDiscovery;
},
TAdapters = TOptions extends {
auth?: AuthService;
}
? TOptions extends { httpAuth?: HttpAuthService }
? { auth: AuthService; httpAuth: HttpAuthService }
: { auth: AuthService }
: TOptions extends { httpAuth?: HttpAuthService }
? { httpAuth: HttpAuthService }
: 'error: at least one of auth and/or httpAuth must be provided',
>(options: TOptions): TAdapters {
const { auth, httpAuth, discovery } = options;
if (auth || httpAuth) {
// TODO: Is this sensible? Could be that a lot of plugins only want one of them and in
// that case overloads might be better, so that it's possible to only provide one of them.
if (!(auth && httpAuth)) {
throw new Error('Both auth and httpAuth must be provided');
}
if (auth && httpAuth) {
return {
auth,
httpAuth,
};
} as TAdapters;
}
if (auth) {
return {
auth,
} as TAdapters;
}
if (httpAuth) {
return {
httpAuth,
} as TAdapters;
}
const identity =
@@ -240,10 +258,11 @@ export function createLegacyAuthAdapters(options: {
const tokenManager = options.tokenManager ?? ServerTokenManager.noop();
const authImpl = new AuthCompat(identity, tokenManager);
const httpAuthImpl = new HttpAuthCompat(authImpl);
return {
auth: authImpl,
httpAuth: httpAuthImpl,
};
} as TAdapters;
}