Skip to content

Commit

Permalink
bi-directional sync tests passing
Browse files Browse the repository at this point in the history
Created a new package for matching V1 webhook requests. Also change implementation to verify via a hmac signature instead of a header/body property value.
  • Loading branch information
andrew-codes committed Mar 3, 2019
1 parent 452ba62 commit 6ee73fb
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 107 deletions.
12 changes: 3 additions & 9 deletions packages/webhooked-github-request-matchers/src/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
const { createHmac } = require('crypto');
const isRequestFromGithub = require('./isRequestFromGithub');

const isRequestFromGithub = (req, hmacKey) =>
req.headers['x-hub-signature'] ===
`sha1=${createHmac('sha1', hmacKey)
.update(JSON.stringify(req.body))
.digest('hex')}`;

const matchesActions = (req, actions = []) => {
if (!isRequestFromGithub(req)) {
const matchesActions = (req, actions = [], key = '') => {
if (!isRequestFromGithub(req, key)) {
return false;
}
return Boolean(actions.find(action => req.body.action === action));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const { createHmac } = require('crypto');

module.exports = (req, hmacKey) =>
req.headers['x-hub-signature'] ===
`sha1=${createHmac('sha1', hmacKey)
.update(JSON.stringify(req.body))
.digest('hex')}`;
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
jest.mock('../src/isRequestFromGithub');
const { when } = require('jest-when');
const { matchesActions } = require('../src');
const isRequestFromGithub = require('../src/isRequestFromGithub');
const key = 'key';

test('returns false if the request is not a github api event', () => {
const nonGHRequest = {
headers: {},
};
when(isRequestFromGithub)
.calledWith(nonGHRequest, key)
.mockReturnValue(false);

expect(matchesActions(nonGHRequest)).toBeFalsy();
});

test('returns false if not actions are provided', () => {
expect(matchesActions(createGHRequest())).toBeFalsy();
test('returns false if no actions are provided', () => {
when(isRequestFromGithub)
.calledWith(createGHRequest(), key)
.mockReturnValue(true);
expect(matchesActions(createGHRequest(), key)).toBeFalsy();
});
test('returns false if the action is not matched', () => {
expect(matchesActions(createGHRequest(), ['created'])).toBeFalsy();
when(isRequestFromGithub)
.calledWith(createGHRequest(), key)
.mockReturnValue(true);
expect(matchesActions(createGHRequest(), ['created'], key)).toBeFalsy();
});

test('returns true if the request matches any one of the provided actions', () => {
when(isRequestFromGithub)
.calledWith(createGHRequest(), key)
.mockReturnValue(true);
expect(
matchesActions(createGHRequest(), ['created', 'labeled']),
matchesActions(createGHRequest(), ['created', 'labeled'], key),
).toBeTruthy();
});

Expand Down
1 change: 1 addition & 0 deletions packages/webhooked-plugin-issue-sync-gh-v1/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"dependencies": {
"@andrew-codes/v1sdk-fetch-connector": "^0.0.1",
"@andrew-codes/webhooked-github-request-matchers": "^0.0.1",
"@andrew-codes/webhooked-v1-request-matchers": "^0.0.1",
"@andrew-codes/webhooked-utils": "^0.0.1",
"fetch-node": "^0.0.1",
"github-api": "^3.0.0",
Expand Down
38 changes: 31 additions & 7 deletions packages/webhooked-plugin-issue-sync-gh-v1/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const fetchConnector = require('@andrew-codes/v1sdk-fetch-connector');
const GitHub = require('github-api');
const v1sdk = require('v1sdk').default;
const { isEmpty } = require('lodash');
const {
isRequestFromV1,
} = require('@andrew-codes/webhooked-v1-request-matchers');
const {
matchesActions,
} = require('@andrew-codes/webhooked-github-request-matchers');
Expand All @@ -18,15 +21,16 @@ module.exports = async (req, options) => {
const { scope, team } = options;
const { v1, gh } = options.connection;
const connectedSdk = fetchConnector(fetch)(v1sdk);
const v1api = connectedSdk(
const v1Api = connectedSdk(
v1.host,
v1.instance,
v1.port,
v1.isHttps,
).withAccessToken(v1.token);
const ghApi = new GitHub({ token: gh.token });
const issues = ghApi.getIssues();
if (matchesActions(req, ['labeled'])) {

if (matchesActions(req, ['labeled'], options.connection.gh.hmacKey)) {
const matchedAssetLabelMapping = Object.entries(options.assetToLabel).find(
mapping => {
const [_, value] = mapping;
Expand All @@ -37,15 +41,35 @@ module.exports = async (req, options) => {
return;
}
const assetType = matchedAssetLabelMapping[0];
const { _oid } = await v1api.create(assetType, {
const { _oid } = await v1Api.create(assetType, {
links: { name: 'Github Issue', url: req.body.issue.url },
name: req.body.issue.title,
scope,
taggedWith: [`github-${req.body.issue.number}`, 'github'],
team,
});
issues.editIssue(req.body.issue.number, { labels: [`v1-${_oid}`, 'v1'] });
return;
return await issues.editIssue(req.body.issue.number, {
labels: [`v1-${_oid}`, 'v1'],
});
} else if (isRequestFromV1(req, options.connection.v1.hmacKey)) {
return await req.body.events
.filter(event => event.eventType === 'AssetChanged')
.filter(
event =>
!isEmpty(event.snapshot[0].taggedWith) &&
!event.snapshot[0].taggedWith.find(tag => /^github-\d+$/.test(tag)),
)
.map(async event => {
const { number, url } = await issues.createIssue({
title: event.snapshot[0].Name,
description: event.snapshot[0].Description,
labels: [`v1-${event.snapshot[0]._oid}`, 'v1'],
});
return await v1Api.update(event.snapshot[0]._oid, {
taggedWith: ['github', `github-${number}`],
links: [{ name: 'Github Issue', url }],
});
});
}
};

Expand All @@ -72,14 +96,14 @@ function validateOptions(options) {
.concat(
validatePropsAreStrings(
options.connection.gh,
['token'],
['token', 'hmacKey'],
p => `Invalid gh connection ${p} option`,
),
)
.concat(
validatePropsAreStrings(
options.connection.v1,
['host', 'instance', 'token'],
['host', 'instance', 'token', 'hmacKey'],
p => `Invalid v1 connection ${p} option`,
),
)
Expand Down
Loading

0 comments on commit 6ee73fb

Please sign in to comment.