Skip to content
This repository has been archived by the owner on Aug 30, 2021. It is now read-only.

Commit

Permalink
Merge pull request #937 from lirantal/feature/seeddb-refactoring
Browse files Browse the repository at this point in the history
SeedDB Refactoring
  • Loading branch information
lirantal committed Sep 30, 2015
2 parents cc80930 + 6f8b5bf commit 7fcd4f2
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 77 deletions.
17 changes: 10 additions & 7 deletions config/lib/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
var config = require('../config'),
mongoose = require('./mongoose'),
express = require('./express'),
chalk = require('chalk');
chalk = require('chalk'),
seed = require('./seed');

function seedDB() {
if (config.seedDB) {
console.log(chalk.bold.red('Warning: Database seeding is turned on'));
seed.start();
}
}

// Initialize Models
mongoose.loadModels();

//SeedDB
if (config.seedDB) {
require('./seed');
}
mongoose.loadModels(seedDB);

module.exports.loadModels = function loadModels() {
mongoose.loadModels();
Expand Down
4 changes: 3 additions & 1 deletion config/lib/mongoose.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ var config = require('../config'),
mongoose = require('mongoose');

// Load the mongoose models
module.exports.loadModels = function () {
module.exports.loadModels = function (callback) {
// Globbing model files
config.files.server.models.forEach(function (modelPath) {
require(path.resolve(modelPath));
});

if (callback) callback();
};

// Initialize Mongoose
Expand Down
189 changes: 121 additions & 68 deletions config/lib/seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,93 +2,146 @@

var mongoose = require('mongoose'),
chalk = require('chalk'),
crypto = require('crypto'),
User = mongoose.model('User');
crypto = require('crypto');

console.log(chalk.bold.red('Warning: Database seeding is turned on'));

var seedUser = {
username: 'user',
password: 'User_Password1!',
provider: 'local',
email: '[email protected]',
firstName: 'User',
lastName: 'Local',
displayName: 'User Local',
roles: ['user']
};

var seedAdmin = {
username: 'admin',
password: 'Admin_Password1!',
provider: 'local',
email: '[email protected]',
firstName: 'Admin',
lastName: 'Local',
displayName: 'Admin Local',
roles: ['user', 'admin']
};

//If production only seed admin if it does not exist
if (process.env.NODE_ENV === 'production') {
//Add Local Admin
User.find({username: seedAdmin.username}, function (err, users) {
if (users.length === 0) {
var user = new User(seedAdmin);

// generate a random password and save
User.generateRandomPassphrase()
.then(saveUser(user))
.catch(reportError);

} else {
console.log(seedAdmin.username + ' user exists');
}
function removeUser (user) {
return new Promise(function (resolve, reject) {
var User = mongoose.model('User');
User.find({username: user.username}).remove(function (err) {
if (err) {
reject(new Error('Database Seeding:\t\t\tFailed to remove local ' + user.username));
}
resolve();
});
});
} else {

//Add Local User
User.find({username: seedUser.username}).remove(function () {
var user = new User(seedUser);
}

// generate a random password and save
User.generateRandomPassphrase()
.then(saveUser(user))
.catch(reportError);
});
function saveUser (user) {
return function() {
return new Promise(function (resolve, reject) {
// Then save the user
user.save(function (err, theuser) {
if (err) {
reject(new Error('Database Seeding:\t\t\tFailed to add local ' + user.username));
} else {
resolve(theuser);
}
});
});
};
}

//Add Local Admin
User.find({username: seedAdmin.username}).remove(function () {
var user = new User(seedAdmin);
function checkUserNotExists (user) {
return new Promise(function (resolve, reject) {
var User = mongoose.model('User');
User.find({username: user.username}, function (err, users) {
if (err) {
reject(new Error('Database Seeding:\t\t\tFailed to find local account ' + user.username));
}

// generate a random password and save
User.generateRandomPassphrase()
.then(saveUser(user))
.catch(reportError);
if (users.length === 0) {
resolve();
} else {
reject(new Error('Database Seeding:\t\t\tFailed due to local account already exists: ' + user.username));
}
});
});
}

function reportSuccess (password) {
return function (user) {
return new Promise(function (resolve, reject) {
console.log(chalk.bold.red('Database Seeding:\t\t\tLocal ' + user.username + ' added with password set to ' + password));
resolve();
});
};
}

// save the specified user with the password provided from the resolved promise
function saveUser(user) {
function seedTheUser (user) {
return function (password) {
// set the new password
user.password = password;
return new Promise(function (resolve, reject) {

var User = mongoose.model('User');
// set the new password
user.password = password;

// Then save the user
user.save(function (err) {
if (err) {
console.log('Database Seeding:\t\t\tFailed to add local ' + user.username);
if (user.username === 'admin' && process.env.NODE_ENV === 'production') {
checkUserNotExists(user)
.then(saveUser(user))
.then(reportSuccess(password))
.then(function () {
resolve();
})
.catch(reportError);
} else {
console.log(chalk.bold.red('Database Seeding:\t\t\tLocal ' + user.username + ' added with password set to ' + password));
removeUser(user)
.then(saveUser(user))
.then(reportSuccess(password))
.then(function () {
resolve();
})
.catch(reportError);
}
});
};
}

// report the error
function reportError(err) {
function reportError (err) {
console.log();
console.log('Database Seeding:\t\t\t Failed to generate random password');
console.log(err);
console.log();
}

module.exports.start = function start() {
var User = mongoose.model('User');
return new Promise(function (resolve, reject) {
var seedUser = {
username: 'user',
password: 'User_Password1!',
provider: 'local',
email: '[email protected]',
firstName: 'User',
lastName: 'Local',
displayName: 'User Local',
roles: ['user']
};

var seedAdmin = {
username: 'admin',
password: 'Admin_Password1!',
provider: 'local',
email: '[email protected]',
firstName: 'Admin',
lastName: 'Local',
displayName: 'Admin Local',
roles: ['user', 'admin']
};

var user = null;
var adminAccount = new User(seedAdmin);
var userAccount = new User(seedUser);

//If production only seed admin if it does not exist
if (process.env.NODE_ENV === 'production') {
User.generateRandomPassphrase()
.then(seedTheUser(adminAccount))
.then(function () {
resolve();
})
.catch(reportError);
} else {
// Add both Admin and User account

User.generateRandomPassphrase()
.then(seedTheUser(userAccount))
.then(User.generateRandomPassphrase)
.then(seedTheUser(adminAccount))
.then(function () {
resolve();
})
.catch(reportError);
}
});
};
123 changes: 123 additions & 0 deletions modules/core/tests/server/core.server.config.tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
'use strict';

/**
* Module dependencies.
*/
var should = require('should'),
mongoose = require('mongoose'),
User = mongoose.model('User'),
path = require('path'),
config = require(path.resolve('./config/config')),
seed = require(path.resolve('./config/lib/seed'));

describe('Configuration tests', function () {

describe('Testing default seedDB:', function () {
before(function(done) {
User.remove(function(err) {
should.not.exist(err);
done();
});
});

after(function(done) {
User.remove(function(err) {
should.not.exist(err);
done();
});
});

it('should not be an admin user to begin with', function(done) {
User.find({username: 'admin'}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);
return done();
});
});

it('should not be a "regular" user to begin with', function(done) {
User.find({username: 'user'}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);
return done();
});
});

it('should set NODE_ENV to production and seedDB turned on so admin account must exist', function(done) {

// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'production';

User.find({username: 'admin'}, function(err, users) {

// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);

seed.start().then(function() {
User.find({username: 'admin'}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);

var admin = users.pop();
admin.username.should.equal('admin');

// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;

User.remove(function(err) {
should.not.exist(err);
return done();
});
});
});
});
});

it('should set NODE_ENV to test and seedDB turned on so admin, and user accounts must exist', function(done) {

// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'test';

User.find({username: 'admin'}, function(err, users) {

// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);

seed.start().then(function() {
User.find({username: 'admin'}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);

var admin = users.pop();
admin.username.should.equal('admin');

User.find({username: 'user'}, function(err, users) {

should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);

var user = users.pop();
user.username.should.equal('user');

// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;

User.remove(function(err) {
should.not.exist(err);
return done();
});
});
});
});
});
});

});

});
2 changes: 1 addition & 1 deletion modules/users/tests/server/user.server.model.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ describe('User Model Unit Tests:', function () {
should.not.exist(err);
});
})
.catch(function (err) {
.catch(function (err) {
should.not.exist(err);
});

Expand Down

0 comments on commit 7fcd4f2

Please sign in to comment.