Skip to content

Commit

Permalink
resolves #53 allow private key file to be specified; expand leading ~
Browse files Browse the repository at this point in the history
  • Loading branch information
mojavelinux committed Feb 9, 2018
1 parent a7df2b9 commit 4b7a6bc
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 3 deletions.
23 changes: 22 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* Licensed under the MIT license.
*/

const fs = require('fs')
const os = require('os')
const path = require('path')
const util = require('util')
const EventEmitter = require('events').EventEmitter
Expand Down Expand Up @@ -47,6 +49,8 @@ GulpSSH.prototype.getClient = function () {
ssh.gulpQueue = []
ssh.gulpConnected = false
this.connections[ssh.gulpId] = ssh
var options = this.options
var privateKeyFile

ssh
.on('error', function (err) {
Expand All @@ -59,7 +63,24 @@ GulpSSH.prototype.getClient = function () {
delete ctx.connections[this.gulpId]
})
.on('ready', ssh.gulpFlushReady)
.connect(this.options.sshConfig)

if ((privateKeyFile = options.sshConfig.privateKeyFile)) {
if (privateKeyFile.charAt() === '~' && (path.sep === '\\'
? /\/|\\/.test(privateKeyFile.charAt(1)) : privateKeyFile.charAt(1) === '/')) {
privateKeyFile = os.homedir() + privateKeyFile.substr(1)
}
var gulpSSH = this
fs.readFile(privateKeyFile, function (err, privateKey) {
if (err) throw err
var sshConfig = Object.assign({}, options.sshConfig, { privateKey })
delete sshConfig.privateKeyFile
gulpSSH.options = Object.assign({}, options, { sshConfig })
ssh.connect(sshConfig)
})
} else {
ssh.connect(options.sshConfig)
}

return ssh
}

Expand Down
61 changes: 59 additions & 2 deletions test/gulp-ssh-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const { expect } = chai
const fs = require('fs-extra')
const gulp = require('gulp')
const GulpSSH = require('..')
const os = require('os')
const path = require('path')
const { obj: map } = require('through2')

Expand All @@ -15,11 +16,12 @@ const FIXTURES_DIR = path.join(__dirname, 'fixtures')

describe('GulpSSH', () => {
let gulpSSH
const privateKeyFile = path.resolve(__dirname, 'etc/ssh/id_rsa')
let sshConfig = {
host: 'localhost',
port: process.env.CI ? 2222 : 22,
username: process.env.USER,
privateKey: fs.readFileSync(path.resolve(__dirname, 'etc/ssh/id_rsa'))
privateKey: fs.readFileSync(privateKeyFile)
}

const collectFiles = (files, cb) => {
Expand All @@ -42,22 +44,77 @@ describe('GulpSSH', () => {
it('should fail if options are not provided', () => {
expect(GulpSSH).to.throw('sshConfig required')
})

it('should defer loading of private key specified in privateKeyFile option', () => {
const localSshConfig = Object.assign({}, sshConfig, { privateKeyFile })
delete localSshConfig.privateKey
gulpSSH = new GulpSSH({ ignoreErrors: false, sshConfig: localSshConfig })
expect(gulpSSH.options.sshConfig.privateKeyFile).to.equal(privateKeyFile)
expect(gulpSSH.options.sshConfig).to.not.have.property('privateKey')
})
})

describe('connect', () => {
it('should connect if credentials are good', (done) => {
gulpSSH.on('error', done)
gulpSSH.getClient().gulpReady(function () {
expect(this.gulpConnected).to.equal(true)
gulpSSH.close()
done()
})
})

it('should fail to connect if credentials are bad', (done) => {
gulpSSH.options.sshConfig = Object.assign({}, gulpSSH.options.sshConfig, { username: 'nobody' })
gulpSSH.options.sshConfig = Object.assign({}, sshConfig, { username: 'nobody' })
gulpSSH.on('error', () => done())
gulpSSH.getClient().gulpReady(() => {
expect.fail()
gulpSSH.close()
done()
})
})

it('should load contents of private key on connect if privateKeyFile option is specified', (done) => {
const localSshConfig = Object.assign({}, sshConfig, { privateKeyFile })
delete localSshConfig.privateKey
gulpSSH = new GulpSSH({ ignoreErrors: false, sshConfig: localSshConfig })
gulpSSH.on('error', done)
gulpSSH.getClient().gulpReady(function () {
expect(gulpSSH.options.sshConfig.privateKey).to.eql(sshConfig.privateKey)
expect(gulpSSH.options.sshConfig).to.not.have.property('privateKeyFile')
expect(localSshConfig.privateKeyFile).to.equal(privateKeyFile)
expect(localSshConfig).to.not.have.property('privateKey')
gulpSSH.close()
done()
})
})

it('should expand leading tilde in privateKeyFile option', (done) => {
const tildePrivateKeyFile = path.join('~', path.relative(os.homedir(), privateKeyFile))
const localSshConfig = Object.assign({}, sshConfig, { privateKeyFile: tildePrivateKeyFile })
delete localSshConfig.privateKey
gulpSSH = new GulpSSH({ ignoreErrors: false, sshConfig: localSshConfig })
gulpSSH.on('error', done)
gulpSSH.getClient().gulpReady(function () {
expect(gulpSSH.options.sshConfig.privateKey).to.eql(sshConfig.privateKey)
expect(gulpSSH.options.sshConfig).to.not.have.property('privateKeyFile')
expect(localSshConfig.privateKeyFile).to.equal(tildePrivateKeyFile)
expect(localSshConfig).to.not.have.property('privateKey')
gulpSSH.close()
done()
})
})

it('should use private key from privateKeyFile option instead of privateKey option', (done) => {
const localSshConfig = Object.assign({}, sshConfig, { privateKeyFile, privateKey: 'bogus' })
gulpSSH = new GulpSSH({ ignoreErrors: false, sshConfig: localSshConfig })
gulpSSH.on('error', done)
gulpSSH.getClient().gulpReady(function () {
expect(gulpSSH.options.sshConfig.privateKey).to.eql(sshConfig.privateKey)
expect(gulpSSH.options.sshConfig).to.not.have.property('privateKeyFile')
expect(localSshConfig.privateKeyFile).to.equal(privateKeyFile)
expect(localSshConfig.privateKey).to.equal('bogus')
gulpSSH.close()
done()
})
})
Expand Down

0 comments on commit 4b7a6bc

Please sign in to comment.