Created
January 13, 2014 16:41
-
-
Save myndzi/8403458 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var prompt = require('promised-prompt'), | |
Promise = prompt.Promise; | |
prompt({ | |
required: true | |
}).ask('db type?', { | |
key: 'db', | |
type: 'multi', | |
default: 'pg', | |
validator: [ 'pg' ] | |
}).ask({ | |
key: 'rootUser', | |
question: 'root user?' | |
}).ask({ | |
key: 'rootPass', | |
type: 'password', | |
question: 'root password?' | |
}).ask({ | |
key: 'user', | |
question: 'client username?' | |
}).ask({ | |
key: 'host', | |
question: 'host?', | |
default: 'localhost' | |
}).ask({ | |
key: 'dbName', | |
question: 'database name?', | |
default: 'twitchbot' | |
}).ask({ | |
key: 'port', | |
type: 'integer', | |
question: 'port?', | |
default: '5432' | |
}).then(function () { | |
switch (this.db) { | |
case 'pg': | |
var pg = this.pg = require('pg'); | |
Promise.promisifyAll(pg); | |
var conString = [ | |
'postgres', '://', | |
encodeURIComponent(this.rootUser), ':', | |
encodeURIComponent(this.rootPass), '@', | |
encodeURIComponent(this.host), ':', | |
encodeURIComponent(this.port), '/' | |
].join(''); | |
console.log('OPENING DB CONNECTION'); | |
return pg.connectAsync(conString).spread(function (client, done) { | |
Promise.promisifyAll(client); | |
this.client = client; | |
this.query = client.queryAsync.bind(client); | |
this.pgDone = done; | |
}.bind(this)); | |
break; | |
default: | |
return Promise.reject('Unsupported database: ' + this.db); | |
break; | |
} | |
}).then(function () { | |
var self = this, client = self.client; | |
return self.query( | |
'SELECT 1 FROM pg_database WHERE datname = $1', | |
[ self.dbName ] | |
).then(function (res) { | |
if (res.rowCount === 0) { | |
var query = 'CREATE DATABASE ' + self.client.escapeIdentifier(self.dbName); | |
return self.query(query).then(function () { | |
console.log(query); | |
}); | |
} | |
}); | |
}).then(function () { | |
return this.query('BEGIN TRANSACTION'); | |
}).then(function (res) { | |
var self = this, client = this.client; | |
return self.query( | |
'SELECT 1 FROM pg_roles WHERE rolname = $1', | |
[ self.user ] | |
).then(function (res) { | |
if (res.rowCount > 0) return; | |
return getRandomPass(24).then(function (password) { | |
self.pass = password; | |
var query = 'CREATE ROLE ' + client.escapeIdentifier(self.user) + | |
' WITH ENCRYPTED password ' + client.escapeLiteral(self.pass); | |
return self.query(query).then(function () { | |
console.log(query.replace(/(ENCRYPTED password).*?$/, '$1 *****')); | |
}); | |
}); | |
}); | |
}).then(function () { | |
var self = this, client = this.client; | |
var query = 'GRANT ALL PRIVILEGES ON DATABASE ' + client.escapeIdentifier(self.dbName) + | |
' TO ' + client.escapeIdentifier(self.user); | |
return self.query(query).then(function () { | |
console.log(query) | |
}); | |
}).ask('write configuration?', { | |
type: 'boolean', | |
default: 'N' | |
}).then(function (res) { | |
var config = { | |
user: this.user, | |
pass: this.pass, | |
host: this.host, | |
port: this.port, | |
database: this.dbName | |
}; | |
if (res) { | |
return prompt().ask('filename?', { | |
default: 'config.json' | |
}).then(function (res) { | |
console.log('WRITING CONFIGURATION'); | |
console.log('filename: ', res); | |
console.log(config); | |
}) | |
} | |
}).then(function () { | |
console.log('DONE'); | |
}).catch(function (err) { | |
console.log(err); | |
}).finally(function () { | |
this.pgDone(); | |
console.log('CLOSING DB CONNECTION'); | |
this.pg.end(); | |
}); | |
var ie = require('int-encoder'), | |
crypto = require('crypto'); | |
var alpha = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()[{]}/?=+\\|-_\'",<.>;:'; | |
function getRandomPass(len) { | |
var deferred = Promise.defer(); | |
var bytes = Math.ceil(Math.log(alpha.length)/Math.log(256)*len); | |
crypto.randomBytes(bytes, function (ex, buf) { | |
ie.alphabet(alpha); | |
var hex = buf.toString('hex'), | |
num = ie.encode(hex, 16); | |
// cut off the MSB, it won't have the full range available | |
deferred.resolve(num.slice(1)); | |
}); | |
return deferred.promise; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment