Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ ___
- IMPROVE: Parse Server will from now on be continuously tested against all relevant MongoDB versions (minor versions). Added MongoDB compatibility table to Parse Server docs. [7161](https://github.com/parse-community/parse-server/pull/7161). Thanks to [Manuel Trezza](https://github.com/mtrezza).
- IMPROVE: Optimize queries on classes with pointer permissions. [#7061](https://github.com/parse-community/parse-server/pull/7061). Thanks to [Pedro Diaz](https://github.com/pdiaz)
- FIX: request.context for afterFind triggers. [#7078](https://github.com/parse-community/parse-server/pull/7078). Thanks to [dblythy](https://github.com/dblythy)
- NEW: `requireAnyUserRoles` and `requireAllUserRoles` for Parse Cloud validator. [#7097](https://github.com/parse-community/parse-server/pull/7097). Thanks to [dblythy](https://github.com/dblythy)
- NEW: Added convenience method Parse.Cloud.sendEmail(...) to send email via email adapter in Cloud Code. [#7089](https://github.com/parse-community/parse-server/pull/7089). Thanks to [dblythy](https://github.com/dblythy)
- FIX: Winston Logger interpolating stdout to console [#7114](https://github.com/parse-community/parse-server/pull/7114). Thanks to [dplewis](https://github.com/dplewis)

### 4.5.0
Expand Down
144 changes: 144 additions & 0 deletions spec/CloudCode.Validator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,150 @@ describe('cloud validator', () => {
});
});

it('basic validator requireAnyUserRoles', async function (done) {
Parse.Cloud.define(
'cloudFunction',
() => {
return true;
},
{
requireUser: true,
requireAnyUserRoles: ['Admin'],
}
);
const user = await Parse.User.signUp('testuser', 'p@ssword');
try {
await Parse.Cloud.run('cloudFunction');
fail('cloud validator should have failed.');
} catch (e) {
expect(e.message).toBe('Validation failed. User does not match the required roles.');
}
const roleACL = new Parse.ACL();
roleACL.setPublicReadAccess(true);
const role = new Parse.Role('Admin', roleACL);
role.getUsers().add(user);
await role.save({ useMasterKey: true });
await Parse.Cloud.run('cloudFunction');
done();
});

it('basic validator requireAllUserRoles', async function (done) {
Parse.Cloud.define(
'cloudFunction',
() => {
return true;
},
{
requireUser: true,
requireAllUserRoles: ['Admin', 'Admin2'],
}
);
const user = await Parse.User.signUp('testuser', 'p@ssword');
try {
await Parse.Cloud.run('cloudFunction');
fail('cloud validator should have failed.');
} catch (e) {
expect(e.message).toBe('Validation failed. User does not match all the required roles.');
}
const roleACL = new Parse.ACL();
roleACL.setPublicReadAccess(true);
const role = new Parse.Role('Admin', roleACL);
role.getUsers().add(user);

const role2 = new Parse.Role('Admin2', roleACL);
role2.getUsers().add(user);
await Promise.all([role.save({ useMasterKey: true }), role2.save({ useMasterKey: true })]);
await Parse.Cloud.run('cloudFunction');
done();
});

it('allow requireAnyUserRoles to be a function', async function (done) {
Parse.Cloud.define(
'cloudFunction',
() => {
return true;
},
{
requireUser: true,
requireAnyUserRoles: () => {
return ['Admin Func'];
},
}
);
const user = await Parse.User.signUp('testuser', 'p@ssword');
try {
await Parse.Cloud.run('cloudFunction');
fail('cloud validator should have failed.');
} catch (e) {
expect(e.message).toBe('Validation failed. User does not match the required roles.');
}
const roleACL = new Parse.ACL();
roleACL.setPublicReadAccess(true);
const role = new Parse.Role('Admin Func', roleACL);
role.getUsers().add(user);
await role.save({ useMasterKey: true });
await Parse.Cloud.run('cloudFunction');
done();
});

it('allow requireAllUserRoles to be a function', async function (done) {
Parse.Cloud.define(
'cloudFunction',
() => {
return true;
},
{
requireUser: true,
requireAllUserRoles: () => {
return ['AdminA', 'AdminB'];
},
}
);
const user = await Parse.User.signUp('testuser', 'p@ssword');
try {
await Parse.Cloud.run('cloudFunction');
fail('cloud validator should have failed.');
} catch (e) {
expect(e.message).toBe('Validation failed. User does not match all the required roles.');
}
const roleACL = new Parse.ACL();
roleACL.setPublicReadAccess(true);
const role = new Parse.Role('AdminA', roleACL);
role.getUsers().add(user);

const role2 = new Parse.Role('AdminB', roleACL);
role2.getUsers().add(user);
await Promise.all([role.save({ useMasterKey: true }), role2.save({ useMasterKey: true })]);
await Parse.Cloud.run('cloudFunction');
done();
});

it('basic requireAllUserRoles but no user', async function (done) {
Parse.Cloud.define(
'cloudFunction',
() => {
return true;
},
{
requireAllUserRoles: ['Admin'],
}
);
try {
await Parse.Cloud.run('cloudFunction');
fail('cloud validator should have failed.');
} catch (e) {
expect(e.message).toBe('Validation failed. Please login to continue.');
}
const user = await Parse.User.signUp('testuser', 'p@ssword');
const roleACL = new Parse.ACL();
roleACL.setPublicReadAccess(true);
const role = new Parse.Role('Admin', roleACL);
role.getUsers().add(user);
await role.save({ useMasterKey: true });
await Parse.Cloud.run('cloudFunction');
done();
});

it('basic beforeSave requireMaster', function (done) {
Parse.Cloud.beforeSave('BeforeSaveFail', () => {}, {
requireMaster: true,
Expand Down
Loading