不要怂,就是干,撸起袖子干!

Commit e43b9db1 by Mick Hansen

add schema validation for strings (don't allow arrays and literal objects)

1 parent 0bfc4e31
...@@ -2,6 +2,8 @@ var Validator = require("validator") ...@@ -2,6 +2,8 @@ var Validator = require("validator")
, Utils = require("./utils") , Utils = require("./utils")
, sequelizeError = require("./errors") , sequelizeError = require("./errors")
, Promise = require("bluebird") , Promise = require("bluebird")
, DataTypes = require("./data-types")
, _ = require('lodash')
function noop() {} function noop() {}
...@@ -288,8 +290,7 @@ DaoValidator.prototype._builtinAttrValidate = function(value, field) { ...@@ -288,8 +290,7 @@ DaoValidator.prototype._builtinAttrValidate = function(value, field) {
* @return {Promise} A promise. * @return {Promise} A promise.
* @private * @private
*/ */
DaoValidator.prototype._invokeCustomValidator = Promise.method(function(validator, validatorType, DaoValidator.prototype._invokeCustomValidator = Promise.method(function(validator, validatorType, optAttrDefined, optValue, optField) {
optAttrDefined, optValue, optField) {
var validatorFunction = null // the validation function to call var validatorFunction = null // the validation function to call
var isAsync = false var isAsync = false
...@@ -333,8 +334,7 @@ DaoValidator.prototype._invokeCustomValidator = Promise.method(function(validato ...@@ -333,8 +334,7 @@ DaoValidator.prototype._invokeCustomValidator = Promise.method(function(validato
* @return {Object} An object with specific keys to invoke the validator. * @return {Object} An object with specific keys to invoke the validator.
* @private * @private
*/ */
DaoValidator.prototype._invokeBuiltinValidator = Promise.method(function(value, DaoValidator.prototype._invokeBuiltinValidator = Promise.method(function(value, test, validatorType, field) {
test, validatorType, field) {
// check if Validator knows that kind of validation test // check if Validator knows that kind of validation test
if (typeof Validator[validatorType] !== 'function') { if (typeof Validator[validatorType] !== 'function') {
...@@ -368,12 +368,11 @@ DaoValidator.prototype._invokeBuiltinValidator = Promise.method(function(value, ...@@ -368,12 +368,11 @@ DaoValidator.prototype._invokeBuiltinValidator = Promise.method(function(value,
* @param {*} value anything. * @param {*} value anything.
* @private * @private
*/ */
DaoValidator.prototype._validateSchema = function(rawAttribute, DaoValidator.prototype._validateSchema = function(rawAttribute, field, value) {
field, value) { var error
if (rawAttribute.allowNull === false && ((value === null) || if (rawAttribute.allowNull === false && ((value === null) || (value === undefined))) {
(value === undefined))) { error = new sequelizeError.ValidationError(field + ' cannot be null')
var error = new sequelizeError.ValidationError(field + ' cannot be null')
error.path = field error.path = field
error.value = value error.value = value
error.type = error.message = 'notNull Violation' error.type = error.message = 'notNull Violation'
...@@ -382,6 +381,19 @@ DaoValidator.prototype._validateSchema = function(rawAttribute, ...@@ -382,6 +381,19 @@ DaoValidator.prototype._validateSchema = function(rawAttribute,
} }
this.errors[field].push(error); this.errors[field].push(error);
} }
if (rawAttribute.type === DataTypes.STRING) {
if (Array.isArray(value) || (_.isObject(value) && !value._isSequelizeMethod)) {
error = new sequelizeError.ValidationError(field + ' cannot be an array or an object')
error.path = field
error.value = value
error.type = error.message = 'string violation'
if (!this.errors.hasOwnProperty(field)) {
this.errors[field] = [];
}
this.errors[field].push(error);
}
}
}; };
......
...@@ -560,6 +560,12 @@ var Utils = module.exports = { ...@@ -560,6 +560,12 @@ var Utils = module.exports = {
Utils.condition = Utils.where Utils.condition = Utils.where
Utils.where.prototype._isSequelizeMethod =
Utils.literal.prototype._isSequelizeMethod =
Utils.cast.prototype._isSequelizeMethod =
Utils.fn.prototype._isSequelizeMethod =
Utils.col.prototype._isSequelizeMethod = true
// I know this may seem silly, but this gives us the ability to recognize whether // I know this may seem silly, but this gives us the ability to recognize whether
// or not we should be escaping or if we should trust the user. Basically, it // or not we should be escaping or if we should trust the user. Basically, it
// keeps things in perspective and organized. // keeps things in perspective and organized.
......
...@@ -130,7 +130,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -130,7 +130,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
describe('create', function() { describe('create', function() {
it('works with non-integer primary keys', function (done) { it('works with non-integer primary keys with a default value', function (done) {
var User = this.sequelize.define('User', { var User = this.sequelize.define('User', {
'id': { 'id': {
primaryKey: true, primaryKey: true,
...@@ -297,9 +297,12 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -297,9 +297,12 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
} }
}) })
userWithDefaults.sync({force: true}).success(function () { userWithDefaults.sync({force: true}).done(function (err) {
userWithDefaults.create({}).success(function (user) { expect(err).not.to.be.ok
userWithDefaults.find(user.id).success(function (user) { userWithDefaults.create({}).done(function (err, user) {
expect(err).not.to.be.ok
userWithDefaults.find(user.id).done(function (err, user) {
expect(err).not.to.be.ok
var now = new Date() var now = new Date()
, pad = function (number) { , pad = function (number) {
if (number > 9) { if (number > 9) {
......
...@@ -162,10 +162,6 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -162,10 +162,6 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
fail: "22", fail: "22",
pass: "23" pass: "23"
} }
// , isArray: {
// fail: 22,
// pass: [22]
// }
, isCreditCard: { , isCreditCard: {
fail: "401288888888188f", fail: "401288888888188f",
pass: "4012888888881881" pass: "4012888888881881"
...@@ -196,7 +192,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -196,7 +192,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
var failingUser = UserFail.build({ name : failingValue }) var failingUser = UserFail.build({ name : failingValue })
failingUser.validate().done( function(err, _errors) { failingUser.validate().done( function(err, _errors) {
expect(_errors).to.not.be.null expect(_errors).not.to.be.null
expect(_errors).to.be.an.instanceOf(Error) expect(_errors).to.be.an.instanceOf(Error)
expect(_errors.name[0].message).to.equal(message) expect(_errors.name[0].message).to.equal(message)
done() done()
...@@ -239,8 +235,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -239,8 +235,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
var validatorDetails = checks[validator] var validatorDetails = checks[validator]
if (!validatorDetails.hasOwnProperty("raw")) { if (!validatorDetails.hasOwnProperty("raw")) {
validatorDetails.fail = [ validatorDetails.fail ] validatorDetails.fail = Array.isArray(validatorDetails.fail) ? validatorDetails.fail : [ validatorDetails.fail ]
validatorDetails.pass = [ validatorDetails.pass ] validatorDetails.pass = Array.isArray(validatorDetails.pass) ? validatorDetails.pass : [ validatorDetails.pass ]
} }
for (var i = 0; i < validatorDetails.fail.length; i++) { for (var i = 0; i < validatorDetails.fail.length; i++) {
...@@ -758,8 +754,53 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -758,8 +754,53 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
expect(user.getDataValue('name')).to.equal('RedCat') expect(user.getDataValue('name')).to.equal('RedCat')
user.setDataValue('name','YellowCat') user.setDataValue('name','YellowCat')
user.validate().done(function(errors){ user.validate().success(function(errors) {
expect(errors).to.be.null expect(errors).not.to.be.ok
done()
})
})
it('raises an error for array on a STRING', function (done) {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING
}
})
User.build({
email: ['iama', 'dummy.com']
}).validate().success(function (errors) {
expect(errors.email[0]).to.be.an.instanceof(Sequelize.ValidationError)
done()
})
})
it('raises an error for {} on a STRING', function (done) {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING
}
})
User.build({
email: {lol: true}
}).validate().success(function (errors) {
expect(errors.email[0]).to.be.an.instanceof(Sequelize.ValidationError)
done()
})
})
it('does not raise an error for null on a STRING (where null is allowed)', function (done) {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING
}
})
User.build({
email: null
}).validate().success(function (errors) {
expect(errors).not.to.be.ok
done() done()
}) })
}) })
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!