Set default protectedFields and remove previous filter logic
This commit is contained in:
@@ -23,6 +23,7 @@ describe('MongoSchemaCollection', () => {
|
|||||||
create: { '*': true },
|
create: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
indexes: {
|
indexes: {
|
||||||
name1: { deviceToken: 1 },
|
name1: { deviceToken: 1 },
|
||||||
@@ -72,6 +73,7 @@ describe('MongoSchemaCollection', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
indexes: {
|
indexes: {
|
||||||
name1: { deviceToken: 1 },
|
name1: { deviceToken: 1 },
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ describe('ParseLiveQueryServer', function() {
|
|||||||
find: {},
|
find: {},
|
||||||
update: {},
|
update: {},
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(deleteSpy).toHaveBeenCalled();
|
expect(deleteSpy).toHaveBeenCalled();
|
||||||
@@ -270,6 +271,7 @@ describe('ParseLiveQueryServer', function() {
|
|||||||
find: {},
|
find: {},
|
||||||
update: {},
|
update: {},
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
@@ -1920,6 +1922,7 @@ describe('LiveQueryController', () => {
|
|||||||
find: {},
|
find: {},
|
||||||
update: {},
|
update: {},
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(deleteSpy).toHaveBeenCalled();
|
expect(deleteSpy).toHaveBeenCalled();
|
||||||
@@ -1933,6 +1936,7 @@ describe('LiveQueryController', () => {
|
|||||||
find: {},
|
find: {},
|
||||||
update: {},
|
update: {},
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -320,6 +320,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
||||||
@@ -338,6 +339,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
};
|
};
|
||||||
config.database.loadSchema().then(schema => {
|
config.database.loadSchema().then(schema => {
|
||||||
schema
|
schema
|
||||||
@@ -461,6 +463,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
||||||
@@ -653,6 +656,68 @@ describe('SchemaController', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('refuses to add CLP with incorrect find', done => {
|
||||||
|
const levelPermissions = {
|
||||||
|
find: { '*': false },
|
||||||
|
get: { '*': true },
|
||||||
|
create: { '*': true },
|
||||||
|
update: { '*': true },
|
||||||
|
delete: { '*': true },
|
||||||
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': ['email'] },
|
||||||
|
};
|
||||||
|
config.database.loadSchema().then(schema => {
|
||||||
|
schema
|
||||||
|
.validateObject('NewClass', {})
|
||||||
|
.then(() => schema.reloadData())
|
||||||
|
.then(() =>
|
||||||
|
schema.updateClass(
|
||||||
|
'NewClass',
|
||||||
|
{},
|
||||||
|
levelPermissions,
|
||||||
|
{},
|
||||||
|
config.database
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(done.fail)
|
||||||
|
.catch(error => {
|
||||||
|
expect(error.code).toEqual(Parse.Error.INVALID_JSON);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refuses to add CLP with incorrect protectedFields', done => {
|
||||||
|
const levelPermissions = {
|
||||||
|
find: { '*': true },
|
||||||
|
get: { '*': true },
|
||||||
|
create: { '*': true },
|
||||||
|
update: { '*': true },
|
||||||
|
delete: { '*': true },
|
||||||
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': 'email' },
|
||||||
|
};
|
||||||
|
config.database.loadSchema().then(schema => {
|
||||||
|
schema
|
||||||
|
.validateObject('NewClass', {})
|
||||||
|
.then(() => schema.reloadData())
|
||||||
|
.then(() =>
|
||||||
|
schema.updateClass(
|
||||||
|
'NewClass',
|
||||||
|
{},
|
||||||
|
levelPermissions,
|
||||||
|
{},
|
||||||
|
config.database
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(done.fail)
|
||||||
|
.catch(error => {
|
||||||
|
expect(error.code).toEqual(Parse.Error.INVALID_JSON);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('will create classes', done => {
|
it('will create classes', done => {
|
||||||
config.database
|
config.database
|
||||||
.loadSchema()
|
.loadSchema()
|
||||||
@@ -706,6 +771,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
||||||
@@ -751,6 +817,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
||||||
@@ -782,6 +849,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
||||||
@@ -815,6 +883,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
||||||
@@ -1002,6 +1071,7 @@ describe('SchemaController', () => {
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ const defaultClassLevelPermissions = {
|
|||||||
delete: {
|
delete: {
|
||||||
'*': true,
|
'*': true,
|
||||||
},
|
},
|
||||||
|
protectedFields: {
|
||||||
|
'*': [],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const plainOldDataSchema = {
|
const plainOldDataSchema = {
|
||||||
@@ -1141,6 +1144,7 @@ describe('schemas', () => {
|
|||||||
update: {},
|
update: {},
|
||||||
delete: {},
|
delete: {},
|
||||||
addField: {},
|
addField: {},
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -2037,6 +2041,7 @@ describe('schemas', () => {
|
|||||||
update: {},
|
update: {},
|
||||||
delete: {},
|
delete: {},
|
||||||
addField: {},
|
addField: {},
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(done)
|
.then(done)
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ const emptyCLPS = Object.freeze({
|
|||||||
update: {},
|
update: {},
|
||||||
delete: {},
|
delete: {},
|
||||||
addField: {},
|
addField: {},
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultCLPS = Object.freeze({
|
const defaultCLPS = Object.freeze({
|
||||||
@@ -71,6 +72,7 @@ const defaultCLPS = Object.freeze({
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
});
|
});
|
||||||
|
|
||||||
function mongoSchemaToParseSchema(mongoSchema) {
|
function mongoSchemaToParseSchema(mongoSchema) {
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ const emptyCLPS = Object.freeze({
|
|||||||
update: {},
|
update: {},
|
||||||
delete: {},
|
delete: {},
|
||||||
addField: {},
|
addField: {},
|
||||||
|
protectedFields: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultCLPS = Object.freeze({
|
const defaultCLPS = Object.freeze({
|
||||||
@@ -115,6 +116,7 @@ const defaultCLPS = Object.freeze({
|
|||||||
update: { '*': true },
|
update: { '*': true },
|
||||||
delete: { '*': true },
|
delete: { '*': true },
|
||||||
addField: { '*': true },
|
addField: { '*': true },
|
||||||
|
protectedFields: { '*': [] },
|
||||||
});
|
});
|
||||||
|
|
||||||
const toParseSchema = schema => {
|
const toParseSchema = schema => {
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ const CLPValidKeys = Object.freeze([
|
|||||||
'addField',
|
'addField',
|
||||||
'readUserFields',
|
'readUserFields',
|
||||||
'writeUserFields',
|
'writeUserFields',
|
||||||
|
'protectedFields',
|
||||||
]);
|
]);
|
||||||
function validateCLP(perms: ClassLevelPermissions, fields: SchemaFields) {
|
function validateCLP(perms: ClassLevelPermissions, fields: SchemaFields) {
|
||||||
if (!perms) {
|
if (!perms) {
|
||||||
@@ -250,7 +251,10 @@ function validateCLP(perms: ClassLevelPermissions, fields: SchemaFields) {
|
|||||||
verifyPermissionKey(key);
|
verifyPermissionKey(key);
|
||||||
// @flow-disable-next
|
// @flow-disable-next
|
||||||
const perm = perms[operation][key];
|
const perm = perms[operation][key];
|
||||||
if (perm !== true) {
|
if (
|
||||||
|
perm !== true &&
|
||||||
|
(operation !== 'protectedFields' || !Array.isArray(perm))
|
||||||
|
) {
|
||||||
// @flow-disable-next
|
// @flow-disable-next
|
||||||
throw new Parse.Error(
|
throw new Parse.Error(
|
||||||
Parse.Error.INVALID_JSON,
|
Parse.Error.INVALID_JSON,
|
||||||
|
|||||||
@@ -565,19 +565,8 @@ RestQuery.prototype.replaceDontSelect = function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanResultOfSensitiveUserInfo = function(result, auth, config) {
|
|
||||||
delete result.password;
|
|
||||||
|
|
||||||
if (auth.isMaster || (auth.user && auth.user.id === result.objectId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const field of config.userSensitiveFields) {
|
|
||||||
delete result[field];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const cleanResultAuthData = function(result) {
|
const cleanResultAuthData = function(result) {
|
||||||
|
delete result.password;
|
||||||
if (result.authData) {
|
if (result.authData) {
|
||||||
Object.keys(result.authData).forEach(provider => {
|
Object.keys(result.authData).forEach(provider => {
|
||||||
if (result.authData[provider] === null) {
|
if (result.authData[provider] === null) {
|
||||||
@@ -645,7 +634,6 @@ RestQuery.prototype.runFind = function(options = {}) {
|
|||||||
.then(results => {
|
.then(results => {
|
||||||
if (this.className === '_User') {
|
if (this.className === '_User') {
|
||||||
for (var result of results) {
|
for (var result of results) {
|
||||||
cleanResultOfSensitiveUserInfo(result, this.auth, this.config);
|
|
||||||
cleanResultAuthData(result);
|
cleanResultAuthData(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user