Move transform acl (#2021)

* Move ACL transforming into Parse Server

For the database adapters, it will be more performant and easier to work with _rperm and _wperm than with the ACL object. This way we can type it as an array and so on, and once we have stronger validations in Parse Server, we can type it as an array containing strings of length < x, which will be much much better in sql databases.

* Use destructuring
This commit is contained in:
Drew
2016-06-12 13:39:41 -07:00
committed by GitHub
parent 5baa53d858
commit d559cb2382
6 changed files with 104 additions and 111 deletions

View File

@@ -24,6 +24,26 @@ function addReadACL(query, acl) {
return newQuery;
}
// Transforms a REST API formatted ACL object to our two-field mongo format.
const transformObjectACL = ({ ACL, ...result }) => {
if (!ACL) {
return result;
}
result._wperm = [];
result._rperm = [];
for (let entry in ACL) {
if (ACL[entry].read) {
result._rperm.push(entry);
}
if (ACL[entry].write) {
result._wperm.push(entry);
}
}
return result;
}
const specialQuerykeys = ['$and', '$or', '_rperm', '_wperm', '_perishable_token', '_email_verify_token'];
const validateQuery = query => {
if (query.ACL) {
@@ -210,6 +230,7 @@ DatabaseController.prototype.update = function(className, query, update, {
throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters");
}
}
update = transformObjectACL(update);
if (many) {
return this.adapter.updateObjectsByQuery(className, query, schema, update);
} else if (upsert) {
@@ -376,7 +397,7 @@ DatabaseController.prototype.destroy = function(className, query, { acl } = {})
DatabaseController.prototype.create = function(className, object, { acl } = {}) {
// Make a copy of the object, so we don't mutate the incoming data.
let originalObject = object;
object = deepcopy(object);
object = transformObjectACL(object);
var isMaster = acl === undefined;
var aclGroup = acl || [];
@@ -671,13 +692,40 @@ DatabaseController.prototype.find = function(className, query, {
return this.adapter.count(className, query, schema);
} else {
return this.adapter.find(className, query, schema, { skip, limit, sort })
.then(objects => objects.map(object => filterSensitiveData(isMaster, aclGroup, className, object)));
.then(objects => objects.map(object => {
object = untransformObjectACL(object);
return filterSensitiveData(isMaster, aclGroup, className, object)
}));
}
});
});
});
};
// Transforms a Database format ACL to a REST API format ACL
const untransformObjectACL = ({_rperm, _wperm, ...output}) => {
if (_rperm || _wperm) {
output.ACL = {};
(_rperm || []).forEach(entry => {
if (!output.ACL[entry]) {
output.ACL[entry] = { read: true };
} else {
output.ACL[entry]['read'] = true;
}
});
(_wperm || []).forEach(entry => {
if (!output.ACL[entry]) {
output.ACL[entry] = { write: true };
} else {
output.ACL[entry]['write'] = true;
}
});
}
return output;
}
DatabaseController.prototype.deleteSchema = function(className) {
return this.collectionExists(className)
.then(exist => {