Adds validation of addFields
This commit is contained in:
@@ -938,4 +938,62 @@ describe('schemas', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not be able to add a field', done => {
|
||||
request.post({
|
||||
url: 'http://localhost:8378/1/schemas/AClass',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
body: {
|
||||
classLevelPermissions: {
|
||||
find: {
|
||||
'*': true
|
||||
},
|
||||
addField: {
|
||||
'role:admin': true
|
||||
}
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
expect(error).toEqual(null);
|
||||
let object = new Parse.Object('AClass');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
fail('should not be able to add a field');
|
||||
done();
|
||||
}, (err) => {
|
||||
expect(err.message).toEqual('Permission denied for this action.');
|
||||
done();
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it('should not be able to add a field', done => {
|
||||
request.post({
|
||||
url: 'http://localhost:8378/1/schemas/AClass',
|
||||
headers: masterKeyHeaders,
|
||||
json: true,
|
||||
body: {
|
||||
classLevelPermissions: {
|
||||
find: {
|
||||
'*': true
|
||||
},
|
||||
addField: {
|
||||
'*': true
|
||||
}
|
||||
}
|
||||
}
|
||||
}, (error, response, body) => {
|
||||
expect(error).toEqual(null);
|
||||
let object = new Parse.Object('AClass');
|
||||
object.set('hello', 'world');
|
||||
return object.save().then(() => {
|
||||
done();
|
||||
}, (err) => {
|
||||
fail('should be able to add a field');
|
||||
done();
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -101,8 +101,12 @@ DatabaseController.prototype.redirectClassNameForKey = function(className, key)
|
||||
// Returns a promise that resolves to the new schema.
|
||||
// This does not update this.schema, because in a situation like a
|
||||
// batch request, that could confuse other users of the schema.
|
||||
DatabaseController.prototype.validateObject = function(className, object, query) {
|
||||
return this.loadSchema().then((schema) => {
|
||||
DatabaseController.prototype.validateObject = function(className, object, query, options) {
|
||||
let schema;
|
||||
return this.loadSchema().then(s => {
|
||||
schema = s;
|
||||
return this.canAddField(schema, className, object, options.acl || []);
|
||||
}).then(() => {
|
||||
return schema.validateObject(className, object, query);
|
||||
});
|
||||
};
|
||||
@@ -332,6 +336,22 @@ DatabaseController.prototype.create = function(className, object, options) {
|
||||
});
|
||||
};
|
||||
|
||||
DatabaseController.prototype.canAddField = function(schema, className, object, aclGroup) {
|
||||
let classSchema = schema.data[className];
|
||||
if (!classSchema) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let fields = Object.keys(object);
|
||||
let schemaFields = Object.keys(classSchema);
|
||||
let newKeys = fields.filter((field) => {
|
||||
return schemaFields.indexOf(field) < 0;
|
||||
})
|
||||
if (newKeys.length > 0) {
|
||||
return schema.validatePermission(className, aclGroup, 'addField');
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Runs a mongo query on the database.
|
||||
// This should only be used for testing - use 'find' for normal code
|
||||
// to avoid Mongo-format dependencies.
|
||||
|
||||
@@ -128,7 +128,7 @@ RestWrite.prototype.validateClientClassCreation = function() {
|
||||
|
||||
// Validates this operation against the schema.
|
||||
RestWrite.prototype.validateSchema = function() {
|
||||
return this.config.database.validateObject(this.className, this.data, this.query);
|
||||
return this.config.database.validateObject(this.className, this.data, this.query, this.runOptions);
|
||||
};
|
||||
|
||||
// Runs any beforeSave triggers against this operation.
|
||||
|
||||
Reference in New Issue
Block a user