fix: allow for webhookSecret to not be configured for GitHub and GitLab events backend
Signed-off-by: djamaile <rdjamaile@gmail.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-events-backend-module-github': patch
|
||||
'@backstage/plugin-events-backend-module-gitlab': patch
|
||||
---
|
||||
|
||||
Don't hard fail for not configuring `webhookSecret` for the GitHub and GitLab events backend. Instead, we don't add the ingress.
|
||||
@@ -27,6 +27,8 @@ export interface Config {
|
||||
* See https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks
|
||||
* for more details.
|
||||
*
|
||||
* Webhook listener will only be enabled if this is set.
|
||||
*
|
||||
* @visibility secret
|
||||
*/
|
||||
webhookSecret?: string;
|
||||
|
||||
@@ -13,7 +13,7 @@ import { SubTopicEventRouter } from '@backstage/plugin-events-node';
|
||||
// @public
|
||||
export function createGithubSignatureValidator(
|
||||
config: Config,
|
||||
): RequestValidator;
|
||||
): RequestValidator | undefined;
|
||||
|
||||
// @public (undocumented)
|
||||
const _default: BackendFeature;
|
||||
|
||||
+6
-6
@@ -65,9 +65,9 @@ describe('createGithubSignatureValidator', () => {
|
||||
} as RequestDetails;
|
||||
};
|
||||
|
||||
it('no secret configured, throw error', async () => {
|
||||
expect(() => createGithubSignatureValidator(configWithoutSecret)).toThrow(
|
||||
"Missing required config value at 'events.modules.github.webhookSecret'",
|
||||
it('should return undefined if no secret is configured', async () => {
|
||||
expect(createGithubSignatureValidator(configWithoutSecret)).toEqual(
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -76,7 +76,7 @@ describe('createGithubSignatureValidator', () => {
|
||||
const context = new TestContext();
|
||||
|
||||
const validator = createGithubSignatureValidator(configWithSecret);
|
||||
await validator(request, context);
|
||||
await validator!(request, context);
|
||||
|
||||
expect(context.details).not.toBeUndefined();
|
||||
expect(context.details?.status).toBe(403);
|
||||
@@ -88,7 +88,7 @@ describe('createGithubSignatureValidator', () => {
|
||||
const context = new TestContext();
|
||||
|
||||
const validator = createGithubSignatureValidator(configWithSecret);
|
||||
await validator(request, context);
|
||||
await validator!(request, context);
|
||||
|
||||
expect(context.details).not.toBeUndefined();
|
||||
expect(context.details?.status).toBe(403);
|
||||
@@ -100,7 +100,7 @@ describe('createGithubSignatureValidator', () => {
|
||||
const context = new TestContext();
|
||||
|
||||
const validator = createGithubSignatureValidator(configWithSecret);
|
||||
await validator(request, context);
|
||||
await validator!(request, context);
|
||||
|
||||
expect(context.details).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -35,8 +35,13 @@ import { verify } from '@octokit/webhooks-methods';
|
||||
*/
|
||||
export function createGithubSignatureValidator(
|
||||
config: Config,
|
||||
): RequestValidator {
|
||||
const secret = config.getString('events.modules.github.webhookSecret');
|
||||
): RequestValidator | undefined {
|
||||
const secret = config.getOptionalString(
|
||||
'events.modules.github.webhookSecret',
|
||||
);
|
||||
if (!secret) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return async (
|
||||
request: RequestDetails,
|
||||
|
||||
@@ -42,6 +42,27 @@ describe('eventsModuleGithubWebhook', () => {
|
||||
} as RequestDetails;
|
||||
};
|
||||
|
||||
it('should not add ingress if validator is undefined', async () => {
|
||||
let addedIngress: HttpPostIngressOptions | undefined;
|
||||
const extensionPoint = {
|
||||
addHttpPostIngress: (ingress: any) => {
|
||||
addedIngress = ingress;
|
||||
},
|
||||
};
|
||||
|
||||
await startTestBackend({
|
||||
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
|
||||
features: [
|
||||
eventsModuleGithubWebhook,
|
||||
mockServices.rootConfig.factory({
|
||||
data: {},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
expect(addedIngress).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should be correctly wired and set up', async () => {
|
||||
let addedIngress: HttpPostIngressOptions | undefined;
|
||||
const extensionPoint = {
|
||||
|
||||
@@ -26,7 +26,7 @@ import { createGithubSignatureValidator } from '../http/createGithubSignatureVal
|
||||
* registering an HTTP POST ingress with request validator
|
||||
* which verifies the webhook signature based on a secret.
|
||||
*
|
||||
* @alpha
|
||||
* @public
|
||||
*/
|
||||
export default createBackendModule({
|
||||
pluginId: 'events',
|
||||
@@ -38,10 +38,13 @@ export default createBackendModule({
|
||||
events: eventsExtensionPoint,
|
||||
},
|
||||
async init({ config, events }) {
|
||||
events.addHttpPostIngress({
|
||||
topic: 'github',
|
||||
validator: createGithubSignatureValidator(config),
|
||||
});
|
||||
const validator = createGithubSignatureValidator(config);
|
||||
if (validator) {
|
||||
events.addHttpPostIngress({
|
||||
topic: 'github',
|
||||
validator,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -27,6 +27,8 @@ export interface Config {
|
||||
* See https://docs.gitlab.com/ee/user/project/integrations/webhooks.html#validate-payloads-by-using-a-secret-token
|
||||
* for more details.
|
||||
*
|
||||
* Webhook listener will only be enabled if this is set.
|
||||
*
|
||||
* @visibility secret
|
||||
*/
|
||||
webhookSecret?: string;
|
||||
|
||||
@@ -11,7 +11,9 @@ import { RequestValidator } from '@backstage/plugin-events-node';
|
||||
import { SubTopicEventRouter } from '@backstage/plugin-events-node';
|
||||
|
||||
// @public
|
||||
export function createGitlabTokenValidator(config: Config): RequestValidator;
|
||||
export function createGitlabTokenValidator(
|
||||
config: Config,
|
||||
): RequestValidator | undefined;
|
||||
|
||||
// @public (undocumented)
|
||||
const _default: BackendFeature;
|
||||
|
||||
@@ -55,10 +55,8 @@ describe('createGitlabTokenValidator', () => {
|
||||
} as Partial<RequestDetails> as unknown as RequestDetails;
|
||||
};
|
||||
|
||||
it('no secret configured, throw error', async () => {
|
||||
expect(() => createGitlabTokenValidator(configWithoutSecret)).toThrow(
|
||||
"Missing required config value at 'events.modules.gitlab.webhookSecret'",
|
||||
);
|
||||
it('should return undefined if no secret is configured', async () => {
|
||||
expect(createGitlabTokenValidator(configWithoutSecret)).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('secret configured, reject request without token', async () => {
|
||||
@@ -66,7 +64,7 @@ describe('createGitlabTokenValidator', () => {
|
||||
const context = new TestContext();
|
||||
|
||||
const validator = createGitlabTokenValidator(configWithSecret);
|
||||
await validator(request, context);
|
||||
await validator!(request, context);
|
||||
|
||||
expect(context.details).not.toBeUndefined();
|
||||
expect(context.details?.status).toBe(403);
|
||||
@@ -78,7 +76,7 @@ describe('createGitlabTokenValidator', () => {
|
||||
const context = new TestContext();
|
||||
|
||||
const validator = createGitlabTokenValidator(configWithSecret);
|
||||
await validator(request, context);
|
||||
await validator!(request, context);
|
||||
|
||||
expect(context.details).not.toBeUndefined();
|
||||
expect(context.details?.status).toBe(403);
|
||||
@@ -90,7 +88,7 @@ describe('createGitlabTokenValidator', () => {
|
||||
const context = new TestContext();
|
||||
|
||||
const validator = createGitlabTokenValidator(configWithSecret);
|
||||
await validator(request, context);
|
||||
await validator!(request, context);
|
||||
|
||||
expect(context.details).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -30,8 +30,16 @@ import {
|
||||
* @param config - root config
|
||||
* @public
|
||||
*/
|
||||
export function createGitlabTokenValidator(config: Config): RequestValidator {
|
||||
const secret = config.getString('events.modules.gitlab.webhookSecret');
|
||||
export function createGitlabTokenValidator(
|
||||
config: Config,
|
||||
): RequestValidator | undefined {
|
||||
const secret = config.getOptionalString(
|
||||
'events.modules.gitlab.webhookSecret',
|
||||
);
|
||||
|
||||
if (!secret) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return async (
|
||||
request: RequestDetails,
|
||||
|
||||
@@ -31,6 +31,27 @@ describe('gitlabWebhookEventsModule', () => {
|
||||
} as Partial<RequestDetails> as unknown as RequestDetails;
|
||||
};
|
||||
|
||||
it('should not add ingress if validator is undefined', async () => {
|
||||
let addedIngress: HttpPostIngressOptions | undefined;
|
||||
const extensionPoint = {
|
||||
addHttpPostIngress: (ingress: any) => {
|
||||
addedIngress = ingress;
|
||||
},
|
||||
};
|
||||
|
||||
await startTestBackend({
|
||||
extensionPoints: [[eventsExtensionPoint, extensionPoint]],
|
||||
features: [
|
||||
eventsModuleGitlabWebhook,
|
||||
mockServices.rootConfig.factory({
|
||||
data: {},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
expect(addedIngress).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should be correctly wired and set up', async () => {
|
||||
let addedIngress: HttpPostIngressOptions | undefined;
|
||||
const extensionPoint = {
|
||||
|
||||
@@ -40,10 +40,13 @@ export default createBackendModule({
|
||||
events: eventsExtensionPoint,
|
||||
},
|
||||
async init({ config, events }) {
|
||||
events.addHttpPostIngress({
|
||||
topic: 'gitlab',
|
||||
validator: createGitlabTokenValidator(config),
|
||||
});
|
||||
const validator = createGitlabTokenValidator(config);
|
||||
if (validator) {
|
||||
events.addHttpPostIngress({
|
||||
topic: 'gitlab',
|
||||
validator: createGitlabTokenValidator(config),
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user