From 4b550e0c8780e6f0d7257ba492d412b4d0e03207 Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Thu, 13 Dec 2012 15:49:43 -0800 Subject: [PATCH 1/7] added root check to emit proxy --- lib/cluster.js | 35 +++++++++++++++++++++++++---------- lib/server.js | 16 +++++++--------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/lib/cluster.js b/lib/cluster.js index 12824ba..ec06fcb 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -103,19 +103,34 @@ Cluster.prototype.emitToUsers = function (uids, ev, data) { } Cluster.prototype.emitToServer = function(host, ev, data, sids) { - var body = { - event: ev, - data: data - }; + var cluster = this; - if(sids) { - body.sids = sids; + if(cluster.rootKey) { + emit(); + } else { + process.server.keys.getLocal(function (err, key) { + if(err) throw err; + cluster.rootKey = key; + emit(); + }); } - try { - request.post({url: 'http://' + host + '/__proxy', json: body}); - } catch(e) { - delete this.remotes[host]; + function emit() { + var headers = {'dpd-ssh-key': cluster.rootKey}; + var body = { + event: ev, + data: data + }; + + if(sids) { + body.sids = sids; + } + + try { + request.post({url: 'http://' + host + '/__proxy', headers: headers, json: body}); + } catch(e) { + delete cluster.remotes[host]; + } } } diff --git a/lib/server.js b/lib/server.js index a29d05d..3c18915 100644 --- a/lib/server.js +++ b/lib/server.js @@ -92,7 +92,7 @@ function Server(options) { setupReqRes(req, res, function(err, next) { if(err) return res.end(err.message); - sessionStore.createSession(req.cookies.get('sid'), function(err, session) { + sessionStore.createSession(req.headers['dpd-auth-token'] || req.cookies.get('sid'), function(err, session) { if(err) { debug('session error', err, session); @@ -103,6 +103,12 @@ function Server(options) { req.session = session; var route = function() { + // XXX - need to require root + if(req.url === '/__proxy' && req.isRoot) { + cluster.handleProxy(req, res); + return; + } + config.loadConfig(options.dir, server, function(err, results) { if (err) throw err; server.resources = results.resources; @@ -118,14 +124,6 @@ function Server(options) { var root = req.headers['dpd-ssh-key'] || req.cookies.get('DpdSshKey'); - // XXX - need to require root - if(req.url === '/__proxy') { - - cluster.handleProxy(req, res); - - return; - } - if (options.env === 'development') { if (root) { req.isRoot = true; } route(); From 55b3af1934065c5f5041f2187f974b3b29c05a01 Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Thu, 13 Dec 2012 20:05:21 -0800 Subject: [PATCH 2/7] added errorTemplate option --- lib/context.js | 8 +++++++- lib/router.js | 6 +++++- lib/server.js | 2 +- lib/start.js | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/context.js b/lib/context.js index 1617cd5..98bd05e 100644 --- a/lib/context.js +++ b/lib/context.js @@ -1,6 +1,7 @@ var internalClient = require('./internal-client') , debug = require('debug')('context') - , respond = require('doh').createResponder(); + , doh = require('doh') + , respond; /** * A `Context` gives access to a `req` and `res` object when passed to `resource.handle()`, @@ -21,6 +22,11 @@ var internalClient = require('./internal-client') function Context(resource, req, res, server) { var ctx = this; + + if(!respond) { + respond = doh.createResponder({template: server.options.errorTemplate}) + } + this.url = req.url.slice(resource.path.length).split('?')[0]; if (this.url.indexOf('/') !== 0) this.url = '/' + this.url; diff --git a/lib/router.js b/lib/router.js index ce5e4e4..f872068 100644 --- a/lib/router.js +++ b/lib/router.js @@ -3,7 +3,7 @@ var db = require('./db') , escapeRegExp = /[\-\[\]{}()+?.,\\\^$|#\s]/g , debug = require('debug')('router') , doh = require('doh') - , error404 = doh.createResponder() + , error404 , async = require('async'); /** @@ -15,6 +15,10 @@ var db = require('./db') */ function Router(resources, server) { + if(!error404) { + error404 = doh.createResponder({template: server.options.errorTemplate}); + } + this.resources = resources || []; this.server = server; } diff --git a/lib/server.js b/lib/server.js index 3c18915..48597b3 100644 --- a/lib/server.js +++ b/lib/server.js @@ -80,7 +80,7 @@ function Server(options) { var sessionStore = this.sessions = new SessionStore('sessions', this.db, this.sockets, cluster); // persist keys in a store - var keys = this.keys = new Keys(); + var keys = this.keys = new Keys(options.dir); this.on('request', function (req, res) { // dont handle socket.io requests diff --git a/lib/start.js b/lib/start.js index 0b97836..4af3061 100644 --- a/lib/start.js +++ b/lib/start.js @@ -12,7 +12,7 @@ var Server = require('./server') commands.start = function (config, fn) { var server = new Server(config); // TODO: Re-enable - // upgrade(server); + // upgrade(server, {template: server.options.errorTemplate}); server.on('listening', fn); server.on('error', fn); server.listen(); From 9fa8612936ab78eee810761f66038ca7811c993e Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Thu, 13 Dec 2012 20:31:12 -0800 Subject: [PATCH 3/7] added annonymous session cleanup at startup --- HISTORY.md | 30 ++++++++++++++++-------------- lib/session.js | 3 +++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index be38247..0ca7030 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,23 +3,25 @@ ## 0.7.0 ### New Features -- New utilities for extending Resource Types. - - Added `Resource.extend("ResourceName", { /* members */ })` syntax for extending Resources. The `init()` function is used as a constructor. The old `util.inherits()` syntax will continue to work. - - Moved `Resource` base class to the exports of the deployd module. You can now use `require('deployd').Resource` instead of `require('deployd/lib/resource')`. - - Added `get(ctx, next)`, `post(ctx, next)`, `put(ctx, next)`, and `del(ctx, next)` utility functions on `Resource`. You can now override those instead of `handle()`. -- New `Module` type in extension API - - Modules can define multiple Resource Types with `this.addResourceType()` - - [TODO] Modules can register their own dashboards. -- Added `dir` to server options - for booting in other directories than `process.cwd()`. -- Resources now support custom events by default -- New collection permission api + + - New utilities for extending Resource Types. + - Added `Resource.extend("ResourceName", { /* members */ })` syntax for extending Resources. The `init()` function is used as a constructor. The old `util.inherits()` syntax will continue to work. + - Moved `Resource` base class to the exports of the deployd module. You can now use `require('deployd').Resource` instead of `require('deployd/lib/resource')`. + - Added `get(ctx, next)`, `post(ctx, next)`, `put(ctx, next)`, and `del(ctx, next)` utility functions on `Resource`. You can now override those instead of `handle()`. + - New `Module` type in extension API + - Modules can define multiple Resource Types with `this.addResourceType()` + - [TODO] Modules can register their own dashboards. + - Added `dir` to server options - for booting in other directories than `process.cwd()`. + - Added `errorTemplate` to server options - for overriding the default error template. + - Resources now support custom events by default + - New collection permission api ### Breaking Changes -- Most configuration properties on the `Resource` class have been moved to the prototype: `external`, `events`, `basicDashboard`, and `dashboard`. - - The `label` and `defaultType` properties will remain on the constructor, as they shouldn't be inherited. -- The configuration option `Resource.events` has been renamed `Resource.eventNames`. - + - Most configuration properties on the `Resource` class have been moved to the prototype: `external`, `events`, `basicDashboard`, and `dashboard`. + - The `label` and `defaultType` properties will remain on the constructor, as they shouldn't be inherited. + - The configuration option `Resource.events` has been renamed `Resource.eventNames`. + - Anonymous sessions are now destroyed every time the server starts. ### Major Bugfixes diff --git a/lib/session.js b/lib/session.js index 36292fc..6ac4e39 100644 --- a/lib/session.js +++ b/lib/session.js @@ -41,6 +41,9 @@ function SessionStore(namespace, db, sockets) { } Store.apply(this, arguments); + + // clear annonymous sessions + this.remove({uid: {$exists: false}}); } util.inherits(SessionStore, Store); exports.SessionStore = SessionStore; From d7d03a3d7591b79268f6414464a79eaaae89c8e0 Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Mon, 17 Dec 2012 15:30:05 -0800 Subject: [PATCH 4/7] fixed connection queue when authenticating with db --- lib/db.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/db.js b/lib/db.js index d5f8a94..f49faaa 100644 --- a/lib/db.js +++ b/lib/db.js @@ -119,25 +119,26 @@ function getConnection(db, fn) { } else { db.connecting = true; db._mdb.open(function (err) { - db.connecting = false; - db.emit('connection attempted', err); if(err) { db.connected = false; throw err; } else { - // check for credentials var credentials = db.options.credentials; if (credentials && credentials.username && credentials.password) { db._mdb.authenticate(credentials.username, credentials.password, function (err) { + db.connecting = false; if (err) { db.connected = false; throw err; } db.connected = true; + db.emit('connection attempted', err); fn(null, db._mdb); }); } else { + db.connecting = false; + db.emit('connection attempted', err); db.connected = true; fn(null, db._mdb); } From 1f0848d5b9fff7fb2033abfb107d55922831260e Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Mon, 17 Dec 2012 15:49:03 -0800 Subject: [PATCH 5/7] added login/logout permissions --- lib/modules/user-collection.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/modules/user-collection.js b/lib/modules/user-collection.js index 96c82c2..ab48332 100644 --- a/lib/modules/user-collection.js +++ b/lib/modules/user-collection.js @@ -181,6 +181,30 @@ UserCollection.prototype.hash = function (password, salt) { return crypto.createHmac('sha256', salt).update(password).digest('hex'); }; +UserCollection.prototype.getRequiredPermissions = function (ctx) { + var requiredPermissions = Collection.prototype.getRequiredPermissions.apply(this, arguments); + + if(ctx.method === 'post' && ctx.url === '/login') { + requiredPermissions['login'] = true; + } + + if(ctx.method === 'post' && ctx.url === '/logout') { + requiredPermissions['logout'] = true; + } + + return requiredPermissions; +} + + +UserCollection.prototype.getDefaultPermissions = function (ctx) { + var defaultPermissions = Collection.prototype.getDefaultPermissions.apply(this, arguments); + + defaultPermissions['login'] = true; + defaultPermissions['logout'] = true; + + return defaultPermissions; +} + UserCollection.label = 'Users Collection'; UserCollection.defaultPath = '/users'; From 6e793dd863718530edc777516036231be6f7ea98 Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Mon, 17 Dec 2012 16:26:49 -0800 Subject: [PATCH 6/7] fixed missing keys.json --- lib/server.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index 48597b3..67248a7 100644 --- a/lib/server.js +++ b/lib/server.js @@ -10,6 +10,7 @@ var http = require('http') , setupReqRes = require('./util/http').setup , debug = require('debug')('server') , config = require('./config-loader') + , path = require('path') , Cluster = require('./cluster'); function extend(origin, add) { @@ -80,7 +81,7 @@ function Server(options) { var sessionStore = this.sessions = new SessionStore('sessions', this.db, this.sockets, cluster); // persist keys in a store - var keys = this.keys = new Keys(options.dir); + var keys = this.keys = new Keys(path.join(options.dir, '.dpd/keys.json')); this.on('request', function (req, res) { // dont handle socket.io requests From 97ce7db8c25f9a0bc005a3c6b8cc93f378044a64 Mon Sep 17 00:00:00 2001 From: Dallon Feldner Date: Wed, 19 Dec 2012 09:20:00 -0700 Subject: [PATCH 7/7] Fixed bug where custom resource events would not show up in the dashboard --- lib/internal-resources/internal-resources.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal-resources/internal-resources.js b/lib/internal-resources/internal-resources.js index dee6f8a..07f486f 100644 --- a/lib/internal-resources/internal-resources.js +++ b/lib/internal-resources/internal-resources.js @@ -63,7 +63,7 @@ InternalResources.prototype.handle = function(ctx, next) { var c = types[key] , pages = c.prototype.dashboard && c.prototype.dashboard.pages; - if (!pages && c.eventNames) { + if (!pages && c.prototype.eventNames) { pages = ['Config', 'Events']; } result[key] = {