diff --git a/spec/CloudCode.spec.js b/spec/CloudCode.spec.js index 99ec4910d1..291421232c 100644 --- a/spec/CloudCode.spec.js +++ b/spec/CloudCode.spec.js @@ -1163,6 +1163,53 @@ describe('Cloud Code', () => { ); }); + it('test save triggers get user roles', async () => { + let beforeSaveFlag = false; + let afterSaveFlag = false; + Parse.Cloud.beforeSave('SaveTriggerUserRoles', async req => { + expect(await req.getRoles()).toEqual(['TestRole']); + beforeSaveFlag = true; + }); + + Parse.Cloud.afterSave('SaveTriggerUserRoles', async req => { + expect(await req.getRoles()).toEqual(['TestRole']); + afterSaveFlag = true; + }); + + const user = new Parse.User(); + user.set('password', 'asdf'); + user.set('email', 'asdf@example.com'); + user.set('username', 'zxcv'); + await user.signUp(); + const role = new Parse.Role('TestRole', new Parse.ACL({ '*': { read: true, write: true } })); + role.getUsers().add(user); + await role.save(); + + const obj = new Parse.Object('SaveTriggerUserRoles'); + await obj.save(); + expect(beforeSaveFlag).toBeTrue(); + expect(afterSaveFlag).toBeTrue(); + }); + + it('should not have user roles for anonymous calls', async () => { + let beforeSaveFlag = false; + let afterSaveFlag = false; + Parse.Cloud.beforeSave('SaveTriggerUserRoles', async req => { + expect(req.getRoles).toBeUndefined(); + beforeSaveFlag = true; + }); + + Parse.Cloud.afterSave('SaveTriggerUserRoles', async req => { + expect(req.getRoles).toBeUndefined(); + afterSaveFlag = true; + }); + + const obj = new Parse.Object('SaveTriggerUserRoles'); + await obj.save(); + expect(beforeSaveFlag).toBeTrue(); + expect(afterSaveFlag).toBeTrue(); + }); + it('beforeSave change propagates through the save response', done => { Parse.Cloud.beforeSave('ChangingObject', function (request) { request.object.set('foo', 'baz'); @@ -2014,6 +2061,37 @@ describe('cloud functions', () => { Parse.Cloud.run('myFunction', {}).then(() => done()); }); + + it('should have user roles', async () => { + let flag = false; + Parse.Cloud.define('myFunction', async req => { + expect(await req.getRoles()).toEqual(['TestRole']); + flag = true; + }); + + const user = new Parse.User(); + user.set('password', 'asdf'); + user.set('email', 'asdf@example.com'); + user.set('username', 'zxcv'); + await user.signUp(); + const role = new Parse.Role('TestRole', new Parse.ACL({ '*': { read: true, write: true } })); + role.getUsers().add(user); + await role.save(); + + await Parse.Cloud.run('myFunction', { sessionToken: user.getSessionToken() }); + expect(flag).toBeTrue(); + }); + + it('should not have user roles for anonymous calls', async () => { + let flag = false; + Parse.Cloud.define('myFunction', async req => { + expect(req.getRoles).toBeUndefined(); + flag = true; + }); + + await Parse.Cloud.run('myFunction'); + expect(flag).toBeTrue(); + }); }); describe('beforeSave hooks', () => { diff --git a/src/Routers/FunctionsRouter.js b/src/Routers/FunctionsRouter.js index 77c0dff7cc..d02d983fa3 100644 --- a/src/Routers/FunctionsRouter.js +++ b/src/Routers/FunctionsRouter.js @@ -131,6 +131,12 @@ export class FunctionsRouter extends PromiseRouter { params: params, master: req.auth && req.auth.isMaster, user: req.auth && req.auth.user, + getRoles: + req.auth && req.auth.user + ? async () => { + return (await req.auth.getUserRoles()).map(r => r.substr('role:'.length)); + } + : undefined, installationId: req.info.installationId, log: req.config.loggerController, headers: req.config.headers, diff --git a/src/triggers.js b/src/triggers.js index e34c5fd3a8..888f6b4361 100644 --- a/src/triggers.js +++ b/src/triggers.js @@ -292,6 +292,9 @@ export function getRequestObject( } if (auth.user) { request['user'] = auth.user; + request['getRoles'] = async () => { + return (await auth.getUserRoles()).map(r => r.substr('role:'.length)); + }; } if (auth.installationId) { request['installationId'] = auth.installationId;