Skip to content

Commit

Permalink
[865758] Added a database healthcheck middleware by refactoring the M…
Browse files Browse the repository at this point in the history
…ongoose handler and the user model, and modifying the architecture slightly to allow this new approach
  • Loading branch information
sedge committed Apr 30, 2013
1 parent 9729378 commit 8c9613e
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 162 deletions.
186 changes: 96 additions & 90 deletions app/http/controllers/user.js
Expand Up @@ -2,93 +2,99 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

var UserHandle = require( "../../models/user" ),
env = require('../../../config/environment');

exports.create = function ( req, res ) {
var userInfo = req.body;

userInfo._id = userInfo.email;

var user = new UserHandle( userInfo );

// Delegates all validation to mongoose during this step
user.save( function( err, thisUser ) {
if ( err ) {
res.json( 400, { error: err, user: null } );
return;
}

res.json( { error: null, user: thisUser } );
});
};

exports.get = function ( req, res ) {
var id = req.params.id;

UserHandle.findById( id, function ( err, user ) {
if ( err || !user ) {
res.json( 400, { error: err || "User not found for ID: " + id, user: null } );
return;
}

res.json( { error: null, user: user } );
});
};

exports.update = function ( req, res ) {
var userInfo = req.body,
id = req.params.id;

UserHandle.findByIdAndUpdate( id, userInfo, function ( err, user ) {
if ( err || !user ) {
res.json( 400, { error: err || "User not found for ID: " + id, user: null } );
return;
}

res.json( { error: null, user: user } );
});
};

exports.del = function ( req, res ) {
var id = req.params.id;

UserHandle.findByIdAndRemove( id , function ( err, user ) {
if ( err || !user ) {
res.json( 400, { error: err || "User not found for ID: " + id, user: null } );
return;
}

res.json( { error: null, user: user } );
});
};

exports.userForm = function( req, res ) {
res.render( 'ajax/forms/new_user', {
ssoAudience: env.get('AUDIENCE')
} );
};

/**
* Access this route from your browser to clear the database of accounts with the emails listed below.
* e.g. "http://localhost:3000/dev/delete"
*
* Obviously this should never go anywhere near production - but it's helpful for now, and at least for me
*/
exports.devDelete = function(req, res) {
var email = [
'ross@mozillafoundation.org',
'ross@ross-eats.co.uk',
'rossbruniges10@yahoo.co.uk',
'rossbruniges@gmail.com',
'kieran.sedgwick@gmail.com',
'kate@mozillafoundation.org'
],
User = require('../../models/user');

email.forEach(function(m) {
User.find({ email:m }).remove();
});

res.send("DELETED!!!");
};
var env = require("../../../config/environment");

module.exports = function ( UserHandle ) {
var controller = {};

controller.create = function ( req, res ) {
var userInfo = req.body;

userInfo._id = userInfo.email;

var user = new UserHandle( userInfo );

// Delegates all validation to mongoose during this step
user.save( function( err, thisUser ) {
if ( err ) {
res.json( 404, { error: err, user: null } );
return;
}

res.json( { error: null, user: thisUser } );
});
};

controller.get = function ( req, res ) {
var id = req.params.id;

UserHandle.findById( id, function ( err, user ) {
if ( err || !user ) {
res.json( 404, { error: err || "User not found for ID: " + id, user: null } );
return;
}

res.json( { error: null, user: user } );
});
};

controller.update = function ( req, res ) {
var userInfo = req.body,
id = req.params.id;

UserHandle.findByIdAndUpdate( id, userInfo, function ( err, user ) {
if ( err || !user ) {
res.json( 404, { error: err || "User not found for ID: " + id, user: null } );
return;
}

res.json( { error: null, user: user } );
});
};

controller.del = function ( req, res ) {
var id = req.params.id;

UserHandle.findByIdAndRemove( id , function ( err, user ) {
if ( err || !user ) {
res.json( 404, { error: err || "User not found for ID: " + id, user: null } );
return;
}

res.json( { error: null, user: user } );
});
};

controller.userForm = function( req, res ) {
res.render( "ajax/forms/new_user", {
ssoAudience: env.get('AUDIENCE')
} );
};

/**
* Access this route from your browser to clear the database of accounts with the emails listed below.
* e.g. "http://localhost:3000/dev/delete"
*
* Obviously this should never go anywhere near production.
* See bug: https://bugzilla.mozilla.org/show_bug.cgi?id=863781
*/
controller.devDelete = function( req, res ) {
var email = [
'ross@mozillafoundation.org',
'ross@ross-eats.co.uk',
'rossbruniges10@yahoo.co.uk',
'rossbruniges@gmail.com',
'kieran.sedgwick@gmail.com'
],
User = require('../../models/user');

email.forEach(function(m) {
User.find({ email:m }).remove();
});

res.send("DELETED!!!");
};

return controller;
}; // END Exports function

12 changes: 6 additions & 6 deletions app/http/routes.js
@@ -1,10 +1,9 @@
// HTTP Routes
routes = {
site: require('./controllers/site'),
user: require('./controllers/user')
};
module.exports = function( http, userHandle ){
routes = {
site: require('./controllers/site'),
user: require('./controllers/user')(userHandle)
};

module.exports = function(http){
http.get('/', routes.site.index);
http.get('/signin', routes.site.signin);
http.get('/js/sso.js', routes.site.sso);
Expand All @@ -24,3 +23,4 @@ module.exports = function(http){
http.get('/dev/delete', routes.user.devDelete);
http.get('/healthcheck', routes.site.healthcheck);
};

8 changes: 5 additions & 3 deletions app/http/server.js
Expand Up @@ -11,9 +11,10 @@ var express = require('express'),
logger = require('../../lib/logger'),
util = require('util'),
application = require('./controllers/application'),
User = require('../models/user'),
persona = require("express-persona"),
env = require('../../config/environment'),
mongo = require('../../lib/mongoose')(env),
User = require('../models/user')(mongo.conn),
persona = require("express-persona"),
route = require('./routes');

var http = express();
Expand All @@ -23,6 +24,7 @@ http.configure(function(){
http.set('views', __dirname + '/views');
http.set('view engine', 'ejs');
http.disable("x-powered-by");
http.use(mongo.healthCheck);
http.use(application.allowCorsRequests);
http.use(express.logger());
http.use(express.static(__dirname + '/public'));
Expand Down Expand Up @@ -86,7 +88,7 @@ process.on('uncaughtException', function(err) {
});

// HTTP Routes
route(http);
route( http, User );

var port = env.get('port');
http.listen(port);
Expand Down
1 change: 1 addition & 0 deletions app/http/views/js/sso.ejs
Expand Up @@ -137,3 +137,4 @@ navigator.personaSSO = {

}
};

1 change: 1 addition & 0 deletions app/http/views/site/signin.ejs
Expand Up @@ -103,3 +103,4 @@
<a href="#" id="signout" class="persona-button dark" style="display:none"><span>Sign out</span></a>
</body>
</html>

111 changes: 56 additions & 55 deletions app/models/user/user.js
@@ -1,7 +1,6 @@
var mongoose = require('../../../lib/mongoose.js'),
mongoose_validator = require('mongoose-validator');

// Custom validation
var mongoose_validator = require('mongoose-validator');

mongoose_validator.extend( 'isDomain', function () {
var str = this.str;

Expand All @@ -11,58 +10,60 @@ mongoose_validator.extend( 'isDomain', function () {
);
}, "Invalid name. All names must be between 1-20 characters, and only include \"-\", \"_\" and alphanumeric characters");

var validate = mongoose_validator.validate;
// Exports
module.exports = function ( connection ) {
var validate = mongoose_validator.validate;

var schema = new mongoose.Schema({
_id: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true,
validate: validate('isEmail')
},
name: {
type: String,
required: true,
unique: true,
validate: validate('isDomain')
},
createdAt: {
type: Date,
required: true,
"default": Date.now
},
updatedAt: {
type: Date,
required: true,
"default": Date.now
},
deletedAt:{
type: Date,
required: false
},
isAdmin: {
type: Boolean,
"default": false
},
isSuspended: {
type: Boolean,
"default": false
},
sendNotifications: {
type: Boolean,
"default": true
},
sendEngagements: {
type: Boolean,
"default": true
}
// TODO: Avatar support
});
var schema = new connection.Schema({
_id: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true,
validate: validate('isEmail')
},
name: {
type: String,
required: true,
unique: true,
validate: validate('isDomain')
},
createdAt: {
type: Date,
required: true,
"default": Date.now
},
updatedAt: {
type: Date,
required: true,
"default": Date.now
},
deletedAt:{
type: Date,
required: false
},
isAdmin: {
type: Boolean,
"default": false
},
isSuspended: {
type: Boolean,
"default": false
},
sendNotifications: {
type: Boolean,
"default": true
},
sendEngagements: {
type: Boolean,
"default": true
}
// TODO: Avatar support
});

var User = mongoose.model('User', schema);
return connection.model('User', schema);
};

module.exports = User;

0 comments on commit 8c9613e

Please sign in to comment.