Skip to content

Commit

Permalink
Java Keystore
Browse files Browse the repository at this point in the history
  • Loading branch information
pdesmarets committed Jul 26, 2019
1 parent 1223805 commit 04c49ee
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 59 deletions.
8 changes: 4 additions & 4 deletions forward_engineering/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ module.exports = {
}
},

applyToInstance(connectionInfo, logger, callback) {
applyToInstance(connectionInfo, logger, callback, app) {
logger.clear();
logger.log('info', connectionInfo, 'connectionInfo', connectionInfo.hiddenKeys);

applyToInstance(connectionInfo, logger)
applyToInstance(connectionInfo, logger, app)
.then(result => {
callback(null, result);
})
Expand All @@ -117,8 +117,8 @@ module.exports = {
});
},

testConnection(connectionInfo, logger, callback) {
testConnection(connectionInfo)
testConnection(connectionInfo, logger, callback, app) {
testConnection(connectionInfo, app)
.then(
callback,
callback
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const applyToInstance = (cassandra) => (connectionInfo, logger) => {
const applyToInstance = (cassandra) => (connectionInfo, logger, app) => {
const script = connectionInfo.script;

if (!Array.isArray(connectionInfo.hosts)) {
return Promise.reject({ message: 'Hosts were not defined' });
}

return cassandra.connect(connectionInfo)
return cassandra.connect(app)(connectionInfo)
.then(() => {
logger.log('info', {
message: 'Applying cassandra script has been started'
Expand Down Expand Up @@ -55,7 +55,7 @@ const applyToInstance = (cassandra) => (connectionInfo, logger) => {
.catch(err => {
cassandra.close();

return Promise.reject(err);
return Promise.reject(cassandra.prepareError(err));
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
module.exports = (cassandra) => (connectionInfo) => {
module.exports = (cassandra) => (connectionInfo, app) => {
if (!Array.isArray(connectionInfo.hosts)) {
return Promise.reject({ message: 'Hosts were not defined' });
}

return cassandra.connect(connectionInfo)
return cassandra.connect(app)(connectionInfo)
.then(() => {
cassandra.close();
}, (err) => {
cassandra.close();
return Promise.reject(err);
return Promise.reject(cassandra.prepareError(err));
});
};
6 changes: 3 additions & 3 deletions forward_engineering/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion forward_engineering/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "",
"author": "Hackolade",
"dependencies": {
"lodash": "^4.17.13"
"lodash": "^4.17.11"
},
"installed": true
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "Cassandra",
"version": "0.1.29",
"versionDate": "2019-05-16",
"version": "0.1.30",
"versionDate": "2019-07-26",
"author": "hackolade",
"engines": {
"hackolade": "2.1.x",
"hackolade": "3.4.0",
"hackoladePlugin": "1.2.0"
},
"contributes": {
Expand Down
22 changes: 14 additions & 8 deletions reverse_engineering/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,38 @@ const cassandra = require('./cassandraHelper');
const systemKeyspaces = require('./package').systemKeyspaces;

module.exports = {
connect: function(connectionInfo, logger, cb){
connect: function(connectionInfo, logger, cb, app){
logger.clear();
logger.log('info', connectionInfo, 'connectionInfo', connectionInfo.hiddenKeys);

if (!Array.isArray(connectionInfo.hosts)) {
return cb({ message: 'Hosts were not defined' });
}

cassandra.connect(connectionInfo).then(cb, cb);
cassandra.connect(app)(connectionInfo)
.then(cb, (error) => {
logger.log('error', error, 'Connection error');
cb(error);
});
},

disconnect: function(connectionInfo, cb){
cassandra.close();
cb();
},

testConnection: function(connectionInfo, logger, cb){
testConnection: function(connectionInfo, logger, cb, app){
this.connect(connectionInfo, logger, (error) => {
this.disconnect(connectionInfo, () => {});
return cb(error);
});

return cb(cassandra.prepareError(error));
}, app);
},

getDbCollectionsNames: function(connectionInfo, logger, cb) {
getDbCollectionsNames: function(connectionInfo, logger, cb, app) {
const { includeSystemCollection } = connectionInfo;

cassandra.connect(connectionInfo).then(() => {
cassandra.connect(app)(connectionInfo).then(() => {
let keyspaces = cassandra.getKeyspacesNames();

if (!includeSystemCollection) {
Expand All @@ -49,7 +54,8 @@ module.exports = {
return cb(err, result);
});
}).catch((error) => {
return cb(error || 'error');
logger.log('error', error);
return cb(cassandra.prepareError(error) || 'error');
});
},

Expand Down
110 changes: 85 additions & 25 deletions reverse_engineering/cassandraHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,103 @@ var state = {
client: null
};

const getSslOptions = (info) => {
const requireKeyStore = (app) => new Promise((resolve, reject) => {
return app.require('java-ssl', (err, Keystore) => {
if (err) {
reject(err);
} else {
resolve(Keystore);
}
});
});

const getCertificatesFromFiles = (info) => {
const readFile = (filePath) => filePath ? fs.readFileSync(filePath) : '';

try {
const ca = readFile(info.sslCaFile);
const cert = readFile(info.sslCertFile);
const key = readFile(info.sslKeyFile);

return Promise.resolve({
ca, cert, key
});
} catch (e) {
return Promise.reject(e);
}
};

const getCertificatesFromKeystore = (info, app) => {
return requireKeyStore(app).then((Keystore) => {
const store = Keystore(info.keystore, info.keystorepass);
const ca = store.getCert(info.alias);
const key = store.getPrivateKey(info.alias);

return {
cert: ca,
key,
ca,
};
});
};

const isSsl = (ssl) => ssl && ssl !== 'false';

const getSslOptions = (info, app) => {
const add = (key, value, obj) => !value ? obj : Object.assign({}, obj, {
[key]: value
});
if (!info.ssl) {
return {};
if (!isSsl(info.ssl)) {
return Promise.resolve({});
}

const host = _.get(info, 'hosts[0].host', '');
const ca = readFile(info.sslCaFile);
const cert = readFile(info.sslCertFile);
const key = readFile(info.sslKeyFile);

const sslOptions = _.flow([
add.bind(null, 'ca', ca),
add.bind(null, 'cert', cert),
add.bind(null, 'key', key),
add.bind(null, 'host', host),
])({
rejectUnauthorized: true,
host
});
let sslPromise;

return { sslOptions };
if (info.ssl === 'jks') {
sslPromise = getCertificatesFromKeystore(info, app);
} else {
sslPromise = getCertificatesFromFiles(info);
}

return sslPromise.then(ssl => {
const sslOptions = _.flow([
add.bind(null, 'ca', ssl.ca),
add.bind(null, 'cert', ssl.cert),
add.bind(null, 'key', ssl.key),
add.bind(null, 'host', host),
])({
rejectUnauthorized: true,
host
});

return { sslOptions };
});
};

const connect = (info) => {
const connect = (app) => (info) => {
if (!state.client) {
const username = info.user;
const password = info.password;
const authProvider = new cassandra.auth.PlainTextAuthProvider(username, password);
const contactPoints = info.hosts.map(item => `${item.host}:${item.port}`);
const readTimeout = 60 * 1000;
state.client = new cassandra.Client(Object.assign({
contactPoints,
authProvider,
socketOptions: {
readTimeout
}
}, getSslOptions(info)));

return getSslOptions(info, app)
.then(sslOptions => {
return new cassandra.Client(Object.assign({
contactPoints,
authProvider,
socketOptions: {
readTimeout
}
}, sslOptions));
})
.then((client) => {
state.client = client;

return state.client.connect();
});
}

return state.client.connect();
Expand Down Expand Up @@ -456,6 +512,10 @@ const mergeDocuments = (documents) => {
};

const prepareError = (error) => {
if (!(error instanceof Error)) {
return error;
}

return {
message: error.message,
stack: error.stack
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,35 @@
"inputKeyword": "password",
"inputType": "password",
"isHiddenKey": true
},
}
]
}, {
"lowerTab": "SSL",
"structure": [
{
"inputLabel": "Use SSL",
"inputLabel": "SSL Type",
"inputKeyword": "ssl",
"inputType": "checkbox"
"inputType": "select",
"options": [{
"label": "None",
"value": false
}, {
"label": "Java Keystore",
"value": "jks"
}, {
"label": "Certificates",
"value": true
}]
},
{
"inputLabel": "Certificate Authority",
"inputKeyword": "sslCaFile",
"inputType": "file",
"inputPlaceholder": "Certificate Authority",
"extensions": ["pem", "crt", "key"],
"isHiddenKey": true,
"dependency": {
"key": "ssl",
"value": true
"value": [true, "true"]
}
},
{
Expand All @@ -78,10 +91,9 @@
"inputType": "file",
"inputPlaceholder": "Client Certificate",
"extensions": ["pem", "crt", "key"],
"isHiddenKey": true,
"dependency": {
"key": "ssl",
"value": true
"value": [true, "true"]
}
},
{
Expand All @@ -90,12 +102,42 @@
"inputType": "file",
"inputPlaceholder": "Client Private Key",
"extensions": ["pem", "crt", "key"],
"dependency": {
"key": "ssl",
"value": [true, "true"]
}
},
{
"inputLabel": "Keystore",
"inputKeyword": "keystore",
"inputType": "file",
"inputPlaceholder": "Keystore path and filename",
"extensions": ["*"],
"dependency": {
"key": "ssl",
"value": "jks"
}
},
{
"inputLabel": "Keystore password",
"inputKeyword": "keystorepass",
"inputType": "password",
"isHiddenKey": true,
"dependency": {
"key": "ssl",
"value": true
"value": "jks"
}
},
{
"inputLabel": "Alias Name",
"inputKeyword": "alias",
"inputType": "text",
"isHiddenKey": true,
"dependency": {
"key": "ssl",
"value": "jks"
}
}
]
]
}
]

0 comments on commit 04c49ee

Please sign in to comment.