function ProxyModel(mongoose) {

    var Schema = mongoose.Schema;
    // Validation helpers

    var validateNotEmpty = function (property) {
        return property && property.length > 0;
    };

    var validatePassword = function (pwd) {
        // validate the password length/complexity;
        // password must be 8+ characters
        // password must contain one upper case letter, one lower case letter, one digit, and one special character of !@#$%&*()
        var regExp = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%&*()]).{8,}/;
        return pwd && regExp.test(pwd);
    };

    // Schema definition
    var ProxyUserSchema = new Schema({
        // Username. Must be unique
        username: {
            type: String,
            unique: true,
            index: true,
            required: true
        },
        // Password at least 8 characters
        password: {
            type: String,
            default: '',
            validate: [validatePassword, 'Password should be at least 8 characters']
        },
        // Optional, true if user needs to reset password
        password_change_needed: {
            type: Boolean,
            default: false
        },
        // Salt used by password
        salt: {
            type: String
        },
        // User's email
        email: {
            type: String,
            trim: true,
            unique: true,
            default: '',
            validate: [validateNotEmpty, 'Please enter your email address'],
            match: [/.+\@.+\..+/, 'Please enter a valid email address']
        },
        // User's role
        roles: {
            type: [
                {
                    type: String,
                    enum: ['user', 'admin']
                }
            ],
            default: ['user']
        },
        // VM assigned to User
        vm_id: {
            type: String,
            default: ''
        },
        // IP of the VM
        vm_ip: {
            type: String,
            default: ''
        },
        // ID of the floating IP address (optional)
        vm_ip_id: {
            type: String,
            default: ''
        },
        // Volume ID
        volume_id: {
            type: String,
            default: ''
        },
        // User's device type
        device_type: {
            type: String,
            default: ''
        },
        // Account approved for use?
        approved: {
            type: Boolean,
            default: false
        },
        // When account created
        created: {
            type: Date,
            default: Date.now
        }
    });

    /**
     * Create hash of password
     * @param password
     * @returns {String}
     */
    ProxyUserSchema.methods.hashPassword = function (password) {
        var that = this;
        if (that.salt && password) {
            return crypto.pbkdf2Sync(password, that.salt, 10000, 64).toString('base64');
        } else {
            return password;
        }
    };

    /**
     * Save hook. Hash password on save IF password was changed
     */
    ProxyUserSchema.pre('save', function (next) {
        var that = this;

        if (that.isModified('password')) {
            // validated by validatePassword function
            that.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
            that.password = that.hashPassword(that.password);
        }
        next();
    });

    /**
     * Get the User's role
     * @returns {String} the role
     */
    ProxyUserSchema.methods.getRole = function () {
        return this.roles[0];
    };

    /**
     * Does the User have the admin role?
     * @returns {boolean} true if the user has the role 'admin'
     */
    ProxyUserSchema.methods.isAdmin = function () {
        return this.roles[0] === 'admin';
    };

    /**
     * Authenticate Password
     * @param password
     * @returns {boolean}
     */
    ProxyUserSchema.methods.authenticate = function (password) {
        return this.password === this.hashPassword(password);
    };


    /**
     * Finds a user wrapped in a promise
     * @param query = {username: 'some username'}
     * @returns {adapter.deferred.promise|*|promise|Promise.deferred.promise|Q.promise}
     */
    ProxyUserSchema.statics.findUserWithPromise = function (query) {
        var deferred = Q.defer();
        this.findOne(query, filtered_fields, function (err, user) {
            if (err) {
                deferred.reject(new Error("User '" + query.username + "' not found"));
            } else {
                deferred.resolve(user);
            }
        });
        return deferred.promise;
    };

    ProxyUserSchema.statics.updateUserWithPromise = function (user) {
        var deferred = Q.defer();
        user.save(function (err, updateduser) {
                if (updateduser) {
                    deferred.resolve(updateduser);
                } else {
                    deferred.reject(new Error('Failed updating user: ' + user.username));
                }
            }
        );
        return deferred.promise;
    };


    return mongoose.model('ProxyUser', ProxyUserSchema);
}
/**
 *  Define the ProxyUser functionality and Schema.
 *
 */
Define the ProxyUser functionality and Schema.
Define the ProxyUser functionality and Schema .
function ProxyModel(mongoose) {
    var Schema = mongoose.Schema;
    var validateNotEmpty = function (property) {
        return property && property.length > 0;
    };
    var validatePassword = function (pwd) {
        var regExp = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%&*()]).{8,}/;
        return pwd && regExp.test(pwd);
    };
    var ProxyUserSchema = new Schema({
        username: {
            type: String,
            unique: true,
            index: true,
            required: true
        },
        password: {
            type: String,
            default: '',
            validate: [validatePassword, 'Password should be at least 8 characters']
        },
        password_change_needed: {
            type: Boolean,
            default: false
        },
        salt: {
            type: String
        },
        email: {
            type: String,
            trim: true,
            unique: true,
            default: '',
            validate: [validateNotEmpty, 'Please enter your email address'],
            match: [/.+\@.+\..+/, 'Please enter a valid email address']
        },
        roles: {
            type: [
                {
                    type: String,
                    enum: ['user', 'admin']
                }
            ],
            default: ['user']
        },
        vm_id: {
            type: String,
            default: ''
        },
        vm_ip: {
            type: String,
            default: ''
        },
        vm_ip_id: {
            type: String,
            default: ''
        },
        volume_id: {
            type: String,
            default: ''
        },
        device_type: {
            type: String,
            default: ''
        },
        approved: {
            type: Boolean,
            default: false
        },
        created: {
            type: Date,
            default: Date.now
        }
    });
    ProxyUserSchema.methods.hashPassword = function (password) {
        var that = this;
        if (that.salt && password) {
            return crypto.pbkdf2Sync(password, that.salt, 10000, 64).toString('base64');
        } else {
            return password;
        }
    };
    ProxyUserSchema.pre('save', function (next) {
        var that = this;
        if (that.isModified('password')) {
            that.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
            that.password = that.hashPassword(that.password);
        }
        next();
    });
    ProxyUserSchema.methods.getRole = function () {
        return this.roles[0];
    };
    ProxyUserSchema.methods.isAdmin = function () {
        return this.roles[0] === 'admin';
    };
    ProxyUserSchema.methods.authenticate = function (password) {
        return this.password === this.hashPassword(password);
    };
    ProxyUserSchema.statics.findUserWithPromise = function (query) {
        var deferred = Q.defer();
        this.findOne(query, filtered_fields, function (err, user) {
            if (err) {
                deferred.reject(new Error("User '" + query.username + "' not found"));
            } else {
                deferred.resolve(user);
            }
        });
        return deferred.promise;
    };
    ProxyUserSchema.statics.updateUserWithPromise = function (user) {
        var deferred = Q.defer();
        user.save(function (err, updateduser) {
                if (updateduser) {
                    deferred.resolve(updateduser);
                } else {
                    deferred.reject(new Error('Failed updating user: ' + user.username));
                }
            }
        );
        return deferred.promise;
    };
    return mongoose.model('ProxyUser', ProxyUserSchema);
}
function ProxyModel ( mongoose ) { var Schema = mongoose . Schema ; var validateNotEmpty = function ( property ) { return property && property . length > 0 ; } ; var validatePassword = function ( pwd ) { var regExp = / (?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%&*()]).{8,} / ; return pwd && regExp . test ( pwd ) ; } ; var ProxyUserSchema = new Schema ( { username : { type : String , unique : true , index : true , required : true } , password : { type : String , default : '' , validate : [ validatePassword , 'Password should be at least 8 characters' ] } , password_change_needed : { type : Boolean , default : false } , salt : { type : String } , email : { type : String , trim : true , unique : true , default : '' , validate : [ validateNotEmpty , 'Please enter your email address' ] , match : [ / .+\@.+\..+ / , 'Please enter a valid email address' ] } , roles : { type : [ { type : String , enum : [ 'user' , 'admin' ] } ] , default : [ 'user' ] } , vm_id : { type : String , default : '' } , vm_ip : { type : String , default : '' } , vm_ip_id : { type : String , default : '' } , volume_id : { type : String , default : '' } , device_type : { type : String , default : '' } , approved : { type : Boolean , default : false } , created : { type : Date , default : Date . now } } ) ; ProxyUserSchema . methods . hashPassword = function ( password ) { var that = this ; if ( that . salt && password ) { return crypto . pbkdf2Sync ( password , that . salt , 10000 , 64 ) . toString ( 'base64' ) ; } else { return password ; } } ; ProxyUserSchema . pre ( 'save' , function ( next ) { var that = this ; if ( that . isModified ( 'password' ) ) { that . salt = new Buffer ( crypto . randomBytes ( 16 ) . toString ( 'base64' ) , 'base64' ) ; that . password = that . hashPassword ( that . password ) ; } next ( ) ; } ) ; ProxyUserSchema . methods . getRole = function ( ) { return this . roles [ 0 ] ; } ; ProxyUserSchema . methods . isAdmin = function ( ) { return this . roles [ 0 ] === 'admin' ; } ; ProxyUserSchema . methods . authenticate = function ( password ) { return this . password === this . hashPassword ( password ) ; } ; ProxyUserSchema . statics . findUserWithPromise = function ( query ) { var deferred = Q . defer ( ) ; this . findOne ( query , filtered_fields , function ( err , user ) { if ( err ) { deferred . reject ( new Error ( "User '" + query . username + "' not found" ) ) ; } else { deferred . resolve ( user ) ; } } ) ; return deferred . promise ; } ; ProxyUserSchema . statics . updateUserWithPromise = function ( user ) { var deferred = Q . defer ( ) ; user . save ( function ( err , updateduser ) { if ( updateduser ) { deferred . resolve ( updateduser ) ; } else { deferred . reject ( new Error ( 'Failed updating user: ' + user . username ) ) ; } } ) ; return deferred . promise ; } ; return mongoose . model ( 'ProxyUser' , ProxyUserSchema ) ; }
Define the ProxyUser functionality and Schema.
Define the ProxyUser functionality and Schema .
// Validation helpers // validate the password length/complexity; // password must be 8+ characters // password must contain one upper case letter, one lower case letter, one digit, and one special character of !@#$%&*() // Schema definition // Username. Must be unique // Password at least 8 characters // Optional, true if user needs to reset password // Salt used by password // User's email // User's role // VM assigned to User // IP of the VM // ID of the floating IP address (optional) // Volume ID // User's device type // Account approved for use? // When account created /**
     * Create hash of password
     * @param password
     * @returns {String}
     */ /**
     * Save hook. Hash password on save IF password was changed
     */ // validated by validatePassword function /**
     * Get the User's role
     * @returns {String} the role
     */ /**
     * Does the User have the admin role?
     * @returns {boolean} true if the user has the role 'admin'
     */ /**
     * Authenticate Password
     * @param password
     * @returns {boolean}
     */ /**
     * Finds a user wrapped in a promise
     * @param query = {username: 'some username'}
     * @returns {adapter.deferred.promise|*|promise|Promise.deferred.promise|Q.promise}
     */