From e62869b661220c0af6704307d779b5d28994bd52 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Thu, 6 Jul 2017 11:01:29 -0600 Subject: [PATCH] moved owner storage to a separate file --- lib/app.js | 55 ---------------------------------- lib/storage.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/worker.js | 11 +------ 3 files changed, 81 insertions(+), 65 deletions(-) create mode 100644 lib/storage.js diff --git a/lib/app.js b/lib/app.js index 235ca02..74c3d86 100644 --- a/lib/app.js +++ b/lib/app.js @@ -24,66 +24,11 @@ module.exports = function (myDeps, conf, overrideHttp) { require('../packages/assets/org.oauth3/oauth3.dns.js'); require('../packages/assets/org.oauth3/oauth3.tunnel.js'); OAUTH3._hooks = require('../packages/assets/org.oauth3/oauth3.node.storage.js'); - var fs = PromiseA.promisifyAll(require('fs')); - var ownersPath = path.join(__dirname, '..', 'var', 'owners.json'); - var scmp = require('scmp'); request = request || PromiseA.promisify(require('request')); - var owners = { - all: function () { - var owners; - try { - owners = require(ownersPath); - } catch(e) { - owners = {}; - } - - return PromiseA.resolve(Object.keys(owners).map(function (key) { - var owner = owners[key]; - owner.id = key; - return owner; - })); - } - , get: function (id) { - var me = this; - - return me.all().then(function (owners) { - return owners.filter(function (owner) { - return scmp(id, owner.id); - })[0]; - }); - } - , exists: function (id) { - var me = this; - - return me.get(id).then(function (owner) { - return !!owner; - }); - } - , set: function (id, obj) { - var owners; - try { - owners = require(ownersPath); - } catch(e) { - owners = {}; - } - obj.id = id; - owners[id] = obj; - - return fs.mkdirAsync(path.dirname(ownersPath)).catch(function (err) { - if (err.code !== 'EEXIST') { - console.error('failed to mkdir', path.dirname(ownersPath), err.toString()); - } - }).then(function () { - return fs.writeFileAsync(ownersPath, JSON.stringify(owners), 'utf8'); - }); - } - }; - myDeps.PromiseA = PromiseA; myDeps.OAUTH3 = OAUTH3; - myDeps.storage = Object.assign({ owners: owners }, myDeps.storage); myDeps.recase = require('recase').create({}); myDeps.request = request; myDeps.api = { diff --git a/lib/storage.js b/lib/storage.js new file mode 100644 index 0000000..1b40922 --- /dev/null +++ b/lib/storage.js @@ -0,0 +1,80 @@ +'use strict'; + +var PromiseA = require('bluebird'); +var path = require('path'); +var fs = PromiseA.promisifyAll(require('fs')); + +module.exports.create = function (deps, conf) { + var scmp = require('scmp'); + var storageDir = path.join(__dirname, '..', 'var'); + + function read(fileName) { + return fs.readFileAsync(path.join(storageDir, fileName)) + .then(JSON.parse, function (err) { + if (err.code === 'ENOEXIST') { + return {}; + } + throw err; + }); + } + function write(fileName, obj) { + return fs.mkdirAsync(storageDir).catch(function (err) { + if (err.code !== 'EEXIST') { + console.error('failed to mkdir', storageDir, err.toString()); + } + }).then(function () { + return fs.writeFileAsync(path.join(storageDir, fileName), JSON.stringify(obj), 'utf8'); + }); + } + + var owners = { + _filename: 'owners.json' + , all: function () { + return read(this._filename).then(function (owners) { + return Object.keys(owners).map(function (id) { + var owner = owners[id]; + owner.id = id; + return owner; + }); + }); + } + , get: function (id) { + // While we could directly read the owners file and access the id directly from + // the resulting object I'm not sure of the details of how the object key lookup + // works or whether that would expose us to timing attacks. + // See https://codahale.com/a-lesson-in-timing-attacks/ + return this.all().then(function (owners) { + return owners.filter(function (owner) { + return scmp(id, owner.id); + })[0]; + }); + } + , exists: function (id) { + return this.get(id).then(function (owner) { + return !!owner; + }); + } + , set: function (id, obj) { + var self = this; + return read(self._filename).then(function (owners) { + obj.id = id; + owners[id] = obj; + return write(self._filename, owners); + }); + } + }; + + var config = { + save: function (changes) { + deps.messenger.send({ + type: 'com.daplie.goldilocks.config-change' + , changes: changes + }); + } + }; + + return { + owners: owners + , config: config + }; +}; diff --git a/lib/worker.js b/lib/worker.js index 5fb9764..b235e8d 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -27,17 +27,8 @@ function create(conf) { // HTTP proxying connection creation is not something we currently control. , net: require('net') }; + deps.storage = require('./storage').create(deps, conf); deps.proxy = require('./proxy-conn').create(deps, conf); - deps.storage = { - config: { - save: function (changes) { - process.send({ - type: 'com.daplie.goldilocks.config-change' - , changes: changes - }); - } - } - }; require('./goldilocks.js').create(deps, conf); process.removeListener('message', create);