leverage webhook secrets from github integrations too
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-events-backend-module-github': patch
|
||||
---
|
||||
|
||||
Support webhook validation based on `integrations.github.[].apps.[].webhookSecret` too
|
||||
@@ -45,6 +45,7 @@
|
||||
"dependencies": {
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/integration": "workspace:^",
|
||||
"@backstage/plugin-events-node": "workspace:^",
|
||||
"@octokit/webhooks-methods": "^3.0.0"
|
||||
},
|
||||
|
||||
@@ -47,6 +47,24 @@ describe('createGithubSignatureValidator', () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
const configWithAppSecret = new ConfigReader({
|
||||
integrations: {
|
||||
github: [
|
||||
{
|
||||
host: 'github.com',
|
||||
apps: [
|
||||
{
|
||||
appId: 1,
|
||||
privateKey: 'a',
|
||||
clientId: 'b',
|
||||
clientSecret: 'c',
|
||||
webhookSecret: secret,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const payloadString = '{"test": "payload", "score": 5.0}';
|
||||
const payload = JSON.parse(payloadString);
|
||||
const payloadBuffer = Buffer.from(payloadString);
|
||||
@@ -104,4 +122,14 @@ describe('createGithubSignatureValidator', () => {
|
||||
|
||||
expect(context.details).toBeUndefined();
|
||||
});
|
||||
|
||||
it('secret configured, accept request with valid signature defined in integrations', async () => {
|
||||
const request = await requestWithSignature(await validSignature);
|
||||
const context = new TestContext();
|
||||
|
||||
const validator = createGithubSignatureValidator(configWithAppSecret);
|
||||
await validator!(request, context);
|
||||
|
||||
expect(context.details).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import {
|
||||
RequestDetails,
|
||||
RequestValidationContext,
|
||||
@@ -36,10 +37,25 @@ import { verify } from '@octokit/webhooks-methods';
|
||||
export function createGithubSignatureValidator(
|
||||
config: Config,
|
||||
): RequestValidator | undefined {
|
||||
const secret = config.getOptionalString(
|
||||
const webhookSecrets = new Set<string>();
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
for (const integration of integrations.github.list()) {
|
||||
for (const app of integration.config.apps ?? []) {
|
||||
if (app.webhookSecret) {
|
||||
webhookSecrets.add(app.webhookSecret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const moduleSecret = config.getOptionalString(
|
||||
'events.modules.github.webhookSecret',
|
||||
);
|
||||
if (!secret) {
|
||||
if (moduleSecret) {
|
||||
webhookSecrets.add(moduleSecret);
|
||||
}
|
||||
|
||||
if (webhookSecrets.size === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -51,18 +67,18 @@ export function createGithubSignatureValidator(
|
||||
| string
|
||||
| undefined;
|
||||
|
||||
if (
|
||||
!signature ||
|
||||
!(await verify(
|
||||
secret,
|
||||
request.raw.body.toString(request.raw.encoding),
|
||||
signature,
|
||||
))
|
||||
) {
|
||||
context.reject({
|
||||
status: 403,
|
||||
payload: { message: 'invalid signature' },
|
||||
});
|
||||
if (signature) {
|
||||
const body = request.raw.body.toString(request.raw.encoding);
|
||||
for (const secret of webhookSecrets) {
|
||||
if (await verify(secret, body, signature)) {
|
||||
return; // OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.reject({
|
||||
status: 403,
|
||||
payload: { message: 'invalid signature' },
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6576,6 +6576,7 @@ __metadata:
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/config": "workspace:^"
|
||||
"@backstage/integration": "workspace:^"
|
||||
"@backstage/plugin-events-backend-test-utils": "workspace:^"
|
||||
"@backstage/plugin-events-node": "workspace:^"
|
||||
"@octokit/webhooks-methods": "npm:^3.0.0"
|
||||
|
||||
Reference in New Issue
Block a user