提交 0cb89e8b 编写于 作者: S Sercan

under heavy development #53

上级 b99e25e5
......@@ -63,6 +63,7 @@
<th>Use Url</th>
<th>Use Ssl</th>
<th>Certificate Auth</th>
<th>Use Ssh</th>
<th>Edit</th>
<th>Delete</th>
</tr>
......@@ -113,6 +114,9 @@
</li>
<li class=""><a data-toggle="tab" href="#tab-3-url" aria-expanded="false">URL</a>
</li>
<li class=""><a data-toggle="tab" href="#tab-4-ssh"
aria-expanded="false">SSH</a>
</li>
</ul>
<div class="tab-content">
<!-- TAB 1 -->
......@@ -137,6 +141,7 @@
<div class="form-group"><label class="col-lg-2 control-label">Port</label>
<div class="col-lg-10"><input id="inputPort" value="27017"
data-required="true"
min="1"
type="number"
placeholder="Port"
class="form-control">
......@@ -182,13 +187,13 @@
<!-- STANDARD AUTH FORM-->
<form id="formStandardAuth" class="form-horizontal">
<div class="form-group"><label class="col-lg-2 control-label">User
</label>
</label>
<div class="col-lg-10"><input id="inputUser" type="text" placeholder="User"
class="form-control">
</div>
</div>
<div class="form-group"><label class="col-lg-2 control-label">Password
</label>
</label>
<div class="col-lg-10"><input id="inputPassword" type="password"
placeholder="Password"
class="form-control">
......@@ -202,7 +207,7 @@
</div>
</div>
<div class="form-group"><label class="col-lg-2 control-label">Use SSL
</label>
</label>
<div id="divUseSSL" class="col-lg-10">
<input id="inputUseSSL" type="checkbox"
class="form-control"
......@@ -228,7 +233,7 @@
</div>
<div class="form-group"><label class="col-lg-2 control-label">PassPhrase
</label>
</label>
<div class="col-lg-10"><input id="inputPassPhrase" type="password"
placeholder="PassPhrase"
class="form-control">
......@@ -237,7 +242,7 @@
<div class="form-group">
<label class="col-lg-2 control-label">Certificate Key File
</label>
</label>
<div class="col-lg-10">
<div class="input-group">
<input class="form-control" type="text"
......@@ -251,7 +256,7 @@
</div>
<div class="form-group">
<label class="col-lg-2 control-label">ROOT CA file </label>
<label class="col-lg-2 control-label">ROOT CA file </label>
<div class="col-lg-10">
<div class="input-group">
<input class="form-control" type="text" id="inputRootCaPath"
......@@ -302,6 +307,98 @@
</form>
</div>
</div>
<!-- TAB 4-->
<div id="tab-4-ssh" class="tab-pane">
<div class="panel-body no-borders modal-background">
<form class="form-horizontal">
<div class="form-group"><label class="col-lg-2 control-label">Use SSH
Tunnel</label>
<div id="divUseSsh" class="col-lg-10">
<input id="inputUseSsh" type="checkbox"
class="form-control"
checked=""
style="position: absolute; opacity: 0;"/>
</div>
</div>
<div class="form-group"><label class="col-lg-2 control-label">Hostname</label>
<div class="col-lg-10"><input id="inputSshHostname"
data-required="true"
disabled="true"
type="text"
placeholder="Hostname"
class="form-control">
</div>
</div>
<div class="form-group"><label class="col-lg-2 control-label">Port</label>
<div class="col-lg-10"><input id="inputSshPort" value="22"
data-required="true"
disabled="true"
min="1"
type="number"
placeholder="Port"
class="form-control">
</div>
</div>
<div class="form-group"><label class="col-lg-2 control-label">Username</label>
<div class="col-lg-10"><input id="inputSshUsername"
data-required="true"
disabled="true"
type="text"
placeholder="Username"
class="form-control">
</div>
</div>
<div class="form-group">
<label class="col-lg-2 control-label">Authentication</label>
<div class="col-lg-10">
<select id="cmbSshAuthType"
disabled="true"
data-placeholder="Authentication type.."
class="chosen-select form-control"
tabindex="-1">
<option></option>
</select>
</div>
</div>
</form>
<!-- CERTIFICATE AUTH FORM FOR SSH -->
<form id="formSshCertificateAuth" class="form-horizontal" style="display: none;">
<div class="form-group">
<label class="col-lg-2 control-label">Certificate </label>
<div class="col-lg-10">
<div class="input-group">
<input class="form-control" type="text" id="inputSshCertificatePath"
disabled="true">
<input class="input-group-btn filestyle" type="file"
id="inputSshCertificate"
data-buttonName="btn-primary">
</div>
</div>
</div>
<div class="form-group">
<label class="col-lg-2 control-label">PassPhrase</label>
<div class="col-lg-10"><input id="inputSshPassPhrase" type="password"
placeholder="PassPhrase"
class="form-control">
</div>
</div>
</form>
<!-- PASSWORD AUTH FORM FOR SSH-->
<form id="formSshPasswordAuth" class="form-horizontal" style="display: none;">
<div class="form-group">
<label class="col-lg-2 control-label">Password</label>
<div class="col-lg-10"><input id="inputSshPassword" type="password"
placeholder="Password"
class="form-control">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
......
......@@ -26,6 +26,7 @@ Template.topNavbar.onRendered(function () {
$(":file").filestyle({icon: false, input: false});
Template.topNavbar.initIChecks();
Template.topNavbar.initChosen();
});
......@@ -39,6 +40,15 @@ Template.topNavbar.events({
}
},
'change #inputSshCertificate': function () {
var blob = $('#inputSshCertificate')[0].files[0];
if (blob) {
$('#inputSshCertificatePath').val(blob.name);
} else {
$('#inputSshCertificatePath').val('');
}
},
'change #inputRootCa': function () {
var blob = $('#inputRootCa')[0].files[0];
if (blob) {
......@@ -57,6 +67,18 @@ Template.topNavbar.events({
}
},
'change #cmbSshAuthType': function () {
var value = $('#cmbSshAuthType').find(":selected").text();
if (value == 'Password') {
$('#formSshPasswordAuth').show();
$('#formSshCertificateAuth').hide();
}
else {
$('#formSshCertificateAuth').show();
$('#formSshPasswordAuth').hide();
}
},
'click #btnRefreshCollections': function (e) {
e.preventDefault();
......@@ -100,6 +122,31 @@ Template.topNavbar.events({
var connection = Connections.findOne({_id: Session.get(Template.strSessionConnection)});
Template.topNavbar.clearAllFieldsOfConnectionModal();
if (connection.sshAddress) {
$('#inputUseSsh').iCheck('check');
$('#inputSshHostname').val(connection.sshAddress);
$('#inputSshPort').val(connection.sshPort);
$('#inputSshUsername').val(connection.sshUser);
if (connection.sshPassword) {
$("#cmbSshAuthType").val('Password').trigger('chosen:updated');
$('#inputSshPassword').val(connection.sshPassword);
$('#formSshPasswordAuth').show();
$('#formSshCertificateAuth').hide();
}
if (connection.sshCertificatePath) {
$("#cmbSshAuthType").val('Key File').trigger('chosen:updated');
$('#inputSshCertificatePath').val(connection.sshCertificatePath);
$('#formSshPasswordAuth').hide();
$('#formSshCertificateAuth').show();
}
if (connection.sshPassPhrase) {
$('#inputSshPassPhrase').val(connection.sshPassPhrase);
}
} else {
$('#inputUseSsh').iCheck('uncheck');
}
if (connection.url) {
$('#inputUseUrl').iCheck('check');
$('#inputUrl').val(connection.url);
......@@ -184,6 +231,24 @@ Template.topNavbar.events({
var inputCertificateKeyPathSelector = $('#inputCertificateKeyPath');
var connection = {};
if ($('#inputUseSsh').iCheck('update')[0].checked) {
connection.sshAddress = $('#inputSshHostname').val();
connection.sshPort = $('#inputSshPort').val();
connection.sshUser = $('#inputSshUsername').val();
if ($('#cmbSshAuthType').val() == 'Password') {
connection.sshPassword = $('#inputSshPassword').val();
}
else if ($('#cmbSshAuthType').val() == 'Key File') {
if ($('#inputSshCertificatePath').val()) {
connection.sshCertificatePath = $('#inputSshCertificatePath').val();
}
if ($('#inputSshPassPhrase').val()) {
connection.sshPassPhrase = $('#inputSshPassPhrase').val();
}
}
}
if ($('#inputUseUrl').iCheck('update')[0].checked) {
connection.url = $('#inputUrl').val();
connection.databaseName = Template.topNavbar.parseDatabaseNameFromUrl(connection.url);
......@@ -288,7 +353,15 @@ Template.topNavbar.clearAllFieldsOfConnectionModal = function () {
$("#inputCertificatePath").val('');
$("#inputPassPhrase").val('');
$("#inputRootCaPath").val('');
$("#inputSshHostname").val('');
$("#inputSshPort").val('22');
$("#inputSshUsername").val('');
$("#cmbSshAuthType").val('').trigger('chosen:updated');
$("#inputSshCertificatePath").val('');
$("#inputSshPassPhrase").val('');
$("#inputSshPassword").val('');
$('#inputUseUrl').iCheck('uncheck');
$('#inputUseSsh').iCheck('uncheck');
$('#inputUseSSL').iCheck('uncheck');
$('#inputAuthStandard').iCheck('check');
$(":file").filestyle('clear');
......@@ -346,6 +419,24 @@ Template.topNavbar.proceedRootCertificateLoading = function (saveMethodName, con
};
Template.topNavbar.loadCertificatesAndSave = function (saveMethodName, connection, currentConnection) {
var sshCertificateSelector = $('#inputSshCertificate');
if (sshCertificateSelector.get(0).files.length == 0 && currentConnection && currentConnection.sshCertificate && $('#inputSshCertificatePath').val()) {
connection.sshCertificate = currentConnection.sshCertificate;
Template.topNavbar.proceedLoadingCertificates(saveMethodName, connection, currentConnection);
} else {
if (sshCertificateSelector.get(0).files.length != 0) {
Template.topNavbar.loadFile(function (file) {
connection.sshCertificate = new Uint8Array(file.target.result);
Template.topNavbar.proceedLoadingCertificates(saveMethodName, connection, currentConnection);
}, sshCertificateSelector[0].files[0]);
} else {
Template.topNavbar.proceedLoadingCertificates(saveMethodName, connection, currentConnection);
}
}
};
Template.topNavbar.proceedLoadingCertificates = function (saveMethodName, connection, currentConnection) {
var certificateSelector = $('#inputCertificate');
if ($('#inputAuthCertificate').iCheck('update')[0].checked && !$('#inputUseUrl').iCheck('update')[0].checked) {
......@@ -375,13 +466,49 @@ Template.topNavbar.loadFile = function (callback, blob) {
fileReader.readAsArrayBuffer(blob);
};
Template.topNavbar.checkConnection = function (connection) {
var sshAuthTypeSelector = $('#cmbSshAuthType');
if (!connection.name) {
toastr.error("Connection name can't be empty");
return false;
}
if ($('#inputUseSsh').iCheck('update')[0].checked) {
if (!connection.sshAddress) {
toastr.error("Ssh hostname can't be empty");
return false;
}
if (!connection.sshPort) {
toastr.error("Ssh port can't be empty");
return false;
}
if (!connection.sshUser) {
toastr.error("Ssh user can't be empty");
return false;
}
if (!sshAuthTypeSelector.find(":selected").text()) {
toastr.error("Ssh authentication type can't be empty");
return false;
}
if (sshAuthTypeSelector.find(":selected").text() == 'Password') {
if (!connection.sshPassword) {
toastr.error("Ssh password can't be empty");
return false;
}
} else {
if (!connection.sshCertificatePath) {
toastr.error("Ssh certificate path can't be empty");
return false;
}
}
}
if ($('#inputUseUrl').iCheck('update')[0].checked) {
if (!connection.url) {
toastr.error("Url can't be empty");
......@@ -453,6 +580,19 @@ Template.topNavbar.connect = function (isRefresh) {
});
};
Template.topNavbar.initChosen = function () {
var cmb = $('#cmbSshAuthType');
cmb.append($("<option></option>")
.attr("value", "Password")
.text("Password"));
cmb.append($("<option></option>")
.attr("value", "Key File")
.text("Key File"));
cmb.chosen({width: '100%'});
};
Template.topNavbar.initIChecks = function () {
var selector = $('#divAuthType');
selector.iCheck({
......@@ -465,6 +605,7 @@ Template.topNavbar.initIChecks = function () {
var anchorTab1Selector = $('#anchorTab1');
var anchorTab2Selector = $('#anchorTab2');
var inputUseUriSelector = $("#inputUseUrl");
var inputUseSshSelector = $("#inputUseSsh");
inputAuthStandardSelector.iCheck('check');
......@@ -472,6 +613,10 @@ Template.topNavbar.initIChecks = function () {
checkboxClass: 'icheckbox_square-green'
});
$('#divUseSsh').iCheck({
checkboxClass: 'icheckbox_square-green'
});
$('#divUseUrl').iCheck({
checkboxClass: 'icheckbox_square-green'
});
......@@ -505,6 +650,39 @@ Template.topNavbar.initIChecks = function () {
anchorTab2Selector.attr('data-toggle', 'tab');
}
});
inputUseSshSelector.iCheck('uncheck');
inputUseSshSelector.on('ifChanged', function (event) {
var inputSshHostnameSelector = $('#inputSshHostname');
var inputSshPortSelector = $('#inputSshPort');
var inputSshUsernameSelector = $('#inputSshUsername');
var comboSshAuthTypeSelector = $('#cmbSshAuthType');
var inputSshPasswordSelector = $('#inputSshPassword');
var inputSshCertificatePathSelector = $('#inputSshCertificatePath');
var inputSshCertificateSelector = $('#inputSshCertificate');
var inputSshPassPhrase = $('#inputSshPassPhrase');
var isChecked = event.currentTarget.checked;
if (isChecked) {
inputSshHostnameSelector.prop('disabled', false);
inputSshPortSelector.prop('disabled', false);
inputSshUsernameSelector.prop('disabled', false);
comboSshAuthTypeSelector.prop('disabled', false).trigger("chosen:updated");
inputSshCertificatePathSelector.prop('disabled', false);
inputSshCertificateSelector.prop('disabled', false);
inputSshPassPhrase.prop('disabled', false);
} else {
inputSshHostnameSelector.prop('disabled', true);
inputSshPortSelector.prop('disabled', true);
inputSshUsernameSelector.prop('disabled', true);
comboSshAuthTypeSelector.prop('disabled', true).trigger("chosen:updated");
inputSshCertificatePathSelector.prop('disabled', true);
inputSshCertificateSelector.prop('disabled', true);
inputSshPassPhrase.prop('disabled', true);
}
});
};
Template.topNavbar.populateConnectionsTable = function () {
......@@ -518,7 +696,8 @@ Template.topNavbar.populateConnectionsTable = function () {
{data: "name"},
{data: "url"},
{data: "useSsl"},
{data: "sslCertificatePath"}
{data: "sslCertificatePath"},
{data: "sshAddress"}
],
columnDefs: [
{
......@@ -550,12 +729,21 @@ Template.topNavbar.populateConnectionsTable = function () {
},
{
targets: [5],
render: function (data) {
if (!data) {
return 'false';
}
return 'true';
}
},
{
targets: [6],
data: null,
bSortable: false,
defaultContent: '<a href="" title="Edit" class="editor_edit"><i class="fa fa-edit text-navy"></i></a>'
},
{
targets: [6],
targets: [7],
data: null,
bSortable: false,
defaultContent: '<a href="" title="Delete" class="editor_remove"><i class="fa fa-remove text-navy"></i></a>'
......
......@@ -3,6 +3,34 @@
*/
Connections = new Mongo.Collection('connections');
Connections.attachSchema(new SimpleSchema({
'sshAddress': {
type: "String",
optional: true
},
'sshPort': {
type: "Number",
optional: true
},
'sshUser': {
type: "String",
optional: true
},
'sshPassword': {
type: "String",
optional: true
},
'sshCertificate': {
type: "String",
optional: true
},
'sshCertificatePath': {
type: "String",
optional: true
},
sshPassPhrase: {
type: "String",
optional: true
},
url: {
type: "String",
optional: true
......
......@@ -2,6 +2,7 @@
"mongodb": "2.1.7",
"mongodb-backup": "1.5.4",
"mongodb-restore": "1.5.2",
"tunnel-ssh": "3.2.1-beta",
"cheerio": "0.20.0",
"winston": "2.2.0"
}
\ No newline at end of file
......@@ -766,6 +766,75 @@
}
}
},
"tunnel-ssh": {
"version": "3.2.1-beta",
"dependencies": {
"bluebird": {
"version": "3.3.3"
},
"debug": {
"version": "2.2.0",
"dependencies": {
"ms": {
"version": "0.7.1"
}
}
},
"lodash": {
"version": "4.5.1"
},
"rc": {
"version": "1.1.6",
"dependencies": {
"deep-extend": {
"version": "0.4.1"
},
"ini": {
"version": "1.3.4"
},
"minimist": {
"version": "1.2.0"
},
"strip-json-comments": {
"version": "1.0.4"
}
}
},
"ssh2": {
"version": "0.4.15",
"dependencies": {
"readable-stream": {
"version": "1.0.34",
"dependencies": {
"core-util-is": {
"version": "1.0.2"
},
"isarray": {
"version": "0.0.1"
},
"string_decoder": {
"version": "0.10.31"
},
"inherits": {
"version": "2.0.1"
}
}
},
"ssh2-streams": {
"version": "0.0.23",
"dependencies": {
"streamsearch": {
"version": "0.1.2"
},
"asn1": {
"version": "0.2.3"
}
}
}
}
}
}
},
"winston": {
"version": "2.2.0",
"dependencies": {
......
......@@ -49,30 +49,38 @@ Meteor.methods({
LOGGER.info('[connect]', connectionUrl, clearConnectionOptionsForLog(connectionOptions));
var mongodbApi = Meteor.npmRequire('mongodb').MongoClient;
return Async.runSync(function (done) {
mongodbApi.connect(connectionUrl, connectionOptions, function (mainError, db) {
if (mainError || db == null || db == undefined) {
done(mainError, db);
if (db) {
db.close();
}
return;
if (connection.sshAddress) {
var config = {
dstPort: connection.port,
host: connection.sshAddress,
port: connection.sshPort,
username: connection.sshUser
};
if (connection.sshCertificate) {
config.privateKey = connection.sshCertificate;
}
try {
database = db;
database.listCollections().toArray(function (err, collections) {
done(err, collections);
});
if (connection.sshPassPhrase) {
config.passphrase = connection.sshPassPhrase;
}
catch (ex) {
LOGGER.error('[connect]', ex);
done(new Meteor.Error(ex.message), null);
if (database) {
database.close();
}
if (connection.sshPassword) {
config.password = connection.sshPassword;
}
});
var tunnel = new Meteor.npmRequire('tunnel-ssh').tunnel;
tunnel(config, function (error) {
if (error) {
done(new Meteor.Error(error.message), null);
return;
}
proceedConnectingMongodb(connectionUrl, connectionOptions, done);
});
} else {
proceedConnectingMongodb(connectionUrl, connectionOptions, done);
}
});
},
......@@ -146,4 +154,30 @@ Meteor.methods({
}
});
}
});
\ No newline at end of file
});
var proceedConnectingMongodb = function (connectionUrl, connectionOptions, done) {
var mongodbApi = Meteor.npmRequire('mongodb').MongoClient;
mongodbApi.connect(connectionUrl, connectionOptions, function (mainError, db) {
if (mainError || db == null || db == undefined) {
done(mainError, db);
if (db) {
db.close();
}
return;
}
try {
database = db;
database.listCollections().toArray(function (err, collections) {
done(err, collections);
});
}
catch (ex) {
LOGGER.error('[connect]', ex);
done(new Meteor.Error(ex.message), null);
if (database) {
database.close();
}
}
});
};
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册