fix: pass full config to StaticTokenIssuer, documentation and test tweaks
Signed-off-by: rtriesscheijn <rtriesscheijn@bol.com>
This commit is contained in:
@@ -88,7 +88,6 @@
|
||||
"@backstage/backend-defaults": "workspace:^",
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^",
|
||||
"@types/body-parser": "^1.19.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express-session": "^1.17.2",
|
||||
|
||||
@@ -76,12 +76,7 @@ export class KeyStores {
|
||||
}
|
||||
|
||||
if (provider === 'static') {
|
||||
const settings = ks?.getConfig(provider);
|
||||
if (settings === undefined) {
|
||||
throw new Error(`Missing configuration for static key store provider`);
|
||||
}
|
||||
|
||||
await StaticKeyStore.fromConfig(settings);
|
||||
await StaticKeyStore.fromConfig(config);
|
||||
}
|
||||
|
||||
throw new Error(`Unknown KeyStore provider: ${provider}`);
|
||||
|
||||
@@ -13,13 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { promises as fs } from 'fs';
|
||||
import { StaticKeyStore } from './StaticKeyStore';
|
||||
import { AnyJWK } from './types';
|
||||
import { ConfigReader } from '@backstage/core-app-api';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { createMockDirectory } from '@backstage/backend-test-utils';
|
||||
|
||||
const publicKeyPath = '/mnt/public.pem';
|
||||
const privateKeyPath = '/mnt/private.pem';
|
||||
const privateKey = `
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgR8Ja2ppMEgOm1KeY
|
||||
@@ -35,37 +33,39 @@ ZoUEY72HTvjIP9xSbLOhWhMREk84T0q91/m3v3sWq5EzHIWw1zRHQisKZw==
|
||||
-----END PUBLIC KEY-----
|
||||
`.trim();
|
||||
|
||||
const config = new ConfigReader({
|
||||
keys: [
|
||||
{
|
||||
publicKeyFile: publicKeyPath,
|
||||
privateKeyFile: privateKeyPath,
|
||||
keyId: '1',
|
||||
algorithm: 'ES256',
|
||||
},
|
||||
{
|
||||
publicKeyFile: publicKeyPath,
|
||||
privateKeyFile: privateKeyPath,
|
||||
keyId: '2',
|
||||
algorithm: 'ES256',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
jest.mock('fs/promises');
|
||||
|
||||
describe('StaticKeyStore', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
fs.readFile = jest.fn().mockImplementation(async (path: string, _: any) => {
|
||||
if (path === publicKeyPath) {
|
||||
return Promise.resolve(publicKey);
|
||||
}
|
||||
if (path === privateKeyPath) {
|
||||
return Promise.resolve(privateKey);
|
||||
}
|
||||
let config: ConfigReader;
|
||||
const sourceDir = createMockDirectory();
|
||||
|
||||
throw new Error('Unexpected path');
|
||||
beforeAll(() => {
|
||||
sourceDir.setContent({
|
||||
'public.pem': publicKey,
|
||||
'private.pem': privateKey,
|
||||
});
|
||||
|
||||
const publicKeyPath = sourceDir.resolve('public.pem');
|
||||
const privateKeyPath = sourceDir.resolve('private.pem');
|
||||
config = new ConfigReader({
|
||||
auth: {
|
||||
keyStore: {
|
||||
static: {
|
||||
keys: [
|
||||
{
|
||||
publicKeyFile: publicKeyPath,
|
||||
privateKeyFile: privateKeyPath,
|
||||
keyId: '1',
|
||||
algorithm: 'ES256',
|
||||
},
|
||||
{
|
||||
publicKeyFile: publicKeyPath,
|
||||
privateKeyFile: privateKeyPath,
|
||||
keyId: '2',
|
||||
algorithm: 'ES256',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -74,16 +74,18 @@ export class StaticKeyStore implements KeyStore {
|
||||
}
|
||||
|
||||
public static async fromConfig(config: Config): Promise<StaticKeyStore> {
|
||||
const keyConfigs = config.getConfigArray('keys').map(c => {
|
||||
const staticKeyConfig: StaticKeyConfig = {
|
||||
publicKeyFile: c.getString('publicKeyFile'),
|
||||
privateKeyFile: c.getString('privateKeyFile'),
|
||||
keyId: c.getString('keyId'),
|
||||
algorithm: c.getOptionalString('algorithm') ?? DEFAULT_ALGORITHM,
|
||||
};
|
||||
const keyConfigs = config
|
||||
.getConfigArray('auth.keyStore.static.keys')
|
||||
.map(c => {
|
||||
const staticKeyConfig: StaticKeyConfig = {
|
||||
publicKeyFile: c.getString('publicKeyFile'),
|
||||
privateKeyFile: c.getString('privateKeyFile'),
|
||||
keyId: c.getString('keyId'),
|
||||
algorithm: c.getOptionalString('algorithm') ?? DEFAULT_ALGORITHM,
|
||||
};
|
||||
|
||||
return staticKeyConfig;
|
||||
});
|
||||
return staticKeyConfig;
|
||||
});
|
||||
|
||||
const keyPairs = await Promise.all(
|
||||
keyConfigs.map(async k => await this.loadKeyPair(k)),
|
||||
|
||||
@@ -26,7 +26,6 @@ const entityRef = stringifyEntityRef({
|
||||
name: 'name',
|
||||
});
|
||||
|
||||
jest.mock('fs/promises');
|
||||
describe('StaticTokenIssuer', () => {
|
||||
it('should issue valid tokens signed by the first listed key', async () => {
|
||||
const staticKeyStore = {
|
||||
|
||||
@@ -35,7 +35,6 @@ export type Options = {
|
||||
issuer: string;
|
||||
/** Expiration time of the JWT in seconds */
|
||||
sessionExpirationSeconds: number;
|
||||
/** id to uniquely identify this key within the JWK set, defaults to '1' */
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user