Skip to content

Commit

Permalink
Adds validation of addFields
Browse files Browse the repository at this point in the history
  • Loading branch information
flovilmart committed Mar 10, 2016
1 parent 64f9fad commit e75d233
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 3 deletions.
58 changes: 58 additions & 0 deletions spec/schemas.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
})
})
});

});
24 changes: 22 additions & 2 deletions src/Controllers/DatabaseController.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
};
Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/RestWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit e75d233

Please sign in to comment.