* Adds schema caching capabilities (off by default) * Use InMemoryCacheAdapter * Uses proper adapter to generate a cache * Fix bugs when running disabled cache * nits * nits * Use options object instead of boolean * Imrpove concurrency of loadSchema * Adds testing with SCHEMA_CACHE_ON * Use CacheController instead of generator - Makes caching SchemaCache use a generated prefix - Makes clearing the SchemaCache clear only the cached schema keys - Enable cache by default (ttl 5s)
699 lines
22 KiB
JavaScript
699 lines
22 KiB
JavaScript
'use strict';
|
||
var Schema = require('../src/Controllers/SchemaController');
|
||
|
||
var Config = require('../src/Config');
|
||
|
||
describe('Pointer Permissions', () => {
|
||
|
||
beforeEach(() => {
|
||
new Config(Parse.applicationId).database.schemaCache.clear();
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should work with find', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
let obj2 = new Parse.Object('AnObject');
|
||
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
obj.set('owner', user);
|
||
obj2.set('owner', user2);
|
||
return Parse.Object.saveAll([obj, obj2]);
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
return schema.updateClass('AnObject', {}, {readUserFields: ['owner']})
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user1', 'password');
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.find();
|
||
}).then((res) => {
|
||
expect(res.length).toBe(1);
|
||
expect(res[0].id).toBe(obj.id);
|
||
done();
|
||
}).catch(error => {
|
||
fail(JSON.stringify(error));
|
||
done();
|
||
});
|
||
});
|
||
|
||
|
||
it_exclude_dbs(['postgres'])('should work with write', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
let obj2 = new Parse.Object('AnObject');
|
||
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
obj.set('owner', user);
|
||
obj.set('reader', user2);
|
||
obj2.set('owner', user2);
|
||
obj2.set('reader', user);
|
||
return Parse.Object.saveAll([obj, obj2]);
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
return schema.updateClass('AnObject', {}, {writeUserFields: ['owner'], readUserFields: ['reader', 'owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user1', 'password');
|
||
}).then(() => {
|
||
obj2.set('hello', 'world');
|
||
return obj2.save();
|
||
}).then((res) => {
|
||
fail('User should not be able to update obj2');
|
||
}, (err) => {
|
||
// User 1 should not be able to update obj2
|
||
expect(err.code).toBe(101);
|
||
return Promise.resolve();
|
||
}).then(()=> {
|
||
obj.set('hello', 'world');
|
||
return obj.save();
|
||
}).then(() => {
|
||
return Parse.User.logIn('user2', 'password');
|
||
}, (err) => {
|
||
fail('User should be able to update');
|
||
return Promise.resolve();
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.find();
|
||
}, (err) => {
|
||
fail('should login with user 2');
|
||
}).then((res) => {
|
||
expect(res.length).toBe(2);
|
||
res.forEach((result) => {
|
||
if (result.id == obj.id) {
|
||
expect(result.get('hello')).toBe('world');
|
||
} else {
|
||
expect(result.id).toBe(obj2.id);
|
||
}
|
||
})
|
||
done();
|
||
}, (err) => {
|
||
fail("failed");
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should let a proper user find', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
let obj2 = new Parse.Object('AnObject');
|
||
user.signUp().then(() => {
|
||
return user2.signUp()
|
||
}).then(() => {
|
||
Parse.User.logOut();
|
||
}).then(() => {
|
||
obj.set('owner', user);
|
||
return Parse.Object.saveAll([obj, obj2]);
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
return schema.updateClass('AnObject', {}, {find: {}, get:{}, readUserFields: ['owner']})
|
||
});
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.find();
|
||
}).then((res) => {
|
||
expect(res.length).toBe(0);
|
||
}).then(() => {
|
||
return Parse.User.logIn('user2', 'password');
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.find();
|
||
}).then((res) => {
|
||
expect(res.length).toBe(0);
|
||
let q = new Parse.Query('AnObject');
|
||
return q.get(obj.id);
|
||
}).then(() => {
|
||
fail('User 2 should not get the obj1 object');
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
expect(err.message).toBe('Object not found.');
|
||
return Promise.resolve();
|
||
}).then(() => {
|
||
return Parse.User.logIn('user1', 'password');
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.find();
|
||
}).then((res) => {
|
||
expect(res.length).toBe(1);
|
||
done();
|
||
}).catch((err) => {
|
||
console.error(err);
|
||
fail('should not fail');
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should not allow creating objects', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
user.save().then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
return schema.addClassIfNotExists('AnObject', {owner: {type:'Pointer', targetClass: '_User'}}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user1', 'password');
|
||
}).then(() => {
|
||
obj.set('owner', user);
|
||
return obj.save();
|
||
}).then(() => {
|
||
fail('should not succeed');
|
||
done();
|
||
}, (err) => {
|
||
expect(err.code).toBe(119);
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should handle multiple writeUserFields', done => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
Parse.Object.saveAll([user, user2])
|
||
.then(() => {
|
||
obj.set('owner', user);
|
||
obj.set('otherOwner', user2);
|
||
return obj.save();
|
||
})
|
||
.then(() => config.database.loadSchema())
|
||
.then(schema => schema.updateClass('AnObject', {}, {find: {"*": true},writeUserFields: ['owner', 'otherOwner']}))
|
||
.then(() => Parse.User.logIn('user1', 'password'))
|
||
.then(() => obj.save({hello: 'fromUser1'}))
|
||
.then(() => Parse.User.logIn('user2', 'password'))
|
||
.then(() => obj.save({hello: 'fromUser2'}))
|
||
.then(() => Parse.User.logOut())
|
||
.then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.first();
|
||
})
|
||
.then(result => {
|
||
expect(result.get('hello')).toBe('fromUser2');
|
||
done();
|
||
}).catch(err => {
|
||
fail('should not fail');
|
||
done();
|
||
})
|
||
});
|
||
|
||
it('should prevent creating pointer permission on missing field', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
config.database.loadSchema().then((schema) => {
|
||
return schema.addClassIfNotExists('AnObject', {}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||
}).then(() => {
|
||
fail('should not succeed');
|
||
}).catch((err) => {
|
||
expect(err.code).toBe(107);
|
||
expect(err.message).toBe("'owner' is not a valid column for class level pointer permissions writeUserFields");
|
||
done();
|
||
})
|
||
});
|
||
|
||
it('should prevent creating pointer permission on bad field', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
config.database.loadSchema().then((schema) => {
|
||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'String'}}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||
}).then(() => {
|
||
fail('should not succeed');
|
||
}).catch((err) => {
|
||
expect(err.code).toBe(107);
|
||
expect(err.message).toBe("'owner' is not a valid column for class level pointer permissions writeUserFields");
|
||
done();
|
||
})
|
||
});
|
||
|
||
it('should prevent creating pointer permission on bad field', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let object = new Parse.Object('AnObject');
|
||
object.set('owner', 'value');
|
||
object.save().then(() => {
|
||
return config.database.loadSchema();
|
||
}).then((schema) => {
|
||
return schema.updateClass('AnObject', {}, {create: {}, writeUserFields: ['owner'], readUserFields: ['owner']});
|
||
}).then(() => {
|
||
fail('should not succeed');
|
||
}).catch((err) => {
|
||
expect(err.code).toBe(107);
|
||
expect(err.message).toBe("'owner' is not a valid column for class level pointer permissions writeUserFields");
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('tests CLP / Pointer Perms / ACL write (PP Locked)', (done) => {
|
||
/*
|
||
tests:
|
||
CLP: update closed ({})
|
||
PointerPerm: "owner"
|
||
ACL: logged in user has access
|
||
|
||
The owner is another user than the ACL
|
||
*/
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
let ACL = new Parse.ACL();
|
||
ACL.setReadAccess(user, true);
|
||
ACL.setWriteAccess(user, true);
|
||
obj.setACL(ACL);
|
||
obj.set('owner', user2);
|
||
return obj.save();
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {}, {update: {}, writeUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user1', 'password');
|
||
}).then(() => {
|
||
// user1 has ACL read/write but should be blocked by PP
|
||
return obj.save({key: 'value'});
|
||
}).then(() => {
|
||
fail('Should not succeed saving');
|
||
done();
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('tests CLP / Pointer Perms / ACL write (ACL Locked)', (done) => {
|
||
/*
|
||
tests:
|
||
CLP: update closed ({})
|
||
PointerPerm: "owner"
|
||
ACL: logged in user has access
|
||
*/
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
let ACL = new Parse.ACL();
|
||
ACL.setReadAccess(user, true);
|
||
ACL.setWriteAccess(user, true);
|
||
obj.setACL(ACL);
|
||
obj.set('owner', user2);
|
||
return obj.save();
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {}, {update: {}, writeUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user2', 'password');
|
||
}).then(() => {
|
||
// user1 has ACL read/write but should be blocked by ACL
|
||
return obj.save({key: 'value'});
|
||
}).then(() => {
|
||
fail('Should not succeed saving');
|
||
done();
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('tests CLP / Pointer Perms / ACL write (ACL/PP OK)', (done) => {
|
||
/*
|
||
tests:
|
||
CLP: update closed ({})
|
||
PointerPerm: "owner"
|
||
ACL: logged in user has access
|
||
*/
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
let ACL = new Parse.ACL();
|
||
ACL.setWriteAccess(user, true);
|
||
ACL.setWriteAccess(user2, true);
|
||
obj.setACL(ACL);
|
||
obj.set('owner', user2);
|
||
return obj.save();
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {}, {update: {}, writeUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user2', 'password');
|
||
}).then(() => {
|
||
// user1 has ACL read/write but should be blocked by ACL
|
||
return obj.save({key: 'value'});
|
||
}).then((objAgain) => {
|
||
expect(objAgain.get('key')).toBe('value');
|
||
done();
|
||
}, (err) => {
|
||
fail('Should not fail saving');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('tests CLP / Pointer Perms / ACL read (PP locked)', (done) => {
|
||
/*
|
||
tests:
|
||
CLP: find/get open ({})
|
||
PointerPerm: "owner" : read
|
||
ACL: logged in user has access
|
||
|
||
The owner is another user than the ACL
|
||
*/
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
let ACL = new Parse.ACL();
|
||
ACL.setReadAccess(user, true);
|
||
ACL.setWriteAccess(user, true);
|
||
obj.setACL(ACL);
|
||
obj.set('owner', user2);
|
||
return obj.save();
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {}, {find: {}, get: {}, readUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user1', 'password');
|
||
}).then(() => {
|
||
// user1 has ACL read/write but should be block
|
||
return obj.fetch();
|
||
}).then(() => {
|
||
fail('Should not succeed saving');
|
||
done();
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('tests CLP / Pointer Perms / ACL read (PP/ACL OK)', (done) => {
|
||
/*
|
||
tests:
|
||
CLP: find/get open ({"*": true})
|
||
PointerPerm: "owner" : read
|
||
ACL: logged in user has access
|
||
*/
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
let ACL = new Parse.ACL();
|
||
ACL.setReadAccess(user, true);
|
||
ACL.setWriteAccess(user, true);
|
||
ACL.setReadAccess(user2, true);
|
||
ACL.setWriteAccess(user2, true);
|
||
obj.setACL(ACL);
|
||
obj.set('owner', user2);
|
||
return obj.save();
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {}, {find: {"*": true}, get: {"*": true}, readUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user2', 'password');
|
||
}).then(() => {
|
||
// user1 has ACL read/write but should be block
|
||
return obj.fetch();
|
||
}).then((objAgain) => {
|
||
expect(objAgain.id).toBe(obj.id);
|
||
done();
|
||
}, (err) => {
|
||
fail('Should not fail fetching');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('tests CLP / Pointer Perms / ACL read (ACL locked)', (done) => {
|
||
/*
|
||
tests:
|
||
CLP: find/get open ({"*": true})
|
||
PointerPerm: "owner" : read // proper owner
|
||
ACL: logged in user has not access
|
||
*/
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let user2 = new Parse.User();
|
||
user.set({
|
||
username: 'user1',
|
||
password: 'password'
|
||
});
|
||
user2.set({
|
||
username: 'user2',
|
||
password: 'password'
|
||
});
|
||
let obj = new Parse.Object('AnObject');
|
||
Parse.Object.saveAll([user, user2]).then(() => {
|
||
let ACL = new Parse.ACL();
|
||
ACL.setReadAccess(user, true);
|
||
ACL.setWriteAccess(user, true);
|
||
obj.setACL(ACL);
|
||
obj.set('owner', user2);
|
||
return obj.save();
|
||
}).then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {}, {find: {"*": true}, get: {"*": true}, readUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return Parse.User.logIn('user2', 'password');
|
||
}).then(() => {
|
||
// user2 has ACL read/write but should be block by ACL
|
||
return obj.fetch();
|
||
}).then(() => {
|
||
fail('Should not succeed saving');
|
||
done();
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should let master key find objects', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let object = new Parse.Object('AnObject');
|
||
object.set('hello', 'world');
|
||
return object.save().then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {find: {}, get: {}, readUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.find();
|
||
}).then(() => {
|
||
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
return Promise.resolve();
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.find({useMasterKey: true});
|
||
}).then((objects) => {
|
||
expect(objects.length).toBe(1);
|
||
done();
|
||
}, (err) => {
|
||
fail('master key should find the object');
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should let master key get objects', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let object = new Parse.Object('AnObject');
|
||
object.set('hello', 'world');
|
||
return object.save().then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {find: {}, get: {}, readUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.get(object.id);
|
||
}).then(() => {
|
||
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
return Promise.resolve();
|
||
}).then(() => {
|
||
let q = new Parse.Query('AnObject');
|
||
return q.get(object.id, {useMasterKey: true});
|
||
}).then((objectAgain) => {
|
||
expect(objectAgain).not.toBeUndefined();
|
||
expect(objectAgain.id).toBe(object.id);
|
||
done();
|
||
}, (err) => {
|
||
fail('master key should find the object');
|
||
done();
|
||
})
|
||
});
|
||
|
||
|
||
it_exclude_dbs(['postgres'])('should let master key update objects', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let object = new Parse.Object('AnObject');
|
||
object.set('hello', 'world');
|
||
return object.save().then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {update: {}, writeUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return object.save({'hello': 'bar'});
|
||
}).then(() => {
|
||
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
return Promise.resolve();
|
||
}).then(() => {
|
||
return object.save({'hello': 'baz'}, {useMasterKey: true});
|
||
}).then((objectAgain) => {
|
||
expect(objectAgain.get('hello')).toBe('baz');
|
||
done();
|
||
}, (err) => {
|
||
fail('master key should save the object');
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('should let master key delete objects', (done) => {
|
||
let config = new Config(Parse.applicationId);
|
||
let user = new Parse.User();
|
||
let object = new Parse.Object('AnObject');
|
||
object.set('hello', 'world');
|
||
return object.save().then(() => {
|
||
return config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.updateClass('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: ['owner']});
|
||
});
|
||
}).then(() => {
|
||
return object.destroy();
|
||
}).then(() => {
|
||
fail();
|
||
}, (err) => {
|
||
expect(err.code).toBe(101);
|
||
return Promise.resolve();
|
||
}).then(() => {
|
||
return object.destroy({useMasterKey: true});
|
||
}).then((objectAgain) => {
|
||
done();
|
||
}, (err) => {
|
||
fail('master key should destroy the object');
|
||
done();
|
||
})
|
||
});
|
||
|
||
it('should fail with invalid pointer perms', () => {
|
||
let config = new Config(Parse.applicationId);
|
||
config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: 'owner'});
|
||
}).catch((err) => {
|
||
expect(err.code).toBe(Parse.Error.INVALID_JSON);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should fail with invalid pointer perms', () => {
|
||
let config = new Config(Parse.applicationId);
|
||
config.database.loadSchema().then((schema) => {
|
||
// Lock the update, and let only owner write
|
||
return schema.addClassIfNotExists('AnObject', {owner: {type: 'Pointer', targetClass: '_User'}}, {delete: {}, writeUserFields: ['owner', 'invalid']});
|
||
}).catch((err) => {
|
||
expect(err.code).toBe(Parse.Error.INVALID_JSON);
|
||
done();
|
||
});
|
||
})
|
||
});
|