Fixes for Class Level and Pointer Permissions (#1989)
* Fixes for Pointer Permissions - Fix bug that would leave public CLP when setting a new set of permissions - Sets empty permissions if missing to match parse.com API - Updates tests to reflect changes * Adds regression test for #1991 * Fit -> It
This commit is contained in:
@@ -43,6 +43,15 @@ function mongoSchemaFieldsToParseSchemaFields(schema) {
|
||||
return response;
|
||||
}
|
||||
|
||||
const emptyCLPS = Object.freeze({
|
||||
find: {},
|
||||
get: {},
|
||||
create: {},
|
||||
update: {},
|
||||
delete: {},
|
||||
addField: {},
|
||||
});
|
||||
|
||||
const defaultCLPS = Object.freeze({
|
||||
find: {'*': true},
|
||||
get: {'*': true},
|
||||
@@ -53,14 +62,14 @@ const defaultCLPS = Object.freeze({
|
||||
});
|
||||
|
||||
function mongoSchemaToParseSchema(mongoSchema) {
|
||||
let clpsFromMongoObject = {};
|
||||
let clps = defaultCLPS;
|
||||
if (mongoSchema._metadata && mongoSchema._metadata.class_permissions) {
|
||||
clpsFromMongoObject = mongoSchema._metadata.class_permissions;
|
||||
clps = {...emptyCLPS, ...mongoSchema._metadata.class_permissions};
|
||||
}
|
||||
return {
|
||||
className: mongoSchema._id,
|
||||
fields: mongoSchemaFieldsToParseSchemaFields(mongoSchema),
|
||||
classLevelPermissions: {...defaultCLPS, ...clpsFromMongoObject},
|
||||
classLevelPermissions: clps,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -704,6 +704,11 @@ DatabaseController.prototype.deleteSchema = function(className) {
|
||||
}
|
||||
|
||||
DatabaseController.prototype.addPointerPermissions = function(schema, className, operation, query, aclGroup = []) {
|
||||
// Check if class has public permission for operation
|
||||
// If the BaseCLP pass, let go through
|
||||
if (schema.testBaseCLP(className, aclGroup, operation)) {
|
||||
return query;
|
||||
}
|
||||
let perms = schema.perms[className];
|
||||
let field = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
let userACL = aclGroup.filter((acl) => {
|
||||
|
||||
@@ -632,30 +632,36 @@ class SchemaController {
|
||||
}
|
||||
return Promise.resolve(this);
|
||||
}
|
||||
|
||||
// Validates an operation passes class-level-permissions set in the schema
|
||||
validatePermission(className, aclGroup, operation) {
|
||||
|
||||
// Validates the base CLP for an operation
|
||||
testBaseCLP(className, aclGroup, operation) {
|
||||
if (!this.perms[className] || !this.perms[className][operation]) {
|
||||
return Promise.resolve();
|
||||
return true;
|
||||
}
|
||||
let classPerms = this.perms[className];
|
||||
let perms = classPerms[operation];
|
||||
// Handle the public scenario quickly
|
||||
if (perms['*']) {
|
||||
return Promise.resolve();
|
||||
return true;
|
||||
}
|
||||
// Check permissions against the aclGroup provided (array of userId/roles)
|
||||
let found = false;
|
||||
for (let i = 0; i < aclGroup.length && !found; i++) {
|
||||
if (perms[aclGroup[i]]) {
|
||||
found = true;
|
||||
}
|
||||
if (aclGroup.some(acl => { return perms[acl] === true })) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
// Validates an operation passes class-level-permissions set in the schema
|
||||
validatePermission(className, aclGroup, operation) {
|
||||
if (this.testBaseCLP(className, aclGroup, operation)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!this.perms[className] || !this.perms[className][operation]) {
|
||||
return true;
|
||||
}
|
||||
let classPerms = this.perms[className];
|
||||
let perms = classPerms[operation];
|
||||
// No matching CLP, let's check the Pointer permissions
|
||||
// And handle those later
|
||||
let permissionField = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
@@ -666,6 +672,7 @@ class SchemaController {
|
||||
'Permission denied for this action.');
|
||||
}
|
||||
|
||||
// Process the readUserFields later
|
||||
if (Array.isArray(classPerms[permissionField]) && classPerms[permissionField].length > 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user