mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Move credential load/save storage functions under get/setFlows
This commit is contained in:
parent
e06cadd761
commit
f9b972349d
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014, 2015 IBM Corp.
|
* Copyright 2014, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -19,34 +19,40 @@ var when = require("when");
|
|||||||
var log = require("../log");
|
var log = require("../log");
|
||||||
|
|
||||||
var credentialCache = {};
|
var credentialCache = {};
|
||||||
var storage = null;
|
|
||||||
var credentialsDef = {};
|
var credentialsDef = {};
|
||||||
|
var dirty = false;
|
||||||
|
|
||||||
module.exports = {
|
var api = module.exports = {
|
||||||
init: function (_storage) {
|
init: function() {
|
||||||
storage = _storage;
|
dirty = false;
|
||||||
|
credentialCache = {};
|
||||||
|
credentialsDef = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the credentials from storage.
|
* Sets the credentials from storage.
|
||||||
*/
|
*/
|
||||||
load: function () {
|
load: function (credentials) {
|
||||||
return storage.getCredentials().then(function (creds) {
|
credentialCache = credentials;
|
||||||
credentialCache = creds;
|
dirty = false;
|
||||||
}).otherwise(function (err) {
|
return when.resolve();
|
||||||
log.warn(log._("nodes.credentials.error",{message: err}));
|
// return storage.getCredentials().then(function (creds) {
|
||||||
});
|
// credentialCache = creds;
|
||||||
|
// }).otherwise(function (err) {
|
||||||
|
// log.warn(log._("nodes.credentials.error",{message: err}));
|
||||||
|
// });
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a set of credentials for the given node id.
|
* Adds a set of credentials for the given node id.
|
||||||
* @param id the node id for the credentials
|
* @param id the node id for the credentials
|
||||||
* @param creds an object of credential key/value pairs
|
* @param creds an object of credential key/value pairs
|
||||||
* @return a promise for the saving of credentials to storage
|
* @return a promise for backwards compatibility TODO: can this be removed?
|
||||||
*/
|
*/
|
||||||
add: function (id, creds) {
|
add: function (id, creds) {
|
||||||
credentialCache[id] = creds;
|
credentialCache[id] = creds;
|
||||||
return storage.saveCredentials(credentialCache);
|
dirty = true;
|
||||||
|
return when.resolve();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +71,7 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
delete: function (id) {
|
delete: function (id) {
|
||||||
delete credentialCache[id];
|
delete credentialCache[id];
|
||||||
storage.saveCredentials(credentialCache);
|
dirty = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,6 +83,9 @@ module.exports = {
|
|||||||
var existingIds = {};
|
var existingIds = {};
|
||||||
config.forEach(function(n) {
|
config.forEach(function(n) {
|
||||||
existingIds[n.id] = true;
|
existingIds[n.id] = true;
|
||||||
|
if (n.credentials) {
|
||||||
|
api.extract(n);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
var deletedCredentials = false;
|
var deletedCredentials = false;
|
||||||
for (var c in credentialCache) {
|
for (var c in credentialCache) {
|
||||||
@ -88,10 +97,9 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (deletedCredentials) {
|
if (deletedCredentials) {
|
||||||
return storage.saveCredentials(credentialCache);
|
dirty = true;
|
||||||
} else {
|
|
||||||
return when.resolve();
|
|
||||||
}
|
}
|
||||||
|
return when.resolve();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,17 +154,10 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
credentialCache[nodeID] = savedCredentials;
|
credentialCache[nodeID] = savedCredentials;
|
||||||
|
dirty = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* Gets the credential definition for the given node type
|
||||||
* @param type the node type
|
* @param type the node type
|
||||||
@ -164,5 +165,14 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
getDefinition: function (type) {
|
getDefinition: function (type) {
|
||||||
return credentialsDef[type];
|
return credentialsDef[type];
|
||||||
|
},
|
||||||
|
|
||||||
|
dirty: function() {
|
||||||
|
return dirty;
|
||||||
|
},
|
||||||
|
|
||||||
|
export: function() {
|
||||||
|
dirty = false;
|
||||||
|
return when.resolve(credentialCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,9 +67,9 @@ function init(runtime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function load() {
|
function load() {
|
||||||
return storage.getFlows().then(function(flows) {
|
return storage.getFlows().then(function(config) {
|
||||||
return credentials.load().then(function() {
|
return credentials.load(config.credentials).then(function() {
|
||||||
return setConfig(flows,"load");
|
return setConfig(config.flows,"load");
|
||||||
});
|
});
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
log.warn(log._("nodes.flows.error",{message:err.toString()}));
|
log.warn(log._("nodes.flows.error",{message:err.toString()}));
|
||||||
@ -81,8 +81,6 @@ function setConfig(_config,type,muteLog) {
|
|||||||
var config = clone(_config);
|
var config = clone(_config);
|
||||||
type = type||"full";
|
type = type||"full";
|
||||||
|
|
||||||
var credentialsChanged = false;
|
|
||||||
var credentialSavePromise = null;
|
|
||||||
var configSavePromise = null;
|
var configSavePromise = null;
|
||||||
|
|
||||||
var diff;
|
var diff;
|
||||||
@ -90,23 +88,20 @@ function setConfig(_config,type,muteLog) {
|
|||||||
if (type !== 'full' && type !== 'load') {
|
if (type !== 'full' && type !== 'load') {
|
||||||
diff = flowUtil.diffConfigs(activeFlowConfig,newFlowConfig);
|
diff = flowUtil.diffConfigs(activeFlowConfig,newFlowConfig);
|
||||||
}
|
}
|
||||||
config.forEach(function(node) {
|
|
||||||
if (node.credentials) {
|
|
||||||
credentials.extract(node);
|
|
||||||
credentialsChanged = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (credentialsChanged) {
|
|
||||||
credentialSavePromise = credentials.save();
|
|
||||||
} else {
|
|
||||||
credentialSavePromise = when.resolve();
|
|
||||||
}
|
|
||||||
if (type === 'load') {
|
if (type === 'load') {
|
||||||
configSavePromise = credentialSavePromise;
|
|
||||||
type = 'full';
|
type = 'full';
|
||||||
|
configSavePromise = when.resolve();
|
||||||
} else {
|
} else {
|
||||||
configSavePromise = credentialSavePromise.then(function() {
|
credentials.clean(config);
|
||||||
return storage.saveFlows(config);
|
var credsDirty = credentials.dirty();
|
||||||
|
configSavePromise = credentials.export().then(function(creds) {
|
||||||
|
var saveConfig = {
|
||||||
|
flows: config,
|
||||||
|
credentialsDirty:credsDirty,
|
||||||
|
credentials: creds
|
||||||
|
}
|
||||||
|
storage.saveFlows(saveConfig);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,15 +109,13 @@ function setConfig(_config,type,muteLog) {
|
|||||||
.then(function() {
|
.then(function() {
|
||||||
activeConfig = config;
|
activeConfig = config;
|
||||||
activeFlowConfig = newFlowConfig;
|
activeFlowConfig = newFlowConfig;
|
||||||
return credentials.clean(activeConfig).then(function() {
|
if (started) {
|
||||||
if (started) {
|
return stop(type,diff,muteLog).then(function() {
|
||||||
return stop(type,diff,muteLog).then(function() {
|
context.clean(activeFlowConfig);
|
||||||
context.clean(activeFlowConfig);
|
start(type,diff,muteLog);
|
||||||
start(type,diff,muteLog);
|
}).otherwise(function(err) {
|
||||||
}).otherwise(function(err) {
|
})
|
||||||
})
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ function createNode(node,def) {
|
|||||||
|
|
||||||
function init(runtime) {
|
function init(runtime) {
|
||||||
settings = runtime.settings;
|
settings = runtime.settings;
|
||||||
credentials.init(runtime.storage);
|
credentials.init();
|
||||||
flows.init(runtime);
|
flows.init(runtime);
|
||||||
registry.init(runtime);
|
registry.init(runtime);
|
||||||
context.init(runtime.settings);
|
context.init(runtime.settings);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2013, 2015 IBM Corp.
|
* Copyright 2013, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -55,17 +55,35 @@ var storageModuleInterface = {
|
|||||||
return storageModule.init(runtime.settings);
|
return storageModule.init(runtime.settings);
|
||||||
},
|
},
|
||||||
getFlows: function() {
|
getFlows: function() {
|
||||||
return storageModule.getFlows();
|
return storageModule.getFlows().then(function(flows) {
|
||||||
|
return storageModule.getCredentials().then(function(creds) {
|
||||||
|
return {
|
||||||
|
flows: flows,
|
||||||
|
credentials: creds
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
},
|
},
|
||||||
saveFlows: function(flows) {
|
saveFlows: function(config) {
|
||||||
return storageModule.saveFlows(flows);
|
var flows = config.flows;
|
||||||
},
|
var credentials = config.credentials;
|
||||||
getCredentials: function() {
|
var credentialSavePromise;
|
||||||
return storageModule.getCredentials();
|
if (config.credentialsDirty) {
|
||||||
},
|
credentialSavePromise = storageModule.saveCredentials(credentials);
|
||||||
saveCredentials: function(credentials) {
|
} else {
|
||||||
return storageModule.saveCredentials(credentials);
|
credentialSavePromise = when.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentialSavePromise.then(function() {
|
||||||
|
return storageModule.saveFlows(flows);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
// getCredentials: function() {
|
||||||
|
// return storageModule.getCredentials();
|
||||||
|
// },
|
||||||
|
// saveCredentials: function(credentials) {
|
||||||
|
// return storageModule.saveCredentials(credentials);
|
||||||
|
// },
|
||||||
getSettings: function() {
|
getSettings: function() {
|
||||||
if (settingsAvailable) {
|
if (settingsAvailable) {
|
||||||
return storageModule.getSettings();
|
return storageModule.getSettings();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014, 2015 IBM Corp.
|
* Copyright 2014, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -19,34 +19,21 @@ var sinon = require("sinon");
|
|||||||
var when = require("when");
|
var when = require("when");
|
||||||
var util = require("util");
|
var util = require("util");
|
||||||
|
|
||||||
var express = require("express");
|
|
||||||
var request = require("supertest");
|
|
||||||
|
|
||||||
var index = require("../../../../red/runtime/nodes/index");
|
var index = require("../../../../red/runtime/nodes/index");
|
||||||
var credentials = require("../../../../red/runtime/nodes/credentials");
|
var credentials = require("../../../../red/runtime/nodes/credentials");
|
||||||
var log = require("../../../../red/runtime/log");
|
var log = require("../../../../red/runtime/log");
|
||||||
var auth = require("../../../../red/api/auth");
|
|
||||||
|
|
||||||
|
|
||||||
describe('Credentials', function() {
|
describe('red/runtime/nodes/credentials', function() {
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
index.clearRegistry();
|
index.clearRegistry();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loads from storage',function(done) {
|
it('loads provided credentials',function(done) {
|
||||||
|
credentials.init();
|
||||||
|
|
||||||
var storage = {
|
credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||||
getCredentials: function() {
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
resolve({"a":{"b":1,"c":2}});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
credentials.init(storage);
|
|
||||||
|
|
||||||
credentials.load().then(function() {
|
|
||||||
|
|
||||||
credentials.get("a").should.have.property('b',1);
|
credentials.get("a").should.have.property('b',1);
|
||||||
credentials.get("a").should.have.property('c',2);
|
credentials.get("a").should.have.property('c',2);
|
||||||
@ -54,182 +41,99 @@ describe('Credentials', function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('adds a new credential',function(done) {
|
||||||
it('saves to storage', function(done) {
|
credentials.init();
|
||||||
var storage = {
|
credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||||
saveCredentials: function(creds) {
|
credentials.dirty().should.be.false;
|
||||||
return when.resolve("saveCalled");
|
should.not.exist(credentials.get("b"));
|
||||||
}
|
credentials.add("b",{"foo":"bar"}).then(function() {
|
||||||
};
|
credentials.get("b").should.have.property("foo","bar");
|
||||||
credentials.init(storage);
|
credentials.dirty().should.be.true;
|
||||||
credentials.save().then(function(res) {
|
done();
|
||||||
res.should.equal("saveCalled");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('saves to storage when new cred added', function(done) {
|
|
||||||
var storage = {
|
|
||||||
getCredentials: function() {
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
resolve({"a":{"b":1,"c":2}});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveCredentials: function(creds) {
|
|
||||||
return when(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sinon.spy(storage,"saveCredentials");
|
|
||||||
credentials.init(storage);
|
|
||||||
credentials.load().then(function() {
|
|
||||||
should.not.exist(credentials.get("b"))
|
|
||||||
credentials.add('b',{"d":3});
|
|
||||||
storage.saveCredentials.callCount.should.be.exactly(1);
|
|
||||||
credentials.get("b").should.have.property('d',3);
|
|
||||||
storage.saveCredentials.restore();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('deletes from storage', function(done) {
|
|
||||||
var storage = {
|
|
||||||
getCredentials: function() {
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
resolve({"a":{"b":1,"c":2}});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveCredentials: function(creds) {
|
|
||||||
return when(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sinon.spy(storage,"saveCredentials");
|
|
||||||
credentials.init(storage);
|
|
||||||
credentials.load().then(function() {
|
|
||||||
should.exist(credentials.get("a"))
|
|
||||||
credentials.delete('a');
|
|
||||||
storage.saveCredentials.callCount.should.be.exactly(1);
|
|
||||||
should.not.exist(credentials.get("a"));
|
|
||||||
storage.saveCredentials.restore();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('clean up from storage', function(done) {
|
|
||||||
var storage = {
|
|
||||||
getCredentials: function() {
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
resolve({"a":{"b":1,"c":2}});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveCredentials: function(creds) {
|
|
||||||
return when(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sinon.spy(storage,"saveCredentials");
|
|
||||||
credentials.init(storage);
|
|
||||||
credentials.load().then(function() {
|
|
||||||
should.exist(credentials.get("a"));
|
|
||||||
credentials.clean([]);
|
|
||||||
storage.saveCredentials.callCount.should.be.exactly(1);
|
|
||||||
should.not.exist(credentials.get("a"));
|
|
||||||
storage.saveCredentials.restore();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('handle error loading from storage', function(done) {
|
|
||||||
var storage = {
|
|
||||||
getCredentials: function() {
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
reject("test forcing failure");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveCredentials: function(creds) {
|
|
||||||
return when(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var logmsg = 'nothing logged yet';
|
|
||||||
sinon.stub(log, 'warn', function(msg) {
|
|
||||||
logmsg = msg;
|
|
||||||
});
|
|
||||||
|
|
||||||
credentials.init(storage);
|
|
||||||
credentials.load().then(function() {
|
|
||||||
log.warn.calledOnce.should.be.true;
|
|
||||||
log.warn.restore();
|
|
||||||
done();
|
|
||||||
}).otherwise(function(err){
|
|
||||||
log.warn.restore();
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('credential type is not registered when extract', function(done) {
|
|
||||||
var testFlows = [{"type":"test","id":"tab1","label":"Sheet 1"}];
|
|
||||||
var storage = {
|
|
||||||
getFlows: function() {
|
|
||||||
var defer = when.defer();
|
|
||||||
defer.resolve(testFlows);
|
|
||||||
return defer.promise;
|
|
||||||
},
|
|
||||||
getCredentials: function() {
|
|
||||||
return when.promise(function(resolve,reject) {
|
|
||||||
resolve({"tab1":{"b":1,"c":2}});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
saveFlows: function(conf) {
|
|
||||||
var defer = when.defer();
|
|
||||||
defer.resolve();
|
|
||||||
should.deepEqual(testFlows, conf);
|
|
||||||
return defer.promise;
|
|
||||||
},
|
|
||||||
saveCredentials: function(creds) {
|
|
||||||
return when(true);
|
|
||||||
},
|
|
||||||
getSettings: function() {
|
|
||||||
return when({});
|
|
||||||
},
|
|
||||||
saveSettings: function(s) {
|
|
||||||
return when();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function TestNode(n) {
|
|
||||||
index.createNode(this, n);
|
|
||||||
|
|
||||||
this.id = 'tab1';
|
|
||||||
this.type = 'test';
|
|
||||||
this.name = 'barney';
|
|
||||||
var node = this;
|
|
||||||
|
|
||||||
this.on("log", function() {
|
|
||||||
// do nothing
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
var logmsg = 'nothing logged yet';
|
|
||||||
sinon.stub(log, 'warn', function(msg) {
|
|
||||||
logmsg = msg;
|
|
||||||
});
|
});
|
||||||
var settings = {
|
});
|
||||||
available: function() { return false;}
|
it('deletes an existing credential',function(done) {
|
||||||
}
|
credentials.init();
|
||||||
index.init({settings:settings, storage:storage});
|
credentials.load({"a":{"b":1,"c":2}}).then(function() {
|
||||||
index.registerType('test', TestNode);
|
credentials.dirty().should.be.false;
|
||||||
index.loadFlows().then(function() {
|
credentials.delete("a");
|
||||||
var testnode = new TestNode({id:'tab1',type:'test',name:'barney'});
|
should.not.exist(credentials.get("a"));
|
||||||
credentials.extract(testnode);
|
credentials.dirty().should.be.true;
|
||||||
log.warn.calledOnce.should.be.true;
|
|
||||||
log.warn.restore();
|
|
||||||
done();
|
done();
|
||||||
}).otherwise(function(err){
|
|
||||||
log.warn.restore();
|
|
||||||
done(err);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('extract and store credential updates in the provided node', function(done) {
|
it('exports the credentials, clearing dirty flag', function(done) {
|
||||||
credentials.init({saveCredentials:function(){}},express());
|
credentials.init();
|
||||||
credentials.register("test",{
|
var creds = {"a":{"b":1,"c":2}};
|
||||||
|
credentials.load(creds).then(function() {
|
||||||
|
credentials.add("b",{"foo":"bar"}).then(function() {
|
||||||
|
credentials.dirty().should.be.true;
|
||||||
|
credentials.export().then(function(exported) {
|
||||||
|
exported.should.eql(creds);
|
||||||
|
credentials.dirty().should.be.false;
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("#clean",function() {
|
||||||
|
it("removes credentials of unknown nodes",function(done) {
|
||||||
|
credentials.init();
|
||||||
|
var creds = {"a":{"b":1,"c":2},"b":{"d":3}};
|
||||||
|
credentials.load(creds).then(function() {
|
||||||
|
credentials.dirty().should.be.false;
|
||||||
|
should.exist(credentials.get("a"));
|
||||||
|
should.exist(credentials.get("b"));
|
||||||
|
credentials.clean([{id:"b"}]).then(function() {
|
||||||
|
credentials.dirty().should.be.true;
|
||||||
|
should.not.exist(credentials.get("a"));
|
||||||
|
should.exist(credentials.get("b"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("extracts credentials of known nodes",function(done) {
|
||||||
|
credentials.init();
|
||||||
|
credentials.register("testNode",{"b":"text","c":"password"})
|
||||||
|
var creds = {"a":{"b":1,"c":2}};
|
||||||
|
var newConfig = [{id:"a",type:"testNode",credentials:{"b":"newBValue","c":"newCValue"}}];
|
||||||
|
credentials.load(creds).then(function() {
|
||||||
|
credentials.dirty().should.be.false;
|
||||||
|
credentials.clean(newConfig).then(function() {
|
||||||
|
credentials.dirty().should.be.true;
|
||||||
|
credentials.get("a").should.have.property('b',"newBValue");
|
||||||
|
credentials.get("a").should.have.property('c',"newCValue");
|
||||||
|
should.not.exist(newConfig[0].credentials);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('warns if a node has no credential definition', function(done) {
|
||||||
|
credentials.init();
|
||||||
|
credentials.load({}).then(function() {
|
||||||
|
var node = {id:"node",type:"test",credentials:{
|
||||||
|
user1:"newUser",
|
||||||
|
password1:"newPassword"
|
||||||
|
}};
|
||||||
|
sinon.spy(log,"warn");
|
||||||
|
credentials.extract(node);
|
||||||
|
log.warn.called.should.be.true;
|
||||||
|
should.not.exist(node.credentials);
|
||||||
|
log.warn.restore();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
it('extract credential updates in the provided node', function(done) {
|
||||||
|
credentials.init();
|
||||||
|
var defintion = {
|
||||||
user1:{type:"text"},
|
user1:{type:"text"},
|
||||||
password1:{type:"password"},
|
password1:{type:"password"},
|
||||||
user2:{type:"text"},
|
user2:{type:"text"},
|
||||||
@ -237,28 +141,46 @@ describe('Credentials', function() {
|
|||||||
user3:{type:"text"},
|
user3:{type:"text"},
|
||||||
password3:{type:"password"}
|
password3:{type:"password"}
|
||||||
|
|
||||||
|
};
|
||||||
|
credentials.register("test",defintion);
|
||||||
|
var def = credentials.getDefinition("test");
|
||||||
|
defintion.should.eql(def);
|
||||||
|
|
||||||
|
credentials.load({"node":{user1:"abc",password1:"123",user2:"def",password2:"456",user3:"ghi",password3:"789"}}).then(function() {
|
||||||
|
var node = {id:"node",type:"test",credentials:{
|
||||||
|
// user1 unchanged
|
||||||
|
password1:"__PWRD__",
|
||||||
|
user2: "",
|
||||||
|
password2:" ",
|
||||||
|
user3:"newUser",
|
||||||
|
password3:"newPassword"
|
||||||
|
}};
|
||||||
|
credentials.dirty().should.be.false;
|
||||||
|
credentials.extract(node);
|
||||||
|
|
||||||
|
node.should.not.have.a.property("credentials");
|
||||||
|
|
||||||
|
credentials.dirty().should.be.true;
|
||||||
|
var newCreds = credentials.get("node");
|
||||||
|
newCreds.should.have.a.property("user1","abc");
|
||||||
|
newCreds.should.have.a.property("password1","123");
|
||||||
|
newCreds.should.not.have.a.property("user2");
|
||||||
|
newCreds.should.not.have.a.property("password2");
|
||||||
|
newCreds.should.have.a.property("user3","newUser");
|
||||||
|
newCreds.should.have.a.property("password3","newPassword");
|
||||||
|
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
credentials.add("node",{user1:"abc",password1:"123",user2:"def",password2:"456",user3:"ghi",password3:"789"});
|
});
|
||||||
var node = {id:"node",type:"test",credentials:{
|
it('extract ignores node without credentials', function(done) {
|
||||||
// user1 unchanged
|
credentials.init();
|
||||||
password1:"__PWRD__",
|
credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() {
|
||||||
user2: "",
|
var node = {id:"node",type:"test"};
|
||||||
password2:" ",
|
|
||||||
user3:"newUser",
|
|
||||||
password3:"newPassword"
|
|
||||||
}};
|
|
||||||
credentials.extract(node);
|
|
||||||
|
|
||||||
node.should.not.have.a.property("credentials");
|
credentials.dirty().should.be.false;
|
||||||
|
credentials.extract(node);
|
||||||
var newCreds = credentials.get("node");
|
credentials.dirty().should.be.false;
|
||||||
newCreds.should.have.a.property("user1","abc");
|
done();
|
||||||
newCreds.should.have.a.property("password1","123");
|
});
|
||||||
newCreds.should.not.have.a.property("user2");
|
|
||||||
newCreds.should.not.have.a.property("password2");
|
|
||||||
newCreds.should.have.a.property("user3","newUser");
|
|
||||||
newCreds.should.have.a.property("password3","newPassword");
|
|
||||||
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014, 2015 IBM Corp.
|
* Copyright 2014, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -30,8 +30,6 @@ describe('flows/index', function() {
|
|||||||
|
|
||||||
var storage;
|
var storage;
|
||||||
var eventsOn;
|
var eventsOn;
|
||||||
var credentialsExtract;
|
|
||||||
var credentialsSave;
|
|
||||||
var credentialsClean;
|
var credentialsClean;
|
||||||
var credentialsLoad;
|
var credentialsLoad;
|
||||||
|
|
||||||
@ -50,13 +48,10 @@ describe('flows/index', function() {
|
|||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
eventsOn = sinon.spy(events,"on");
|
eventsOn = sinon.spy(events,"on");
|
||||||
credentialsExtract = sinon.stub(credentials,"extract",function(conf) {
|
|
||||||
delete conf.credentials;
|
|
||||||
});
|
|
||||||
credentialsSave = sinon.stub(credentials,"save",function() {
|
|
||||||
return when.resolve();
|
|
||||||
});
|
|
||||||
credentialsClean = sinon.stub(credentials,"clean",function(conf) {
|
credentialsClean = sinon.stub(credentials,"clean",function(conf) {
|
||||||
|
conf.forEach(function(n) {
|
||||||
|
delete n.credentials;
|
||||||
|
});
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
});
|
});
|
||||||
credentialsLoad = sinon.stub(credentials,"load",function() {
|
credentialsLoad = sinon.stub(credentials,"load",function() {
|
||||||
@ -97,8 +92,6 @@ describe('flows/index', function() {
|
|||||||
|
|
||||||
afterEach(function(done) {
|
afterEach(function(done) {
|
||||||
eventsOn.restore();
|
eventsOn.restore();
|
||||||
credentialsExtract.restore();
|
|
||||||
credentialsSave.restore();
|
|
||||||
credentialsClean.restore();
|
credentialsClean.restore();
|
||||||
credentialsLoad.restore();
|
credentialsLoad.restore();
|
||||||
flowCreate.restore();
|
flowCreate.restore();
|
||||||
@ -121,7 +114,6 @@ describe('flows/index', function() {
|
|||||||
];
|
];
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
flows.setFlows(originalConfig).then(function() {
|
flows.setFlows(originalConfig).then(function() {
|
||||||
credentialsExtract.called.should.be.false;
|
|
||||||
credentialsClean.called.should.be.true;
|
credentialsClean.called.should.be.true;
|
||||||
storage.hasOwnProperty('conf').should.be.true;
|
storage.hasOwnProperty('conf').should.be.true;
|
||||||
flows.getFlows().should.eql(originalConfig);
|
flows.getFlows().should.eql(originalConfig);
|
||||||
@ -136,8 +128,7 @@ describe('flows/index', function() {
|
|||||||
];
|
];
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
flows.setFlows(originalConfig,"load").then(function() {
|
flows.setFlows(originalConfig,"load").then(function() {
|
||||||
credentialsExtract.called.should.be.false;
|
credentialsClean.called.should.be.false;
|
||||||
credentialsClean.called.should.be.true;
|
|
||||||
// 'load' type does not trigger a save
|
// 'load' type does not trigger a save
|
||||||
storage.hasOwnProperty('conf').should.be.false;
|
storage.hasOwnProperty('conf').should.be.false;
|
||||||
flows.getFlows().should.eql(originalConfig);
|
flows.getFlows().should.eql(originalConfig);
|
||||||
@ -148,18 +139,17 @@ describe('flows/index', function() {
|
|||||||
|
|
||||||
it('extracts credentials from the full flow', function(done) {
|
it('extracts credentials from the full flow', function(done) {
|
||||||
var originalConfig = [
|
var originalConfig = [
|
||||||
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[],credentials:{}},
|
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[],credentials:{"a":1}},
|
||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
flows.setFlows(originalConfig).then(function() {
|
flows.setFlows(originalConfig).then(function() {
|
||||||
credentialsExtract.called.should.be.true;
|
|
||||||
credentialsClean.called.should.be.true;
|
credentialsClean.called.should.be.true;
|
||||||
storage.hasOwnProperty('conf').should.be.true;
|
storage.hasOwnProperty('conf').should.be.true;
|
||||||
var cleanedFlows = flows.getFlows();
|
var cleanedFlows = flows.getFlows();
|
||||||
storage.conf.should.eql(cleanedFlows);
|
storage.conf.flows.should.eql(cleanedFlows);
|
||||||
cleanedFlows.should.not.eql(originalConfig);
|
cleanedFlows.should.not.eql(originalConfig);
|
||||||
cleanedFlows[0].credentials = {};
|
cleanedFlows[0].credentials = {"a":1};
|
||||||
cleanedFlows.should.eql(originalConfig);
|
cleanedFlows.should.eql(originalConfig);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@ -175,7 +165,7 @@ describe('flows/index', function() {
|
|||||||
newConfig.push({id:"t2",type:"tab"});
|
newConfig.push({id:"t2",type:"tab"});
|
||||||
newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]});
|
newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]});
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.once('nodes-started',function() {
|
events.once('nodes-started',function() {
|
||||||
@ -204,7 +194,7 @@ describe('flows/index', function() {
|
|||||||
newConfig.push({id:"t2",type:"tab"});
|
newConfig.push({id:"t2",type:"tab"});
|
||||||
newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]});
|
newConfig.push({id:"t2-1",x:10,y:10,z:"t2",type:"test",wires:[]});
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.once('nodes-started',function() {
|
events.once('nodes-started',function() {
|
||||||
@ -232,13 +222,11 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
flows.load().then(function() {
|
flows.load().then(function() {
|
||||||
credentialsExtract.called.should.be.false;
|
|
||||||
credentialsLoad.called.should.be.true;
|
credentialsLoad.called.should.be.true;
|
||||||
credentialsClean.called.should.be.true;
|
|
||||||
// 'load' type does not trigger a save
|
// 'load' type does not trigger a save
|
||||||
storage.hasOwnProperty('conf').should.be.false;
|
storage.hasOwnProperty('conf').should.be.false;
|
||||||
flows.getFlows().should.eql(originalConfig);
|
flows.getFlows().should.eql(originalConfig);
|
||||||
@ -254,7 +242,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.once('nodes-started',function() {
|
events.once('nodes-started',function() {
|
||||||
@ -274,7 +262,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
@ -293,7 +281,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
flows.load().then(function() {
|
flows.load().then(function() {
|
||||||
@ -316,7 +304,7 @@ describe('flows/index', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#get',function() {
|
describe.skip('#get',function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -327,7 +315,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
flows.load().then(function() {
|
flows.load().then(function() {
|
||||||
@ -351,7 +339,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.once('nodes-started',function() {
|
events.once('nodes-started',function() {
|
||||||
@ -376,7 +364,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]}
|
{id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.once('nodes-started',function() {
|
events.once('nodes-started',function() {
|
||||||
@ -404,7 +392,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.once('nodes-started',function() {
|
events.once('nodes-started',function() {
|
||||||
@ -430,7 +418,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]}
|
{id:"t3-1",x:10,y:10,z:"t3",type:"test",config:"configNode",wires:[]}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.once('nodes-started',function() {
|
events.once('nodes-started',function() {
|
||||||
@ -505,7 +493,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
flows.init({settings:{},storage:storage});
|
flows.init({settings:{},storage:storage});
|
||||||
flows.load().then(function() {
|
flows.load().then(function() {
|
||||||
@ -529,7 +517,7 @@ describe('flows/index', function() {
|
|||||||
{id:"t1",type:"tab"}
|
{id:"t1",type:"tab"}
|
||||||
];
|
];
|
||||||
storage.getFlows = function() {
|
storage.getFlows = function() {
|
||||||
return when.resolve(originalConfig);
|
return when.resolve({flows:originalConfig});
|
||||||
}
|
}
|
||||||
storage.setFlows = function() {
|
storage.setFlows = function() {
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014 IBM Corp.
|
* Copyright 2014, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -40,19 +40,13 @@ describe("red/nodes/index", function() {
|
|||||||
|
|
||||||
var testFlows = [{"type":"test","id":"tab1","label":"Sheet 1"}];
|
var testFlows = [{"type":"test","id":"tab1","label":"Sheet 1"}];
|
||||||
var storage = {
|
var storage = {
|
||||||
getFlows: function() {
|
getFlows: function() {
|
||||||
return when(testFlows);
|
return when({flows:testFlows,credentials:{"tab1":{"b":1,"c":2}}});
|
||||||
},
|
},
|
||||||
getCredentials: function() {
|
saveFlows: function(conf) {
|
||||||
return when({"tab1":{"b":1,"c":2}});
|
should.deepEqual(testFlows, conf.flows);
|
||||||
},
|
return when();
|
||||||
saveFlows: function(conf) {
|
}
|
||||||
should.deepEqual(testFlows, conf);
|
|
||||||
return when();
|
|
||||||
},
|
|
||||||
saveCredentials: function(creds) {
|
|
||||||
return when(true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var settings = {
|
var settings = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2014, 2015 IBM Corp.
|
* Copyright 2014, 2016 IBM Corp.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -75,12 +75,14 @@ describe("red/storage/index", function() {
|
|||||||
},
|
},
|
||||||
getFlows : function() {
|
getFlows : function() {
|
||||||
calledFlagGetFlows = true;
|
calledFlagGetFlows = true;
|
||||||
|
return when.resolve([]);
|
||||||
},
|
},
|
||||||
saveFlows : function (flows) {
|
saveFlows : function (flows) {
|
||||||
flows.should.be.true;
|
flows.should.be.true;
|
||||||
},
|
},
|
||||||
getCredentials : function() {
|
getCredentials : function() {
|
||||||
calledFlagGetCredentials = true;
|
calledFlagGetCredentials = true;
|
||||||
|
return when.resolve({});
|
||||||
},
|
},
|
||||||
saveCredentials : function(credentials) {
|
saveCredentials : function(credentials) {
|
||||||
credentials.should.be.true;
|
credentials.should.be.true;
|
||||||
@ -127,9 +129,7 @@ describe("red/storage/index", function() {
|
|||||||
|
|
||||||
storage.init(moduleToLoad);
|
storage.init(moduleToLoad);
|
||||||
storage.getFlows();
|
storage.getFlows();
|
||||||
storage.saveFlows(true);
|
storage.saveFlows({flows:[],credentials:{}});
|
||||||
storage.getCredentials();
|
|
||||||
storage.saveCredentials(true);
|
|
||||||
storage.getSettings();
|
storage.getSettings();
|
||||||
storage.saveSettings(true);
|
storage.saveSettings(true);
|
||||||
storage.getSessions();
|
storage.getSessions();
|
||||||
|
Loading…
Reference in New Issue
Block a user