backend-common: add allowDisabledTokenManager option for ServerTokenManager

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-04-20 16:14:01 +02:00
parent 93f79c4c54
commit ba0b8b45da
4 changed files with 55 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Added option to `ServerTokenManager.fromConfig` that allows it to be instantiated in production without any configured keys.
+2 -1
View File
@@ -772,7 +772,7 @@ export class ServerTokenManager implements TokenManager {
static fromConfig(
config: Config,
options: ServerTokenManagerOptions,
): ServerTokenManager;
): TokenManager;
// (undocumented)
getToken(): Promise<{
token: string;
@@ -782,6 +782,7 @@ export class ServerTokenManager implements TokenManager {
// @public
export interface ServerTokenManagerOptions {
allowDisabledTokenManager?: boolean;
logger: LoggerService;
}
@@ -301,6 +301,20 @@ describe('ServerTokenManager', () => {
),
).toThrow();
});
it('should throw errors when disabled', async () => {
const manager = ServerTokenManager.fromConfig(new ConfigReader({}), {
logger,
allowDisabledTokenManager: true,
});
await expect(manager.getToken()).rejects.toThrow(
'Unable to generate legacy token',
);
await expect(manager.authenticate('nah')).rejects.toThrow(
'Unable to authenticate legacy token',
);
});
});
describe('NODE_ENV === development', () => {
@@ -40,6 +40,23 @@ class NoopTokenManager implements TokenManager {
async authenticate() {}
}
/**
* A token manager that throws an error when trying to generate or authenticate tokens.
*/
class DisabledTokenManager implements TokenManager {
async getToken(): Promise<{ token: string }> {
throw new Error(
"Unable to generate legacy token, no legacy keys are configured in 'backend.auth.keys' or 'backend.auth.externalAccess'",
);
}
async authenticate() {
throw new AuthenticationError(
"Unable to authenticate legacy token, no legacy keys are configured in 'backend.auth.keys' or 'backend.auth.externalAccess'",
);
}
}
/**
* Options for {@link ServerTokenManager}.
*
@@ -50,6 +67,11 @@ export interface ServerTokenManagerOptions {
* The logger to use.
*/
logger: LoggerService;
/**
* Whether to disable the token manager if no keys are configured.
*/
allowDisabledTokenManager?: boolean;
}
/**
@@ -73,7 +95,10 @@ export class ServerTokenManager implements TokenManager {
return new NoopTokenManager();
}
static fromConfig(config: Config, options: ServerTokenManagerOptions) {
static fromConfig(
config: Config,
options: ServerTokenManagerOptions,
): TokenManager {
const oldSecrets = config
.getOptionalConfigArray('backend.auth.keys')
?.map(c => c.getString('secret'));
@@ -87,6 +112,14 @@ export class ServerTokenManager implements TokenManager {
return new ServerTokenManager(secrets, options);
}
// When using the new backend system with new auth services we instead rely
// on the new plugin auth and external access configurations. If no legacy
// keys are configured we disable the token manager completely, rather than
// requiring users to configure legacy keys.
if (options.allowDisabledTokenManager) {
return new DisabledTokenManager();
}
if (process.env.NODE_ENV !== 'development') {
throw new Error(
'You must configure at least one key in backend.auth.keys for production.',