From b5d3f505e3e2779a14552ec0b5039e2057d823cd Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 31 May 2016 14:39:50 +0100 Subject: [PATCH] Defer loading of token sessions until they are accessed Fixes #895 --- red/api/auth/tokens.js | 74 +++++++++++++++++++------------- test/red/api/auth/tokens_spec.js | 29 ++++++------- 2 files changed, 56 insertions(+), 47 deletions(-) diff --git a/red/api/auth/tokens.js b/red/api/auth/tokens.js index 38a38a7c1..3faf4c392 100644 --- a/red/api/auth/tokens.js +++ b/red/api/auth/tokens.js @@ -32,6 +32,8 @@ var sessionExpiryTime var sessions = {}; +var loadedSessions = null; + function expireSessions() { var now = Date.now(); var modified = false; @@ -50,49 +52,61 @@ function expireSessions() { return when.resolve(); } } +function loadSessions() { + if (loadedSessions === null) { + loadedSessions = storage.getSessions().then(function(_sessions) { + sessions = _sessions||{}; + return expireSessions(); + }); + } + return loadedSessions; +} module.exports = { init: function(adminAuthSettings, _storage) { storage = _storage; - sessionExpiryTime = adminAuthSettings.sessionExpiryTime || 604800; // 1 week in seconds - - return storage.getSessions().then(function(_sessions) { - sessions = _sessions||{}; - return expireSessions(); - }); + // At this point, storage will not have been initialised, so defer loading + // the sessions until there's a request for them. + loadedSessions = null; + return when.resolve(); }, get: function(token) { - if (sessions[token]) { - if (sessions[token].expires < Date.now()) { - return expireSessions().then(function() { return null }); + return loadSessions().then(function() { + if (sessions[token]) { + if (sessions[token].expires < Date.now()) { + return expireSessions().then(function() { return null }); + } } - } - return when.resolve(sessions[token]); + return when.resolve(sessions[token]); + }); }, create: function(user,client,scope) { - var accessToken = generateToken(128); - - var accessTokenExpiresAt = Date.now() + (sessionExpiryTime*1000); - - var session = { - user:user, - client:client, - scope:scope, - accessToken: accessToken, - expires: accessTokenExpiresAt - }; - sessions[accessToken] = session; - return storage.saveSessions(sessions).then(function() { - return { + return loadSessions().then(function() { + var accessToken = generateToken(128); + + var accessTokenExpiresAt = Date.now() + (sessionExpiryTime*1000); + + var session = { + user:user, + client:client, + scope:scope, accessToken: accessToken, - expires_in: sessionExpiryTime - } + expires: accessTokenExpiresAt + }; + sessions[accessToken] = session; + return storage.saveSessions(sessions).then(function() { + return { + accessToken: accessToken, + expires_in: sessionExpiryTime + } + }); }); }, revoke: function(token) { - delete sessions[token]; - return storage.saveSessions(sessions); + return loadSessions().then(function() { + delete sessions[token]; + return storage.saveSessions(sessions); + }); } } - diff --git a/test/red/api/auth/tokens_spec.js b/test/red/api/auth/tokens_spec.js index b7496cde8..678d25ca5 100644 --- a/test/red/api/auth/tokens_spec.js +++ b/test/red/api/auth/tokens_spec.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ - + var should = require("should"); var when = require("when"); var sinon = require("sinon"); @@ -24,16 +24,11 @@ var Tokens = require("../../../../red/api/auth/tokens"); describe("Tokens", function() { describe("#init",function() { it('loads sessions', function(done) { - Tokens.init({},{ - getSessions:function() { - done(); - return when.resolve(); - } - }); + Tokens.init({}).then(done); }); }); - - + + describe("#get",function() { it('returns a valid token', function(done) { Tokens.init({},{ @@ -51,7 +46,7 @@ describe("Tokens", function() { }); }); }); - + it('returns null for an invalid token', function(done) { Tokens.init({},{ getSessions:function() { @@ -98,7 +93,7 @@ describe("Tokens", function() { }); }); }); - + describe("#create",function() { it('creates a token', function(done) { var savedSession; @@ -112,14 +107,14 @@ describe("Tokens", function() { } }); var expectedExpiryTime = Date.now()+10000; - - + + Tokens.create("user","client","scope").then(function(token) { try { should.exist(savedSession); var sessionKeys = Object.keys(savedSession); sessionKeys.should.have.lengthOf(1); - + token.should.have.a.property('accessToken',sessionKeys[0]); savedSession[sessionKeys[0]].should.have.a.property('user','user'); savedSession[sessionKeys[0]].should.have.a.property('client','client'); @@ -133,7 +128,7 @@ describe("Tokens", function() { }); }); }); - + describe("#revoke", function() { it('revokes a token', function(done) { var savedSession; @@ -157,5 +152,5 @@ describe("Tokens", function() { }); }); }); - -}); \ No newline at end of file + +});