Merged add_webhook_secret

This commit is contained in:
Pol.Alvarez@BSC 2018-02-23 17:36:03 +01:00
commit d5c8f44616
4 changed files with 86 additions and 32 deletions

View File

@ -5,3 +5,6 @@ EXPOSE 8080
# Set this variable to the name of your production config file (without the extension) # Set this variable to the name of your production config file (without the extension)
ENV NODE_ENV development ENV NODE_ENV development
# Set this variable to the value of the secret field of the Github webhook
ENV WEBHOOK_SECRET ''

View File

@ -118,7 +118,7 @@ const logTransaction = function (txId, from, to, amount, gasPrice) {
logger.info("===================================================="); logger.info("====================================================");
} }
const log = function (msg) { const info = function (msg) {
logger.info(msg); logger.info(msg);
} }
@ -141,9 +141,9 @@ const sendTransaction = function (to, amount, gasPrice) {
// This ensures the transaction cannot be replayed on different networks // This ensures the transaction cannot be replayed on different networks
chainId: providers.Provider.chainId.homestead chainId: providers.Provider.chainId.homestead
}; };
const signedTransaction = wallet.sign(transaction); const signedTransaction = wallet.sign(transaction);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
provider.sendTransaction(signedTransaction) provider.sendTransaction(signedTransaction)
.then(function(hash) { .then(function(hash) {
@ -151,7 +151,7 @@ const sendTransaction = function (to, amount, gasPrice) {
}).catch(function(err) { }).catch(function(err) {
reject(err); reject(err);
}); });
}); });
} }
@ -161,7 +161,7 @@ module.exports = {
getAmount: getAmount, getAmount: getAmount,
getGasPrice: prices.getGasPrice, getGasPrice: prices.getGasPrice,
sendTransaction: sendTransaction, sendTransaction: sendTransaction,
log: log, info: info,
logTransaction: logTransaction, logTransaction: logTransaction,
error: error error: error
} }

View File

@ -10,6 +10,8 @@
const config = require('./config'); const config = require('./config');
const bot = require('./bot'); const bot = require('./bot');
const crypto = require('crypto');
var express = require('express'), var express = require('express'),
cors = require('cors'), cors = require('cors'),
@ -23,28 +25,74 @@ app.use(helmet());
// Receive a POST request at the url specified by an env. var. // Receive a POST request at the url specified by an env. var.
app.post(`${config.urlEndpoint}`, jsonParser, function (req, res, next) { app.post(`${config.urlEndpoint}`, jsonParser, function (req, res, next) {
if (!req.body || !req.body.action) { if (!req.body || !req.body.action) {
return res.sendStatus(400); return res.sendStatus(400);
} else if (!bot.needsFunding(req)) { } else if (!bot.needsFunding(req)) {
return res.sendStatus(204); return res.sendStatus(204);
} }
setTimeout(() => {
processRequest(req)
.then(() => {
bot.info('issue well funded: ' + res.body.issue.url);
})
.catch((err) => {
bot.error('Error funding issue: ' + req.body.issue.url);
bot.error('error: ' + err);
bot.error('dump: ' + req);
});
}, config.delayInMiliSeconds);
validation = validateRequest(req);
if (validation.correct) {
setTimeout(() => {
processRequest(req)
.then(() => {
bot.info('issue well funded: ' + req.body.issue.url);
})
.catch((err) => {
bot.error('Error processing request: ' + req.body.issue.url);
bot.error('error: ' + err);
bot.error('dump: ' + req.body);
});
}, config.delayInMiliSeconds);
} else {
bot.error('Error validating issue: ' + req.body.issue.url);
bot.error('error: ' + validation.error);
}
return res.sendStatus(200); return res.sendStatus(200);
}); });
const validateRequest = function (req) {
validation = {correct: false, error: ''};
webhookSecret = process.env.WEBHOOK_SECRET;
if(!webhookSecret) {
validation.error = 'Github Webhook Secret key not found. ' +
'Please set env variable WEBHOOK_SECRET to github\'s webhook secret value';
} else {
const blob = JSON.stringify(req.body);
const hmac = crypto.createHmac('sha1', webhookSecret);
const ourSignature = `sha1=${hmac.update(blob).digest('hex')}`;
const theirSignature = req.get('X-Hub-Signature');
const bufferA = Buffer.from(ourSignature, 'utf8');
const bufferB = Buffer.from(theirSignature, 'utf8');
const safe = crypto.timingSafeEqual(bufferA, bufferB);
if (safe) {
validation.correct = true;
} else {
validation.error = 'Invalid signature. Check that WEBHOOK_SECRET ' +
'env variable matches github\'s webhook secret value';
}
}
return validation;
}
const processRequest = function (req) { const processRequest = function (req) {
<<<<<<< HEAD
const wallet = bot.wallet; const wallet = bot.wallet;
=======
const eth = bot.eth;
>>>>>>> add_webhook_secret
const from = config.sourceAddress; const from = config.sourceAddress;
const to = bot.getAddress(req); const to = bot.getAddress(req);
@ -74,5 +122,5 @@ const processRequest = function (req) {
const port = process.env.PORT || 8181 const port = process.env.PORT || 8181
app.listen(port, function () { app.listen(port, function () {
bot.log('Autobounty listening on port', port); bot.info('Autobounty listening on port', port);
}); });

View File

@ -31,39 +31,42 @@ All issues tagged with **[bounty](https://github.com/status-im/status-react/issu
Autobounty is build using docker. Before building the image, you need to set up a configuration as follows: Autobounty is build using docker. Before building the image, you need to set up a configuration as follows:
The [config]() folder contains the files for configuring the bot. The description for the variables can be found in *default.js*. Create a production config file (e.g. *production.js*) uing the {default,development}.js as template to override the default ones. **Remeber** to set the environment variable *NODE_ENV* in the dockerfile (e.g. `ENV NODE_ENV production`). The [config]() folder contains the files for configuring the bot. The description for the variables can be found in *default.js*. Create a production config file (e.g. *production.js*) uing the {default,development}.js as template to override the default ones.
**Remeber** to set the environment variable *NODE_ENV* in the dockerfile (e.g. `ENV NODE_ENV production`) and *WEBHOOK_SECRET* to the value specified in the secret field during the webhook creation (e.g. for random creation *ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'*).
)
```javascript ```javascript
// Debug mode for testing the bot // Debug mode for testing the bot
debug: true, debug: true,
// URL where the bot is listening (e.g. '/funding') // URL where the bot is listening (e.g. '/funding')
urlEndpoint: '', urlEndpoint: '',
// Path for the log files inside the docker image (e.g. './log/'), // Path for the log files inside the docker image (e.g. './log/'),
remember to create the folder inside the docker workspace if you change it remember to create the folder inside the docker workspace if you change it
(the folde will be copied to the docker image during the build) (the folde will be copied to the docker image during the build)
logPath: '', logPath: '',
// URL for the signer (e.g. 'https://ropsten.infura.io') // URL for the signer (e.g. 'https://ropsten.infura.io')
signerPath: '', signerPath: '',
// Address with the funding for the bounties // Address with the funding for the bounties
sourceAddress: '', sourceAddress: '',
// Token of the currency for fetching real time prices (e.g. 'SNT') // Token of the currency for fetching real time prices (e.g. 'SNT')
token: '', token: '',
// Limit for the gas used in a transaction (e.g. 92000) // Limit for the gas used in a transaction (e.g. 92000)
gasLimit: 0, gasLimit: 0,
// Price per hour you will pay in dolars (e.g. 35) // Price per hour you will pay in dolars (e.g. 35)
priceHour: 0, priceHour: 0,
// Delay before funding a bounty (e.g. 3600000) // Delay before funding a bounty (e.g. 3600000)
delayInMiliSeconds: 0, delayInMiliSeconds: 0,
// Bounty Labels for the issues and the correspondent houres (e.g. {'bounty-xs': 3}) // Bounty Labels for the issues and the correspondent houres (e.g. {'bounty-xs': 3})
bountyLabels: {}, bountyLabels: {},
@ -80,12 +83,12 @@ Create a github webhook with the following information:
* Payoload URL: IP_HOST/URL_ENDPOINT * Payoload URL: IP_HOST/URL_ENDPOINT
* Content Type: application/json * Content Type: application/json
* Secret: blank * Secret: the value you set for environment variable WEBHOOK_SECRET.
* Configure the webhook to be triggered by comments in issues selecting the Issue Comment box in 'Let me select individual events' * Configure the webhook to be triggered by comments in issues selecting the Issue Comment box in 'Let me select individual events'
Where *IP_HOST* is the ip of the machine running the docker image and *URL_ENDPOINT* is the configuration variable with the same name in your custom config file. Where *IP_HOST* is the ip of the machine running the docker image and *URL_ENDPOINT* is the configuration variable with the same name in your custom config file.
#### Build #### Build
To build and run the docker image issue the following commands: To build and run the docker image issue the following commands: