[CCSDK-28] populated the seed code for dgbuilder
[ccsdk/distribution.git] / dgbuilder / red / nodes / credentials.js
diff --git a/dgbuilder/red/nodes/credentials.js b/dgbuilder/red/nodes/credentials.js
new file mode 100644 (file)
index 0000000..22e78d8
--- /dev/null
@@ -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];
+    }
+}