Add filter sensitive fields logic that apply CLPs\nAdd protectedFields CLP\nAdd defaults for protectedFields CLP\nFix tests

This commit is contained in:
awgeorge
2019-01-29 08:52:49 +00:00
committed by Arthur Cinader
parent b343de0c70
commit 0dec4931a0
7 changed files with 122 additions and 13 deletions

View File

@@ -162,7 +162,15 @@ const validateQuery = (query: any): void => {
};
// Filters out any data that shouldn't be on this REST-formatted object.
const filterSensitiveData = (isMaster, aclGroup, className, object) => {
const filterSensitiveData = (
isMaster,
aclGroup,
className,
protectedFields,
object
) => {
protectedFields && protectedFields.forEach(k => delete object[k]);
if (className !== '_User') {
return object;
}
@@ -1141,7 +1149,8 @@ class DatabaseController {
distinct,
pipeline,
readPreference,
}: any = {}
}: any = {},
auth: any = {}
): Promise<any> {
const isMaster = acl === undefined;
const aclGroup = acl || [];
@@ -1206,6 +1215,7 @@ class DatabaseController {
this.reduceInRelation(className, query, schemaController)
)
.then(() => {
let protectedFields;
if (!isMaster) {
query = this.addPointerPermissions(
schemaController,
@@ -1214,6 +1224,15 @@ class DatabaseController {
query,
aclGroup
);
// ProtectedFields is generated before executing the query so we
// can optimize the query using Mongo Projection at a later stage.
protectedFields = this.addProtectedFields(
schemaController,
className,
query,
aclGroup,
auth
);
}
if (!query) {
if (op === 'get') {
@@ -1276,6 +1295,7 @@ class DatabaseController {
isMaster,
aclGroup,
className,
protectedFields,
object
);
})
@@ -1390,6 +1410,42 @@ class DatabaseController {
}
}
addProtectedFields(
schema: SchemaController.SchemaController,
className: string,
query: any = {},
aclGroup: any[] = [],
auth: any = {}
) {
const perms = schema.getClassLevelPermissions(className);
if (!perms) return null;
const protectedFields = perms.protectedFields;
if (!protectedFields) return null;
if (aclGroup.indexOf(query.objectId) > -1) return null;
if (
Object.keys(query).length === 0 &&
auth &&
auth.user &&
aclGroup.indexOf(auth.user.id) > -1
)
return null;
let protectedKeys;
[...(auth.userRoles || []), '*'].forEach(role => {
// If you are in multiple groups assign the role with the least protectedKeys.
// Technically this could fail if multiple roles protect different fields and produce the same count.
// But we have no way of knowing the role hierarchy here.
const fields = protectedFields[role];
if (fields && (!protectedKeys || fields.length < protectedKeys.length)) {
protectedKeys = fields;
}
});
return protectedKeys;
}
// TODO: create indexes on first creation of a _User object. Otherwise it's impossible to
// have a Parse app without it having a _User collection.
performInitialization() {