diff options
Diffstat (limited to 'dgbuilder/red/nodes/credentials.js')
-rw-r--r-- | dgbuilder/red/nodes/credentials.js | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/dgbuilder/red/nodes/credentials.js b/dgbuilder/red/nodes/credentials.js new file mode 100644 index 00000000..22e78d81 --- /dev/null +++ b/dgbuilder/red/nodes/credentials.js @@ -0,0 +1,208 @@ +/** + * Copyright 2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var util = require("util"); +var when = require("when"); + +var credentialCache = {}; +var storage = null; +var credentialsDef = {}; +var redApp = null; + +/** + * Adds an HTTP endpoint to allow look up of credentials for a given node id. + */ +function registerEndpoint(type) { + redApp.get('/credentials/' + type + '/:id', function (req, res) { + // TODO: This could be a generic endpoint with the type value + // parameterised. + // + // TODO: It should verify the given node id is of the type specified - + // but that would add a dependency from this module to the + // registry module that knows about node types. + var nodeType = type; + var nodeID = req.params.id; + + var credentials = credentialCache[nodeID]; + if (credentials === undefined) { + res.json({}); + return; + } + var definition = credentialsDef[nodeType]; + + var sendCredentials = {}; + for (var cred in definition) { + if (definition.hasOwnProperty(cred)) { + if (definition[cred].type == "password") { + var key = 'has_' + cred; + sendCredentials[key] = credentials[cred] != null && credentials[cred] !== ''; + continue; + } + sendCredentials[cred] = credentials[cred] || ''; + } + } + res.json(sendCredentials); + + }); +} + + +module.exports = { + init: function (_storage) { + storage = _storage; + // TODO: this should get passed in init function call rather than + // required directly. + redApp = require("../server").app; + }, + + /** + * Loads the credentials from storage. + */ + load: function () { + return storage.getCredentials().then(function (creds) { + credentialCache = creds; + }).otherwise(function (err) { + util.log("[red] Error loading credentials : " + err); + }); + }, + + /** + * Adds a set of credentials for the given node id. + * @param id the node id for the credentials + * @param creds an object of credential key/value pairs + * @return a promise for the saving of credentials to storage + */ + add: function (id, creds) { + credentialCache[id] = creds; + return storage.saveCredentials(credentialCache); + }, + + /** + * Gets the credentials for the given node id. + * @param id the node id for the credentials + * @return the credentials + */ + get: function (id) { + return credentialCache[id]; + }, + + /** + * Deletes the credentials for the given node id. + * @param id the node id for the credentials + * @return a promise for the saving of credentials to storage + */ + delete: function (id) { + delete credentialCache[id]; + storage.saveCredentials(credentialCache); + }, + + /** + * Deletes any credentials for nodes that no longer exist + * @param getNode a function that can return a node for a given id + * @return a promise for the saving of credentials to storage + */ + clean: function (getNode) { + var deletedCredentials = false; + for (var c in credentialCache) { + if (credentialCache.hasOwnProperty(c)) { + var n = getNode(c); + if (!n) { + deletedCredentials = true; + delete credentialCache[c]; + } + } + } + if (deletedCredentials) { + return storage.saveCredentials(credentialCache); + } else { + return when.resolve(); + } + }, + + /** + * Registers a node credential definition. + * @param type the node type + * @param definition the credential definition + */ + register: function (type, definition) { + var dashedType = type.replace(/\s+/g, '-'); + credentialsDef[dashedType] = definition; + registerEndpoint(dashedType); + }, + + /** + * Extracts and stores any credential updates in the provided node. + * The provided node may have a .credentials property that contains + * new credentials for the node. + * This function loops through the credentials in the definition for + * the node-type and applies any of the updates provided in the node. + * + * This function does not save the credentials to disk as it is expected + * to be called multiple times when a new flow is deployed. + * + * @param node the node to extract credentials from + */ + extract: function(node) { + var nodeID = node.id; + var nodeType = node.type; + var newCreds = node.credentials; + if (newCreds) { + var savedCredentials = credentialCache[nodeID] || {}; + + var dashedType = nodeType.replace(/\s+/g, '-'); + var definition = credentialsDef[dashedType]; + + if (!definition) { + util.log('Credential Type ' + nodeType + ' is not registered.'); + return; + } + + 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]; + } + } + credentialCache[nodeID] = savedCredentials; + } + }, + + /** + * Saves the credentials to storage + * @return a promise for the saving of credentials to storage + */ + save: function () { + return storage.saveCredentials(credentialCache); + }, + + /** + * Gets the credential definition for the given node type + * @param type the node type + * @return the credential definition + */ + getDefinition: function (type) { + return credentialsDef[type]; + } +} |