diff --git a/.dockerignore b/.dockerignore index a41f125..9c39416 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1 @@ db/* -node_modules diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b9eea79 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,40 @@ +sudo: required + +language: node_js + +node_js: +- "7" + +services: + - docker + +env: + - DOCKER_COMPOSE_VERSION=1.11.2 + +addons: + apt: + packages: + - linux-image-extra-$(uname -r) + - linux-image-extra-virtual + - apt-transport-https + - ca-certificates + - curl + - software-properties-common + - docker-ce=17.06.0~ce-0~ubuntu + +before_install: + # update is required to update the repositories to see the new packages for + # Docker. + + # Print out the current docker-compose version. Once this reports 1.6+ then we + # do not need the following steps. + - docker-compose --version + + # Update docker-compose version + - sudo rm /usr/local/bin/docker-compose + - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose + - chmod +x docker-compose + - sudo mv docker-compose /usr/local/bin + + # Run docker-compose + - docker-compose up --build ./test/docker-compose.yml diff --git a/dist/contract/deploy.js b/dist/contract/deploy.js index 75ef83e..5172688 100644 --- a/dist/contract/deploy.js +++ b/dist/contract/deploy.js @@ -32,7 +32,7 @@ function deploy(_ref) { return new _bluebird2.default(function (resolve, reject) { - var msgID = 'deploy_contract_' + new Date().getTime(); + var msgID = 'deploy_contract_' + new Date().getTime() + '_' + tokenDetails['organization']; var payload = { id: msgID, diff --git a/dist/contract/rewardContributor.js b/dist/contract/rewardContributor.js index 897bd22..646e7c4 100644 --- a/dist/contract/rewardContributor.js +++ b/dist/contract/rewardContributor.js @@ -22,26 +22,36 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de /** * [rewardContributor description] - * @param {[type]} eventDetails [description] - * @return [type] [description] + * @param {[type]} contributor [description] + * @param {[type]} event [description] + * @param {[type]} eventType [description] + * @param {[type]} rewardValue [description] + * @param {[type]} reservedValue [description] + * @param {[type]} deliveryID [description] + * @return [type] [description] */ function rewardContributor(_ref) { var _this = this; - var eventDetails = _ref.eventDetails; + var contributor = _ref.contributor, + event = _ref.event, + eventType = _ref.eventType, + rewardValue = _ref.rewardValue, + reservedValue = _ref.reservedValue, + deliveryID = _ref.deliveryID; return new _bluebird2.default(function (resolve, reject) { - var msgID = 'reward_contributor_' + new Date().getTime(); + var msgID = 'reward_' + contributor + '_' + new Date().getTime() + '_' + deliveryID; - _this.calculateRewardBonus({ eventDetails: eventDetails }).then(function (rewardBonus) { - var params = [eventDetails['contributor'], eventDetails['event'], eventDetails['action'], rewardBonus, eventDetails['delivery_id']]; + try { + var params = [contributor, event, eventType, rewardValue, reservedValue, deliveryID]; _this.signer.write((0, _stringify2.default)({ id: msgID, event: 'sign_contract_transaction', data: { recoveryShare: _this.recoveryShare, - organization: eventDetails['organization'], + organization: organization, method: 'rewardContributor', params: params } @@ -59,8 +69,8 @@ function rewardContributor(_ref) { reject(result); } }); - }).catch(function (error) { + } catch (error) { reject(error); - }); + } }); } \ No newline at end of file diff --git a/dist/events/gollumEvent.js b/dist/events/gollumEvent.js new file mode 100644 index 0000000..6394b2b --- /dev/null +++ b/dist/events/gollumEvent.js @@ -0,0 +1,48 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = gollumEvent; + +var _bluebird = require('bluebird'); + +var _bluebird2 = _interopRequireDefault(_bluebird); + +var _gittokenRewardValues = require('gittoken-reward-values'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * [gollumEvent description] + * @param {[type]} payload [description] + * @param {[type]} headers [description] + * @return [type] [description] + */ +function gollumEvent(_ref) { + var _this = this; + + var payload = _ref.payload, + headers = _ref.headers; + + return new _bluebird2.default(function (resolve, reject) { + var pages = payload.pages; + + + _bluebird2.default.resolve(pages).map(function (page, i) { + return _this.rewardContributor({ + contributor: payload['sender']['login'], + event: 'gollum', + eventType: payload[page.action], + rewardValue: _gittokenRewardValues.rewardValues['gollum'][page.action], + reservedValue: _gittokenRewardValues.reservedValues['gollum'][page.action], + deliveryID: headers['x-github-delivery'] + '-' + i, + organization: payload['organization']['login'] + }); + }).then(function (receipts) { + resolve(receipts); + }).catch(function (error) { + reject(error); + }); + }); +} \ No newline at end of file diff --git a/dist/events/index.js b/dist/events/index.js index a50b7da..1275fb3 100644 --- a/dist/events/index.js +++ b/dist/events/index.js @@ -3,12 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.pingEvent = undefined; +exports.gollumEvent = exports.pingEvent = undefined; var _pingEvent = require('./pingEvent'); var _pingEvent2 = _interopRequireDefault(_pingEvent); +var _gollumEvent = require('./gollumEvent'); + +var _gollumEvent2 = _interopRequireDefault(_gollumEvent); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -exports.pingEvent = _pingEvent2.default; \ No newline at end of file +exports.pingEvent = _pingEvent2.default; +exports.gollumEvent = _gollumEvent2.default; \ No newline at end of file diff --git a/dist/events/pingEvent.js b/dist/events/pingEvent.js index 43d87e1..d8c3c01 100644 --- a/dist/events/pingEvent.js +++ b/dist/events/pingEvent.js @@ -3,11 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true }); - -var _stringify = require('babel-runtime/core-js/json/stringify'); - -var _stringify2 = _interopRequireDefault(_stringify); - exports.default = pingEvent; var _bluebird = require('bluebird'); @@ -25,7 +20,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de function pingEvent(_ref) { var _this = this; - var eventDetails = _ref.eventDetails, + var payload = _ref.payload, + headers = _ref.headers, tokenDetails = _ref.tokenDetails; return new _bluebird2.default(function (resolve, reject) { @@ -33,19 +29,28 @@ function pingEvent(_ref) { _this.deploy({ tokenDetails: tokenDetails }).then(function (txReceipt) { receipts.push(txReceipt); - return _this.rewardContributor({ eventDetails: eventDetails }); + return _this.rewardContributor({ + contributor: payload['sender']['login'], + event: 'ping', + eventType: '', + rewardValue: rewardValues['ping'], + reservedValue: reservedValues['ping'], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }); }).then(function (txReceipt) { receipts.push(txReceipt); - var data = { + /* + NOTE: Consider removing Listener Service from Webhook process. + const data = { organization: tokenDetails['organization'], token: receipts[0]['contractAddress'] - }; - - console.log('Sending Data ' + (0, _stringify2.default)(data) + ' to Event Listener'); - - // Setup Event Listener for newly deployed token - _this.watcher.eventListener.write((0, _stringify2.default)({ type: 'WATCH_TOKEN', data: data })); + } + console.log(`Sending Data ${JSON.stringify(data)} to Event Listener`) + // Setup Event Listener for newly deployed token + this.watcher.eventListener.write(JSON.stringify({ type: 'WATCH_TOKEN', data })) + */ resolve(receipts); }).catch(function (error) { diff --git a/dist/index.js b/dist/index.js index ede072d..b66df0c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -110,9 +110,9 @@ var GitTokenWebHookManager = function (_GitTokenSignerClient) { _this.webhookRouter = _index12.default.bind(_this); _this.handleWebHookEvent = _index8.handleWebHookEvent.bind(_this); _this.rewardContributor = _index10.rewardContributor.bind(_this); - _this.calculateRewardBonus = _index5.calculateRewardBonus.bind(_this); _this.deploy = _index10.deploy.bind(_this); _this.pingEvent = _index9.pingEvent.bind(_this); + _this.gollumEvent = _index9.gollumEvent.bind(_this); // Variables _this.signerIpcPath = signerIpcPath; diff --git a/dist/middleware/processRequest.js b/dist/middleware/processRequest.js index cd86f06..ef04209 100644 --- a/dist/middleware/processRequest.js +++ b/dist/middleware/processRequest.js @@ -10,37 +10,128 @@ var _stringify2 = _interopRequireDefault(_stringify); exports.default = processRequest; +var _bluebird = require('bluebird'); + +var _bluebird2 = _interopRequireDefault(_bluebird); + +var _gittokenRewardValues = require('gittoken-reward-values'); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * [processRequest description] - * @param {[type]} req [description] - * @param {[type]} res [description] - * @return [type] [description] + * @param {[type]} req [description] + * @param {[type]} res [description] + * @param {Function} next [description] + * @return [type] [description] */ function processRequest(req, res, next) { - var headers = req.headers, - payload = req.body.payload; - - - var data = JSON.parse(payload); - - req.eventDetails = { - delivery_id: headers['x-github-delivery'], - event: headers['x-github-event'], - action: data['action'] ? data['action'] : '', - organization: data['organization']['login'], - contributor: data['sender']['login'], - date_received: new Date().getTime() - }; - - this.processEvent({ - eventDetails: req.eventDetails, - tokenDetails: req.tokenDetails - }).then(function (receipts) { - req.receipts = receipts; - next(); - }).catch(function (error) { - res.status(500).send((0, _stringify2.default)(error, null, 2)); + var _this = this; + + return new _bluebird2.default(function (resolve, reject) { + var headers = req.headers, + body = req.body, + tokenDetails = req.tokenDetails; + + + var event = headers['x-github-event']; + var payload = JSON.parse(body['payload']); + + _bluebird2.default.resolve().then(function () { + switch (event) { + case 'ping': + // TODO: REFACTOR + return _this.pingEvent({ payload: payload, headers: headers, tokenDetails: tokenDetails }); + break; + case 'create': + // payload.ref_type + return _this.rewardContributor({ + contributor: payload['sender']['login'], + event: event, + eventType: payload.ref_type, + rewardValue: _gittokenRewardValues.rewardValues[event][payload.ref_type], + reservedValue: _gittokenRewardValues.reservedValues[event][payload.ref_type], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }); + break; + case 'deployment_status': + // payload.status + return _this.rewardContributor({ + contributor: payload['sender']['login'], + event: event, + eventType: payload.ref_type, + rewardValue: _gittokenRewardValues.rewardValues[event][payload.status], + reservedValue: _gittokenRewardValues.reservedValues[event][payload.status], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }); + break; + case 'gollum': + return _this.gollumEvent({ payload: payload, headers: headers }); + break; + case 'page_build': + // payload.build.status + return _this.rewardContributor({ + contributor: payload['sender']['login'], + event: event, + eventType: payload.build.status, + rewardValue: _gittokenRewardValues.rewardValues[event][payload.build.status], + reservedValue: _gittokenRewardValues.reservedValues[event][payload.build.status], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }); + break; + case 'status': + // payload.state + return _this.rewardContributor({ + contributor: payload['sender']['login'], + event: event, + eventType: payload.state, + rewardValue: _gittokenRewardValues.rewardValues[event][payload.state], + reservedValue: _gittokenRewardValues.reservedValues[event][payload.state], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }); + break; + default: + return _this.rewardContributor({ + contributor: payload['sender']['login'], + event: event, + eventType: payload.action, + rewardValue: _gittokenRewardValues.rewardValues[event][payload.action], + reservedValue: _gittokenRewardValues.reservedValues[event][payload.action], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }); + } + }).then(function (receipts) { + req.receipts = receipts; + next(); + }).catch(function (error) { + res.status(500).send((0, _stringify2.default)(error, null, 2)); + }); + }); +} + +// Determine number of pages to reward + +function calcGollumReward(pages) { + var reward = 0; + + forEach(pages, function (page) { + reward += _gittokenRewardValues.rewardValues[page.action]; + }); + + return reward; +} + +function calcGollumReserve(pages) { + var reserved = 0; + + forEach(pages, function (page) { + reserved += _gittokenRewardValues.reservedValues[page.action]; }); + + return reserved; } \ No newline at end of file diff --git a/dist/utils/calculateTokenValues.js b/dist/utils/calculateTokenValues.js new file mode 100644 index 0000000..1f32b5e --- /dev/null +++ b/dist/utils/calculateTokenValues.js @@ -0,0 +1,30 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = calculateTokenValues; + +var _bluebird = require('bluebird'); + +var _bluebird2 = _interopRequireDefault(_bluebird); + +var _gittokenRewardValues = require('gittoken-reward-values'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function calculateTokenValues(_ref) { + var eventDetails = _ref.eventDetails; + + return new _bluebird2.default(function (resolve, reject) { + + /** + * TODO: Parse event details and payload body for reward values + */ + + resolve({ + rewardValue: 0, + reservedValue: 0 + }); + }); +} \ No newline at end of file diff --git a/dist/utils/index.js b/dist/utils/index.js index d5a4575..95b1936 100644 --- a/dist/utils/index.js +++ b/dist/utils/index.js @@ -3,16 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.verifyLog = exports.signLog = exports.calculateRewardBonus = exports.processEvent = undefined; +exports.verifyLog = exports.signLog = exports.processEvent = undefined; var _processEvent = require('./processEvent'); var _processEvent2 = _interopRequireDefault(_processEvent); -var _calculateRewardBonus = require('./calculateRewardBonus'); - -var _calculateRewardBonus2 = _interopRequireDefault(_calculateRewardBonus); - var _signLog = require('./signLog'); var _signLog2 = _interopRequireDefault(_signLog); @@ -24,6 +20,5 @@ var _verifyLog2 = _interopRequireDefault(_verifyLog); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.processEvent = _processEvent2.default; -exports.calculateRewardBonus = _calculateRewardBonus2.default; exports.signLog = _signLog2.default; exports.verifyLog = _verifyLog2.default; \ No newline at end of file diff --git a/dist/utils/processEvent.js b/dist/utils/processEvent.js index 4009208..2a1b85f 100644 --- a/dist/utils/processEvent.js +++ b/dist/utils/processEvent.js @@ -20,12 +20,16 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de function processEvent(_ref) { var _this = this; - var eventDetails = _ref.eventDetails, + var request = _ref.request, tokenDetails = _ref.tokenDetails; return new _bluebird2.default(function (resolve, reject) { + var headers = request.headers, + payload = request.body.payload; + + _bluebird2.default.resolve().then(function () { - switch (eventDetails['event']) { + switch (headers['x-github-event']) { case 'ping': return _this.pingEvent({ eventDetails: eventDetails, diff --git a/examples/manager.js b/examples/manager.js index aa25967..e31b382 100644 --- a/examples/manager.js +++ b/examples/manager.js @@ -1,4 +1,3 @@ -const Promise = require('bluebird') const GitTokenWebHookManager = require('../dist/index').default const { diff --git a/package.json b/package.json index a2bea25..e6a0928 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gittoken-webhook-manager", - "version": "0.0.39", + "version": "0.0.40", "description": "GitToken Manager for GitHub Web Hook Events", "main": "./dist/index", "scripts": { @@ -26,9 +26,10 @@ "dotenv": "^4.0.0", "ethereumjs-util": "^5.1.2", "express": "^4.15.4", - "gittoken-event-listener": "0.0.12", + "gittoken-event-listener": "0.0.13", "gittoken-registry": "0.0.1", - "gittoken-signer": "0.0.37", + "gittoken-reward-values": "0.0.1", + "gittoken-signer": "0.0.44", "hyperlog": "^4.12.1", "level": "^1.7.0", "request": "^2.81.0", @@ -46,6 +47,7 @@ "babel-preset-react": "^6.24.1", "babel-preset-stage-0": "^6.24.1", "babel-runtime": "^6.23.0", - "chai": "^4.0.1" + "chai": "^4.0.1", + "mocha": "^4.0.1" } } diff --git a/src/contract/deploy.js b/src/contract/deploy.js index 7d2ae23..7a33cbb 100644 --- a/src/contract/deploy.js +++ b/src/contract/deploy.js @@ -9,7 +9,7 @@ import split from 'split' export default function deploy({ tokenDetails }) { return new Promise((resolve, reject) => { - const msgID = `deploy_contract_${new Date().getTime()}` + const msgID = `deploy_contract_${new Date().getTime()}_${tokenDetails['organization']}` const payload = { id: msgID, diff --git a/src/contract/rewardContributor.js b/src/contract/rewardContributor.js index 822ac1c..33bba9e 100644 --- a/src/contract/rewardContributor.js +++ b/src/contract/rewardContributor.js @@ -3,20 +3,33 @@ import split from 'split' /** * [rewardContributor description] - * @param {[type]} eventDetails [description] - * @return [type] [description] + * @param {[type]} contributor [description] + * @param {[type]} event [description] + * @param {[type]} eventType [description] + * @param {[type]} rewardValue [description] + * @param {[type]} reservedValue [description] + * @param {[type]} deliveryID [description] + * @return [type] [description] */ -export default function rewardContributor ({ eventDetails }) { +export default function rewardContributor({ + contributor, + event, + eventType, + rewardValue, + reservedValue, + deliveryID +}) { return new Promise((resolve, reject) => { - const msgID = `reward_contributor_${new Date().getTime()}` + const msgID = `reward_${contributor}_${new Date().getTime()}_${deliveryID}` - this.calculateRewardBonus({ eventDetails }).then((rewardBonus) => { + try { const params = [ - eventDetails['contributor'], - eventDetails['event'], - eventDetails['action'], - rewardBonus, - eventDetails['delivery_id'] + contributor, + event, + eventType, + rewardValue, + reservedValue, + deliveryID ] this.signer.write(JSON.stringify({ @@ -24,7 +37,7 @@ export default function rewardContributor ({ eventDetails }) { event: 'sign_contract_transaction', data: { recoveryShare: this.recoveryShare, - organization: eventDetails['organization'], + organization, method: 'rewardContributor', params } @@ -38,9 +51,8 @@ export default function rewardContributor ({ eventDetails }) { reject(result) } }) - - }).catch((error) => { + } catch (error) { reject(error) - }) + } }) } diff --git a/src/events/gollumEvent.js b/src/events/gollumEvent.js new file mode 100644 index 0000000..f483eda --- /dev/null +++ b/src/events/gollumEvent.js @@ -0,0 +1,30 @@ +import Promise from 'bluebird' +import { rewardValues, reservedValues } from 'gittoken-reward-values' + +/** + * [gollumEvent description] + * @param {[type]} payload [description] + * @param {[type]} headers [description] + * @return [type] [description] + */ +export default function gollumEvent({ payload, headers }) { + return new Promise((resolve, reject) => { + const { pages } = payload + + Promise.resolve(pages).map((page, i) => { + return this.rewardContributor({ + contributor: payload['sender']['login'], + event: 'gollum', + eventType: payload[page.action], + rewardValue: rewardValues['gollum'][page.action], + reservedValue: reservedValues['gollum'][page.action], + deliveryID: `${headers['x-github-delivery']}-${i}`, + organization: payload['organization']['login'] + }) + }).then((receipts) => { + resolve(receipts) + }).catch((error) => { + reject(error) + }) + }) +} diff --git a/src/events/index.js b/src/events/index.js index 1c7c128..5c4e874 100644 --- a/src/events/index.js +++ b/src/events/index.js @@ -1,5 +1,7 @@ import pingEvent from './pingEvent' +import gollumEvent from './gollumEvent' export { - pingEvent + pingEvent, + gollumEvent } diff --git a/src/events/pingEvent.js b/src/events/pingEvent.js index f26e286..3a22496 100644 --- a/src/events/pingEvent.js +++ b/src/events/pingEvent.js @@ -6,19 +6,27 @@ import Promise from 'bluebird' * @param {[type]} tokenDetails [description] * @return [type] [description] */ -export default function pingEvent({ - eventDetails, - tokenDetails -}) { +export default function pingEvent({ payload, headers, tokenDetails }) { return new Promise((resolve, reject) => { let receipts = [] this.deploy({ tokenDetails }).then((txReceipt) => { receipts.push(txReceipt) - return this.rewardContributor({ eventDetails }) + return this.rewardContributor({ + contributor: payload['sender']['login'], + event: 'ping', + eventType: '', + rewardValue: rewardValues['ping'], + reservedValue: reservedValues['ping'], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }) }).then((txReceipt) => { receipts.push(txReceipt) + /* + NOTE: Consider removing Listener Service from Webhook process. + const data = { organization: tokenDetails['organization'], token: receipts[0]['contractAddress'] @@ -28,6 +36,8 @@ export default function pingEvent({ // Setup Event Listener for newly deployed token this.watcher.eventListener.write(JSON.stringify({ type: 'WATCH_TOKEN', data })) + */ + resolve(receipts) }).catch((error) => { diff --git a/src/index.js b/src/index.js index 1021019..12e975b 100644 --- a/src/index.js +++ b/src/index.js @@ -13,8 +13,7 @@ import GitTokenEventWatcherClient from 'gittoken-event-listener/dist/client/inde import { processEvent, signLog, - verifyLog, - calculateRewardBonus + verifyLog } from './utils/index' import { @@ -33,7 +32,8 @@ import { } from './controllers/index' import { - pingEvent + pingEvent, + gollumEvent } from './events/index' import { @@ -61,24 +61,24 @@ export default class GitTokenWebHookManager extends GitTokenSignerClient { }) // // Methods - this.signLog = signLog.bind(this) - this.verifyLog = verifyLog.bind(this) - this.processEvent = processEvent.bind(this) - this.selectFromRegistry = selectFromRegistry.bind(this) - this.insertIntoWebhook = insertIntoWebhook.bind(this) - this.saveEvent = saveEvent.bind(this) - this.validateOrganization = validateOrganization.bind(this) - this.processRequest = processRequest.bind(this) - this.webhookRouter = webhookRouter.bind(this) - this.handleWebHookEvent = handleWebHookEvent.bind(this) - this.rewardContributor = rewardContributor.bind(this) - this.calculateRewardBonus = calculateRewardBonus.bind(this) - this.deploy = deploy.bind(this) - this.pingEvent = pingEvent.bind(this) + this.signLog = signLog.bind(this) + this.verifyLog = verifyLog.bind(this) + this.processEvent = processEvent.bind(this) + this.selectFromRegistry = selectFromRegistry.bind(this) + this.insertIntoWebhook = insertIntoWebhook.bind(this) + this.saveEvent = saveEvent.bind(this) + this.validateOrganization = validateOrganization.bind(this) + this.processRequest = processRequest.bind(this) + this.webhookRouter = webhookRouter.bind(this) + this.handleWebHookEvent = handleWebHookEvent.bind(this) + this.rewardContributor = rewardContributor.bind(this) + this.deploy = deploy.bind(this) + this.pingEvent = pingEvent.bind(this) + this.gollumEvent = gollumEvent.bind(this) // Variables - this.signerIpcPath = signerIpcPath - this.recoveryShare = recoveryShare + this.signerIpcPath = signerIpcPath + this.recoveryShare = recoveryShare // this.deployParams = deployParams // Hyperlog DAG Store diff --git a/src/middleware/processRequest.js b/src/middleware/processRequest.js index 63a1dbe..93d7818 100644 --- a/src/middleware/processRequest.js +++ b/src/middleware/processRequest.js @@ -1,30 +1,117 @@ +import Promise from 'bluebird' +import { rewardValues, reservedValues } from 'gittoken-reward-values' + /** * [processRequest description] - * @param {[type]} req [description] - * @param {[type]} res [description] - * @return [type] [description] + * @param {[type]} req [description] + * @param {[type]} res [description] + * @param {Function} next [description] + * @return [type] [description] */ export default function processRequest(req, res, next) { - const { headers, body: { payload } } = req - - const data = JSON.parse(payload) - - req.eventDetails = { - delivery_id: headers['x-github-delivery'], - event: headers['x-github-event'], - action: data['action'] ? data['action'] : '', - organization: data['organization']['login'], - contributor: data['sender']['login'], - date_received: new Date().getTime(), - } - - this.processEvent({ - eventDetails: req.eventDetails, - tokenDetails: req.tokenDetails - }).then((receipts) => { - req.receipts = receipts - next() - }).catch((error) => { - res.status(500).send(JSON.stringify(error, null, 2)); + return new Promise((resolve, reject) => { + const { headers, body, tokenDetails } = req + + const event = headers['x-github-event'] + const payload = JSON.parse(body['payload']) + + Promise.resolve().then(() => { + switch(event) { + case 'ping': + // TODO: REFACTOR + return this.pingEvent({ payload, headers, tokenDetails }) + break; + case 'create': + // payload.ref_type + return this.rewardContributor({ + contributor: payload['sender']['login'], + event, + eventType: payload.ref_type, + rewardValue: rewardValues[event][payload.ref_type], + reservedValue: reservedValues[event][payload.ref_type], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }) + break; + case 'deployment_status': + // payload.status + return this.rewardContributor({ + contributor: payload['sender']['login'], + event, + eventType: payload.ref_type, + rewardValue: rewardValues[event][payload.status], + reservedValue: reservedValues[event][payload.status], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }) + break; + case 'gollum': + return this.gollumEvent({ payload, headers }) + break; + case 'page_build': + // payload.build.status + return this.rewardContributor({ + contributor: payload['sender']['login'], + event, + eventType: payload.build.status, + rewardValue: rewardValues[event][payload.build.status], + reservedValue: reservedValues[event][payload.build.status], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }) + break; + case 'status': + // payload.state + return this.rewardContributor({ + contributor: payload['sender']['login'], + event, + eventType: payload.state, + rewardValue: rewardValues[event][payload.state], + reservedValue: reservedValues[event][payload.state], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }) + break; + default: + return this.rewardContributor({ + contributor: payload['sender']['login'], + event, + eventType: payload.action, + rewardValue: rewardValues[event][payload.action], + reservedValue: reservedValues[event][payload.action], + deliveryID: headers['x-github-delivery'], + organization: payload['organization']['login'] + }) + } + }).then((receipts) => { + req.receipts = receipts + next() + }).catch((error) => { + res.status(500).send(JSON.stringify(error, null, 2)); + }) + }) +} + + +// Determine number of pages to reward + +function calcGollumReward(pages) { + let reward = 0; + + forEach(pages, (page) => { + reward += rewardValues[page.action] + }) + + return reward +} + + +function calcGollumReserve(pages) { + let reserved = 0; + + forEach(pages, (page) => { + reserved += reservedValues[page.action] }) + + return reserved } diff --git a/src/utils/calculateRewardBonus.js b/src/utils/calculateRewardBonus.js deleted file mode 100644 index cb8e8b2..0000000 --- a/src/utils/calculateRewardBonus.js +++ /dev/null @@ -1,8 +0,0 @@ -import Promise from 'bluebird' - -export default function calculateRewardBonus({ eventDetails }) { - return new Promise ((resolve, reject) => { - // TODO: Calculate Additional Reward Bonuses based on contribution analysis - resolve(0) - }) -} diff --git a/src/utils/index.js b/src/utils/index.js index c9dccef..3a35b6d 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,11 +1,9 @@ import processEvent from './processEvent' -import calculateRewardBonus from './calculateRewardBonus' import signLog from './signLog' import verifyLog from './verifyLog' export { processEvent, - calculateRewardBonus, signLog, verifyLog, } diff --git a/src/utils/processEvent.js b/src/utils/processEvent.js index 97682b2..e06d9e8 100644 --- a/src/utils/processEvent.js +++ b/src/utils/processEvent.js @@ -6,10 +6,12 @@ import Promise from 'bluebird' * @param {Object} tokenDetails [description] * @return [type] [description] */ -export default function processEvent({ eventDetails, tokenDetails }) { +export default function processEvent({ request, tokenDetails }) { return new Promise((resolve, reject) => { + const { headers, body: { payload } } = request + Promise.resolve().then(() => { - switch(eventDetails['event']) { + switch(headers['x-github-event']) { case 'ping': return this.pingEvent({ eventDetails, diff --git a/test/Dockerfile b/test/Dockerfile new file mode 100644 index 0000000..a28d0dd --- /dev/null +++ b/test/Dockerfile @@ -0,0 +1,11 @@ +# Use this Dockerfile for CI tests only! + +FROM node:6.11.0 + +WORKDIR /gittoken-webhook-manager + +ADD . . + +RUN npm install + +CMD mocha diff --git a/test/docker-compose.yml b/test/docker-compose.yml new file mode 100644 index 0000000..0bb870d --- /dev/null +++ b/test/docker-compose.yml @@ -0,0 +1,37 @@ +version: '3.0' +volumes: + signer-volume: + ipc-volume: + log-volume: +services: + listener: + env_file: + - ../node_modules/gittoken-event-listener/.env + build: + context: ../node_modules/gittoken-event-listener/. + ipc: signer + volumes: + - ipc-volume:/tmp/ + signer: + env_file: + - ../node_modules/gittoken-signer/.env + build: + context: ../node_modules/gittoken-signer/. + ipc: host + volumes: + - signer-volume:/keystore/ + - ipc-volume:/tmp/ + webhookmgr: + ports: + - 3000:3000 + env_file: + - ../.env + build: + context: . + depends_on: + - listener + - signer + ipc: signer + volumes: + - log-volume:/db + - ipc-volume:/tmp/ diff --git a/test/test_pingEvent.js b/test/test_pingEvent.js new file mode 100644 index 0000000..3a3e66b --- /dev/null +++ b/test/test_pingEvent.js @@ -0,0 +1,57 @@ +const Promise = require('bluebird') +const GitTokenWebHookManager = require('../dist/index').default +const assert = require('chai').assert + +const { + port, + logDBPath, + signerIpcPath, + watcherIpcPath, + recoveryShare, + mysqlHost, + mysqlUser, + mysqlRootPassword, + mysqlDatabase +} = require('../config') + +function instantiateWebhookMgr() { + return new Promise((resolve, reject) => { + + /** + * NOTE: To run the tests, both the GitToken Signer and Contract Event Listener + * services must be running locally before running the tests and the correct environmental + * variables provided in the constructor of the WebHook Manager + * + */ + + try { + const manager = new GitTokenWebHookManager({ + port, + logDBPath, + signerIpcPath, + watcherIpcPath, + recoveryShare, + mysqlHost, + mysqlUser, + mysqlRootPassword, + mysqlDatabase + }) + + resolve(manager) + + } catch (error) { + reject(error) + } + }) +} + + +describe('GitToken Webhook Manager Ping Event', function() { + it('Should deploy a new contract on a ping event', function() { + instantiateWebhookMgr().then((manager) => { + assert.notEqual(manager, null, "Expect web hook manager instance to not be null") + }).catch((error) => { + assert.equal(error, null, "Expect no errors to occur") + }) + }).timeout(20000) +})