Allow protectedFields for Authenticated users and Public. Fix userField with keys/excludedKeys (#6415)
* fix error message and test it * protected fields fixes * clean * remove duplicate test, add some comments * no need for 'requiresAuthentication'
This commit is contained in:
@@ -175,32 +175,62 @@ const volatileClasses = Object.freeze([
|
||||
|
||||
// Anything that start with role
|
||||
const roleRegex = /^role:.*/;
|
||||
// Anything that starts with userField
|
||||
const pointerPermissionRegex = /^userField:.*/;
|
||||
// Anything that starts with userField (allowed for protected fields only)
|
||||
const protectedFieldsPointerRegex = /^userField:.*/;
|
||||
// * permission
|
||||
const publicRegex = /^\*$/;
|
||||
|
||||
const requireAuthenticationRegex = /^requiresAuthentication$/;
|
||||
const authenticatedRegex = /^authenticated$/;
|
||||
|
||||
const pointerFieldsRegex = /^pointerFields$/;
|
||||
const requiresAuthenticationRegex = /^requiresAuthentication$/;
|
||||
|
||||
const permissionKeyRegex = Object.freeze([
|
||||
roleRegex,
|
||||
pointerPermissionRegex,
|
||||
const clpPointerRegex = /^pointerFields$/;
|
||||
|
||||
// regex for validating entities in protectedFields object
|
||||
const protectedFieldsRegex = Object.freeze([
|
||||
protectedFieldsPointerRegex,
|
||||
publicRegex,
|
||||
requireAuthenticationRegex,
|
||||
pointerFieldsRegex,
|
||||
authenticatedRegex,
|
||||
roleRegex,
|
||||
]);
|
||||
|
||||
// clp regex
|
||||
const clpFieldsRegex = Object.freeze([
|
||||
clpPointerRegex,
|
||||
publicRegex,
|
||||
requiresAuthenticationRegex,
|
||||
roleRegex,
|
||||
]);
|
||||
|
||||
function validatePermissionKey(key, userIdRegExp) {
|
||||
let matchesSome = false;
|
||||
for (const regEx of permissionKeyRegex) {
|
||||
for (const regEx of clpFieldsRegex) {
|
||||
if (key.match(regEx) !== null) {
|
||||
matchesSome = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// userId depends on startup options so it's dynamic
|
||||
const valid = matchesSome || key.match(userIdRegExp) !== null;
|
||||
if (!valid) {
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_JSON,
|
||||
`'${key}' is not a valid key for class level permissions`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateProtectedFieldsKey(key, userIdRegExp) {
|
||||
let matchesSome = false;
|
||||
for (const regEx of protectedFieldsRegex) {
|
||||
if (key.match(regEx) !== null) {
|
||||
matchesSome = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// userId regex depends on launch options so it's dynamic
|
||||
const valid = matchesSome || key.match(userIdRegExp) !== null;
|
||||
if (!valid) {
|
||||
throw new Parse.Error(
|
||||
@@ -264,7 +294,7 @@ function validateCLP(
|
||||
if (operationKey === 'protectedFields') {
|
||||
for (const entity in operation) {
|
||||
// throws on unexpected key
|
||||
validatePermissionKey(entity, userIdRegExp);
|
||||
validateProtectedFieldsKey(entity, userIdRegExp);
|
||||
|
||||
const protectedFields = operation[entity];
|
||||
|
||||
@@ -301,6 +331,8 @@ function validateCLP(
|
||||
// throws on unexpected key
|
||||
validatePermissionKey(entity, userIdRegExp);
|
||||
|
||||
// entity can be either:
|
||||
// "pointerFields": string[]
|
||||
if (entity === 'pointerFields') {
|
||||
const pointerFields = operation[entity];
|
||||
|
||||
@@ -311,13 +343,14 @@ function validateCLP(
|
||||
} else {
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_JSON,
|
||||
`'${pointerFields}' is not a valid value for protectedFields[${entity}] - expected an array.`
|
||||
`'${pointerFields}' is not a valid value for ${operationKey}[${entity}] - expected an array.`
|
||||
);
|
||||
}
|
||||
// proceed with next entity key
|
||||
continue;
|
||||
}
|
||||
|
||||
// or [entity]: boolean
|
||||
const permit = operation[entity];
|
||||
|
||||
if (permit !== true) {
|
||||
|
||||
Reference in New Issue
Block a user