summaryrefslogtreecommitdiffstats
path: root/dgbuilder/red/nodes/credentials.js
diff options
context:
space:
mode:
Diffstat (limited to 'dgbuilder/red/nodes/credentials.js')
-rw-r--r--dgbuilder/red/nodes/credentials.js208
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];
+ }
+}