Added bcrypt for password hashing

This commit is contained in:
Ritchie Martori 2013-07-15 14:07:17 -07:00
parent 3f7e4b693a
commit aa8d1bb853
4 changed files with 67 additions and 8 deletions

View File

@ -12,6 +12,20 @@
// Class level permissions
// blog posts
allow: ['owner', 'admin'] to: '*' // allow owner's of posts and admins to do anything
allow: '*' to: ['find', 'read'] // allow everyone to read and find
// comments
allow '*' to: ['find', 'read'] // read aka findById
allow 'user' to: ['create']
allow ['owner', 'admin'] to: '*'
// users only section
allow: '*' to: ['find', 'read', 'create']
allow: 'owner' to: ['*.destroy', '*.save']
// scopes
// URL level permissions
// URL level permissions

View File

@ -2,16 +2,21 @@
* Module Dependencies.
*/
var ModelBuilder = require('jugglingdb').ModelBuilder
var ModelBuilder = require('jugglingdb').ModelBuilder;
var modeler = new ModelBuilder();
/**
* Extends from the built in `asteroid.Model` type.
* Define the built in asteroid.Model.
*/
var Model = module.exports = modeler.define('model');
Model.shared = true;
/*!
* For **remoting**. Construct objects when calling instance methods remotely.
*/
Model.sharedCtor = function (data, id, fn) {
var ModelCtor = this;
@ -87,12 +92,17 @@ Model.afterRemote = function (name, fn) {
}
/*!
* Setup extended models.
* Called when a model is extended.
*/
Model.setup = function () {
var ModelCtor = this;
// each model has its
// own access control
// list
Model.acl = [];
ModelCtor.sharedCtor.accepts = [
{arg: 'data', type: 'object', http: {source: 'body'}},
{arg: 'id', type: 'any', http: {source: 'url'}}

View File

@ -5,7 +5,9 @@
var Model = require('../asteroid').Model
, asteroid = require('../asteroid')
, path = require('path')
, SALT_WORK_FACTOR = 10
, crypto = require('crypto')
, bcrypt = require('bcrypt')
, passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
@ -128,8 +130,14 @@ User.logout = function (sid, fn) {
*/
User.prototype.hasPassword = function (plain, fn) {
// TODO - bcrypt
fn(null, this.password === plain);
if(this.password && plain) {
bcrypt.compare(plain, this.password, function(err, isMatch) {
if(err) return fn(err);
fn(null, isMatch);
});
} else {
fn(null, false);
}
}
/**
@ -233,6 +241,11 @@ User.confirm = function (uid, token, redirect, fn) {
});
}
User.setter.password = function (plain) {
var salt = bcrypt.genSaltSync(this.constructor.settings.saltWorkFactor || SALT_WORK_FACTOR);
this._password = bcrypt.hashSync(plain, salt);
}
/**
* Setup an extended user model.
*/

View File

@ -162,11 +162,33 @@ describe('User', function(){
describe('user.hasPassword(plain, fn)', function(){
it('Determine if the password matches the stored password.', function(done) {
var u = new User({username: 'foo', password: 'bar'});
u.hasPassword('bar', function (err, isMatch) {
assert(isMatch, 'password doesnt match');
done();
});
});
});
it('should match a password after it is changed', function(done) {
User.create({email: 'foo@baz.net', username: 'bat', password: 'baz'}, function (err, user) {
User.findById(user.id, function (err, foundUser) {
assert(foundUser);
foundUser.hasPassword('baz', function (err, isMatch) {
assert(isMatch);
foundUser.password = 'baz2';
foundUser.save(function (err, updatedUser) {
updatedUser.hasPassword('baz2', function (err, isMatch) {
assert(isMatch);
User.findById(user.id, function (err, uu) {
uu.hasPassword('baz2', function (err, isMatch) {
assert(isMatch);
done();
});
});
});
});
});
});
});
});
});