forked from mirrors/probot
add PRIVATE_KEY_PATH env var support; closes #122
The loading preference is: 1. CLI flag 2. `PRIVATE_KEY` 3. `PRIVATE_KEY_PATH` 4. Find a `.pem` file in the current working dir Changes: - break out PK loading logic into module `lib/private-key.js` - add more info to error messaging if probot fails to find a PK - add tests - add note to deployment docs
This commit is contained in:
parent
f639dfc30d
commit
0f14bf3499
|
@ -3,20 +3,14 @@
|
|||
require('dotenv').config();
|
||||
|
||||
const program = require('commander');
|
||||
const {findPrivateKey} = require('../lib/private-key');
|
||||
|
||||
program
|
||||
.usage('[options] <plugins...>')
|
||||
.option('-i, --integration <id>', 'ID of the GitHub Integration', process.env.INTEGRATION_ID)
|
||||
.option('-s, --secret <secret>', 'Webhook secret of the GitHub Integration', process.env.WEBHOOK_SECRET || 'development')
|
||||
.option('-p, --port <n>', 'Port to start the server on', process.env.PORT || 3000)
|
||||
.option('-P, --private-key <file>', 'Path to certificate of the GitHub Integration', path => {
|
||||
try {
|
||||
return require('fs').readFileSync(path);
|
||||
} catch (err) {
|
||||
console.warn(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}, process.env.PRIVATE_KEY)
|
||||
.option('-P, --private-key <file>', 'Path to certificate of the GitHub Integration', findPrivateKey)
|
||||
.option('-t, --tunnel <subdomain>', 'Expose your local bot to the internet', process.env.SUBDOMAIN || process.env.NODE_ENV != 'production')
|
||||
.parse(process.argv);
|
||||
|
||||
|
@ -25,18 +19,6 @@ if(!program.integration) {
|
|||
program.help();
|
||||
}
|
||||
|
||||
if(!program.privateKey) {
|
||||
const fs = require('fs');
|
||||
const key = fs.readdirSync(process.cwd()).find(path => path.endsWith('.pem'));
|
||||
|
||||
if (key) {
|
||||
program.privateKey = fs.readFileSync(key);
|
||||
} else {
|
||||
console.warn("Missing GitHub Integration private key.\nUse --private-key flag or set PRIVATE_KEY environment variable.");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(program.tunnel) {
|
||||
try {
|
||||
setupTunnel();
|
||||
|
|
|
@ -32,7 +32,13 @@ To deploy a plugin to any cloud provider, you will need 3 environment variables:
|
|||
|
||||
- `INTEGRATION_ID`: the ID of the integration, which you can get from the [integration settings page](https://github.com/settings/integrations).
|
||||
- `WEBHOOK_SECRET`: the **Webhook Secret** that you generated when you created the integration.
|
||||
- `PRIVATE_KEY`: the contents of the private key you downloaded after creating the integration.
|
||||
|
||||
And one of:
|
||||
|
||||
- `PRIVATE_KEY`: the contents of the private key you downloaded after creating the integration, OR...
|
||||
- `PRIVATE_KEY_PATH`: the path to a private key file.
|
||||
|
||||
`PRIVATE_KEY` takes precedence over `PRIVATE_KEY_PATH`.
|
||||
|
||||
### Heroku
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
const fs = require('fs');
|
||||
|
||||
/**
|
||||
* Finds a private key through various user-(un)specified methods.
|
||||
* Order of precedence:
|
||||
* 1. Explicit path (CLI option)
|
||||
* 2. `PRIVATE_KEY` env var
|
||||
* 3. `PRIVATE_KEY_PATH` env var
|
||||
* 4. Any file w/ `.pem` extension in current working dir
|
||||
* @param {string} [filepath] - Explicit, user-defined path to keyfile
|
||||
* @returns {string} Private key
|
||||
*/
|
||||
function findPrivateKey(filepath) {
|
||||
if (filepath) {
|
||||
return fs.readFileSync(filepath);
|
||||
}
|
||||
if (process.env.PRIVATE_KEY) {
|
||||
return process.env.PRIVATE_KEY;
|
||||
}
|
||||
if (process.env.PRIVATE_KEY_PATH) {
|
||||
return fs.readFileSync(process.env.PRIVATE_KEY_PATH);
|
||||
}
|
||||
const foundPath = fs.readdirSync(process.cwd())
|
||||
.find(path => path.endsWith('.pem'));
|
||||
if (foundPath) {
|
||||
return findPrivateKey(foundPath);
|
||||
}
|
||||
throw new Error(`Missing private key for GitHub Integration. Please use:
|
||||
* \`--private-key=/path/to/private-key\` flag, or
|
||||
* \`PRIVATE_KEY\` environment variable, or
|
||||
* \`PRIVATE_KEY_PATH\` environment variable
|
||||
`);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findPrivateKey
|
||||
};
|
|
@ -0,0 +1,107 @@
|
|||
const fs = require('fs');
|
||||
|
||||
const expect = require('expect');
|
||||
|
||||
const {findPrivateKey} = require('../lib/private-key');
|
||||
|
||||
describe('private-key', function () {
|
||||
let privateKey;
|
||||
let keyfilePath;
|
||||
|
||||
beforeEach(function () {
|
||||
privateKey = 'I AM PRIVET KEY!?!!~1!';
|
||||
keyfilePath = '/some/path';
|
||||
expect.spyOn(fs, 'readFileSync')
|
||||
.andReturn(privateKey);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
expect.restoreSpies();
|
||||
});
|
||||
|
||||
describe('findPrivateKey()', function () {
|
||||
describe('when a filepath is provided', function () {
|
||||
it('should read the file at given filepath', function () {
|
||||
findPrivateKey(keyfilePath);
|
||||
expect(fs.readFileSync)
|
||||
.toHaveBeenCalledWith(keyfilePath);
|
||||
});
|
||||
|
||||
it('should return the key', function () {
|
||||
expect(findPrivateKey(keyfilePath))
|
||||
.toEqual(privateKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a PRIVATE_KEY env var is provided', function () {
|
||||
beforeEach(function () {
|
||||
process.env.PRIVATE_KEY = privateKey;
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
delete process.env.PRIVATE_KEY;
|
||||
});
|
||||
|
||||
it('should return the key', function () {
|
||||
expect(findPrivateKey())
|
||||
.toEqual(privateKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a PRIVATE_KEY_PATH env var is provided', function () {
|
||||
beforeEach(function () {
|
||||
process.env.PRIVATE_KEY_PATH = keyfilePath;
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
delete process.env.PRIVATE_KEY_PATH;
|
||||
});
|
||||
|
||||
it('should read the file at given filepath', function () {
|
||||
findPrivateKey();
|
||||
expect(fs.readFileSync)
|
||||
.toHaveBeenCalledWith(keyfilePath);
|
||||
});
|
||||
|
||||
it('should return the key', function () {
|
||||
expect(findPrivateKey())
|
||||
.toEqual(privateKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when no private key is provided', function () {
|
||||
beforeEach(function () {
|
||||
expect.spyOn(fs, 'readdirSync')
|
||||
.andReturn([
|
||||
'foo.txt',
|
||||
'foo.pem'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should look for one in the current directory', function () {
|
||||
findPrivateKey();
|
||||
expect(fs.readdirSync)
|
||||
.toHaveBeenCalledWith(process.cwd());
|
||||
});
|
||||
|
||||
describe('and a key file is present', function () {
|
||||
it('should load the key file', function () {
|
||||
findPrivateKey();
|
||||
expect(fs.readFileSync)
|
||||
.toHaveBeenCalledWith('foo.pem');
|
||||
});
|
||||
});
|
||||
|
||||
describe('and a key file is not present', function () {
|
||||
beforeEach(function () {
|
||||
fs.readdirSync.restore();
|
||||
});
|
||||
|
||||
it('should throw an error', function () {
|
||||
expect(findPrivateKey)
|
||||
.toThrow(Error, /missing private key for github integrationy/i);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue