mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge pull request #251 from Belphemur/credentials-pr
Rewrite credentials API to work with save on deploy.
This commit is contained in:
commit
d4919e27bd
@ -92,6 +92,14 @@ var RED = function() {
|
|||||||
node.dirty = true;
|
node.dirty = true;
|
||||||
node.changed = false;
|
node.changed = false;
|
||||||
}
|
}
|
||||||
|
if(node._creds) {
|
||||||
|
delete node._creds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RED.nodes.eachConfig(function (confNode) {
|
||||||
|
if (confNode._creds) {
|
||||||
|
delete confNode._creds;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// Once deployed, cannot undo back to a clean state
|
// Once deployed, cannot undo back to a clean state
|
||||||
RED.history.markAllDirty();
|
RED.history.markAllDirty();
|
||||||
|
@ -175,13 +175,17 @@ RED.nodes = function() {
|
|||||||
/**
|
/**
|
||||||
* Converts a node to an exportable JSON Object
|
* Converts a node to an exportable JSON Object
|
||||||
**/
|
**/
|
||||||
function convertNode(n) {
|
function convertNode(n, exportCreds) {
|
||||||
|
exportCreds = exportCreds || false;
|
||||||
var node = {};
|
var node = {};
|
||||||
node.id = n.id;
|
node.id = n.id;
|
||||||
node.type = n.type;
|
node.type = n.type;
|
||||||
for (var d in n._def.defaults) {
|
for (var d in n._def.defaults) {
|
||||||
node[d] = n[d];
|
node[d] = n[d];
|
||||||
}
|
}
|
||||||
|
if(exportCreds && n._creds) {
|
||||||
|
node._creds = n._creds.send;
|
||||||
|
}
|
||||||
if (n._def.category != "config") {
|
if (n._def.category != "config") {
|
||||||
node.x = n.x;
|
node.x = n.x;
|
||||||
node.y = n.y;
|
node.y = n.y;
|
||||||
@ -235,11 +239,11 @@ RED.nodes = function() {
|
|||||||
nns.push(workspaces[i]);
|
nns.push(workspaces[i]);
|
||||||
}
|
}
|
||||||
for (var i in configNodes) {
|
for (var i in configNodes) {
|
||||||
nns.push(convertNode(configNodes[i]));
|
nns.push(convertNode(configNodes[i], true));
|
||||||
}
|
}
|
||||||
for (var i in nodes) {
|
for (var i in nodes) {
|
||||||
var node = nodes[i];
|
var node = nodes[i];
|
||||||
nns.push(convertNode(node));
|
nns.push(convertNode(node, true));
|
||||||
}
|
}
|
||||||
return nns;
|
return nns;
|
||||||
}
|
}
|
||||||
|
@ -22,25 +22,40 @@ RED.editor = function() {
|
|||||||
return 'credentials/' + dashedType + "/" + nodeID;
|
return 'credentials/' + dashedType + "/" + nodeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendCredentials(node,credDefinition,prefix) {
|
/**
|
||||||
var credentials = {};
|
* Assign the credentials to the node
|
||||||
|
* @param node - the node containing the credentials
|
||||||
|
* @param credDefinition - definition of the credentials
|
||||||
|
* @param prefix - prefix of the input fields
|
||||||
|
*/
|
||||||
|
function manageNodeCredentials(node, credDefinition, prefix) {
|
||||||
|
if(!node._creds) {
|
||||||
|
node._creds = {server: {}, send: {}, input: {}};
|
||||||
|
}
|
||||||
|
|
||||||
for (var cred in credDefinition) {
|
for (var cred in credDefinition) {
|
||||||
var input = $("#" + prefix + '-' + cred);
|
var input = $("#" + prefix + '-' + cred);
|
||||||
var value = input.val();
|
var value = input.val();
|
||||||
if (credDefinition[cred].type == 'password' && value == '__PWRD__') {
|
if (credDefinition[cred].type == 'password') {
|
||||||
continue;
|
if(value != '') {
|
||||||
|
node._creds.input['has' + cred] = true;
|
||||||
|
if (value == '__PWRD__') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node._creds.input['has' + cred] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
credentials[cred] = value;
|
if (node._creds.server[cred] != value) {
|
||||||
}
|
node._creds.send[cred] = value;
|
||||||
node._def._creds = credentials;
|
} else {
|
||||||
$.ajax({
|
delete node._creds.send[cred];
|
||||||
url: getCredentialsURL(node.type, node.id),
|
}
|
||||||
type: 'POST',
|
if (credDefinition[cred].type != 'password') {
|
||||||
data: credentials,
|
node._creds.input[cred] = value;
|
||||||
success: function (result) {
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -222,7 +237,7 @@ RED.editor = function() {
|
|||||||
if (editing_node._def.credentials) {
|
if (editing_node._def.credentials) {
|
||||||
var prefix = 'node-input';
|
var prefix = 'node-input';
|
||||||
var credDefinition = editing_node._def.credentials;
|
var credDefinition = editing_node._def.credentials;
|
||||||
sendCredentials(editing_node,credDefinition,prefix);
|
manageNodeCredentials(editing_node,credDefinition,prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -357,6 +372,32 @@ RED.editor = function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign the value to each credential field
|
||||||
|
* @param node
|
||||||
|
* @param credDef
|
||||||
|
* @param credData
|
||||||
|
* @param prefix
|
||||||
|
*/
|
||||||
|
function populateCredentialsInputs(node, credDef, credData, prefix) {
|
||||||
|
for (var cred in credDef) {
|
||||||
|
if (credDef[cred].type == 'password') {
|
||||||
|
if (credData['has' + cred]) {
|
||||||
|
$('#' + prefix + '-' + cred).val('__PWRD__');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#' + prefix + '-' + cred).val('');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
preparePropertyEditor(credData, cred, prefix);
|
||||||
|
}
|
||||||
|
attachPropertyChangeHandler(node, credDef, cred, prefix);
|
||||||
|
for (var cred in credDef) {
|
||||||
|
$("#" + prefix + "-" + cred).change();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare all of the editor dialog fields
|
* Prepare all of the editor dialog fields
|
||||||
* @param node - the node being edited
|
* @param node - the node being edited
|
||||||
@ -373,25 +414,16 @@ RED.editor = function() {
|
|||||||
attachPropertyChangeHandler(node,definition.defaults,d,prefix);
|
attachPropertyChangeHandler(node,definition.defaults,d,prefix);
|
||||||
}
|
}
|
||||||
if (definition.credentials) {
|
if (definition.credentials) {
|
||||||
|
if (node._creds) {
|
||||||
$.getJSON(getCredentialsURL(node.type, node.id), function (data) {
|
populateCredentialsInputs(node, definition.credentials, node._creds.input, prefix);
|
||||||
for (var cred in definition.credentials) {
|
} else {
|
||||||
if (definition.credentials[cred].type == 'password') {
|
node._creds = {server: {}, send: {}, input: {}};
|
||||||
if (data['has' + cred]) {
|
$.getJSON(getCredentialsURL(node.type, node.id), function (data) {
|
||||||
$('#' + prefix + '-' + cred).val('__PWRD__');
|
node._creds.server = data;
|
||||||
}
|
node._creds.input = jQuery.extend({}, data);
|
||||||
else {
|
populateCredentialsInputs(node, definition.credentials, node._creds.input, prefix);
|
||||||
$('#' + prefix + '-' + cred).val('');
|
});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
preparePropertyEditor(data, cred, prefix);
|
|
||||||
}
|
|
||||||
attachPropertyChangeHandler(node, definition.credentials, cred, prefix);
|
|
||||||
for (var cred in definition.credentials) {
|
|
||||||
$("#" + prefix + "-" + cred).change();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (definition.oneditprepare) {
|
if (definition.oneditprepare) {
|
||||||
definition.oneditprepare.call(node);
|
definition.oneditprepare.call(node);
|
||||||
@ -449,14 +481,6 @@ RED.editor = function() {
|
|||||||
var configNode = RED.nodes.node(configId);
|
var configNode = RED.nodes.node(configId);
|
||||||
var configTypeDef = RED.nodes.getType(configType);
|
var configTypeDef = RED.nodes.getType(configType);
|
||||||
|
|
||||||
if (configTypeDef.credentials) {
|
|
||||||
$.ajax({
|
|
||||||
url: getCredentialsURL(configType, configId),
|
|
||||||
type: 'DELETE',
|
|
||||||
success: function (result) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (configTypeDef.ondelete) {
|
if (configTypeDef.ondelete) {
|
||||||
configTypeDef.ondelete.call(RED.nodes.node(configId));
|
configTypeDef.ondelete.call(RED.nodes.node(configId));
|
||||||
}
|
}
|
||||||
@ -546,7 +570,7 @@ RED.editor = function() {
|
|||||||
updateConfigNodeSelect(configProperty,configType,configId);
|
updateConfigNodeSelect(configProperty,configType,configId);
|
||||||
}
|
}
|
||||||
if (configTypeDef.credentials) {
|
if (configTypeDef.credentials) {
|
||||||
sendCredentials(configNode,configTypeDef.credentials,"node-config-input");
|
manageNodeCredentials(configNode,configTypeDef.credentials,"node-config-input");
|
||||||
}
|
}
|
||||||
if (configTypeDef.oneditsave) {
|
if (configTypeDef.oneditsave) {
|
||||||
configTypeDef.oneditsave.call(RED.nodes.node(configId));
|
configTypeDef.oneditsave.call(RED.nodes.node(configId));
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var util = require("util");
|
var util = require("util");
|
||||||
|
var when = require("when");
|
||||||
|
|
||||||
var credentials = {};
|
var credentials = {};
|
||||||
var storage = null;
|
var storage = null;
|
||||||
@ -32,40 +33,6 @@ function isRegistered(type) {
|
|||||||
return getCredDef(type) !== undefined;
|
return getCredDef(type) !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function restPOST(type) {
|
|
||||||
redApp.post('/credentials/' + type + '/:id', function (req, res) {
|
|
||||||
var body = "";
|
|
||||||
req.on('data', function (chunk) {
|
|
||||||
body += chunk;
|
|
||||||
});
|
|
||||||
req.on('end', function () {
|
|
||||||
var nodeType = type;
|
|
||||||
var nodeID = req.params.id;
|
|
||||||
|
|
||||||
var newCreds = querystring.parse(body);
|
|
||||||
var credentials = Credentials.get(nodeID) || {};
|
|
||||||
var definition = getCredDef(nodeType);
|
|
||||||
|
|
||||||
for (var cred in definition) {
|
|
||||||
if (definition.hasOwnProperty(cred)) {
|
|
||||||
if (newCreds[cred] === undefined) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (definition[cred].type == "password" && newCreds[cred] == '__PWRD__') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (newCreds[cred] === '') {
|
|
||||||
delete credentials[cred];
|
|
||||||
}
|
|
||||||
credentials[cred] = newCreds[cred];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Credentials.add(nodeID, credentials);
|
|
||||||
res.send(200);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function restGET(type) {
|
function restGET(type) {
|
||||||
redApp.get('/credentials/' + type + '/:id', function (req, res) {
|
redApp.get('/credentials/' + type + '/:id', function (req, res) {
|
||||||
var nodeType = type;
|
var nodeType = type;
|
||||||
@ -93,14 +60,6 @@ function restGET(type) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function restDELETE(type) {
|
|
||||||
redApp.delete('/credentials/' + type + '/:id', function (req, res) {
|
|
||||||
var nodeID = req.params.id;
|
|
||||||
|
|
||||||
Credentials.delete(nodeID);
|
|
||||||
res.send(200);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init: function (_storage) {
|
init: function (_storage) {
|
||||||
@ -148,8 +107,41 @@ module.exports = {
|
|||||||
register: function (type, definition) {
|
register: function (type, definition) {
|
||||||
var dashedType = type.replace(/\s+/g, '-');
|
var dashedType = type.replace(/\s+/g, '-');
|
||||||
credentialsDef[dashedType] = definition;
|
credentialsDef[dashedType] = definition;
|
||||||
restDELETE(dashedType);
|
|
||||||
restGET(dashedType);
|
restGET(dashedType);
|
||||||
restPOST(dashedType);
|
},
|
||||||
|
/**
|
||||||
|
* Merge the new credentials with the existings one
|
||||||
|
* @param nodeID
|
||||||
|
* @param nodeType
|
||||||
|
* @param newCreds
|
||||||
|
*/
|
||||||
|
merge: function (nodeID, nodeType, newCreds) {
|
||||||
|
var savedCredentials = Credentials.get(nodeID) || {};
|
||||||
|
|
||||||
|
if (!isRegistered(nodeType)) {
|
||||||
|
util.log('Credential Type ' + nodeType + ' is not registered.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var definition = getCredDef(nodeType);
|
||||||
|
for (var cred in definition) {
|
||||||
|
if (definition.hasOwnProperty(cred)) {
|
||||||
|
if (newCreds[cred] === undefined) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (definition[cred].type == "password" && newCreds[cred] == '__PWRD__') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (0 === newCreds[cred].length || /^\s*$/.test(newCreds[cred])) {
|
||||||
|
delete savedCredentials[cred];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
savedCredentials[cred] = newCreds[cred];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
credentials[nodeID] = savedCredentials;
|
||||||
|
},
|
||||||
|
save: function () {
|
||||||
|
return storage.saveCredentials(credentials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,26 @@ events.on('type-registered',function(type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
var parseCredentials = function (config) {
|
||||||
|
return when.promise(function (resolve, defect) {
|
||||||
|
for (var i in config) {
|
||||||
|
if (config.hasOwnProperty(i)) {
|
||||||
|
var node = config[i];
|
||||||
|
if (!node._creds) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var type = node.type;
|
||||||
|
credentials.merge(node.id, type, node._creds);
|
||||||
|
delete node._creds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
credentials.save().then(function () {
|
||||||
|
resolve(config);
|
||||||
|
}).otherwise(function (err) {
|
||||||
|
defect(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var parseConfig = function() {
|
var parseConfig = function() {
|
||||||
var i;
|
var i;
|
||||||
@ -155,13 +174,16 @@ var flowNodes = module.exports = {
|
|||||||
getFlows: function() {
|
getFlows: function() {
|
||||||
return activeConfig;
|
return activeConfig;
|
||||||
},
|
},
|
||||||
setFlows: function(conf) {
|
setFlows: function (conf) {
|
||||||
return storage.saveFlows(conf).then(function() {
|
return parseCredentials(conf).then(function (confCredsRemoved) {
|
||||||
return stopFlows().then(function() {
|
return storage.saveFlows(confCredsRemoved).then(function () {
|
||||||
activeConfig = conf;
|
return stopFlows().then(function () {
|
||||||
parseConfig();
|
activeConfig = confCredsRemoved;
|
||||||
});
|
parseConfig();
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
},
|
},
|
||||||
stopFlows: stopFlows
|
stopFlows: stopFlows
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user