Skip to content

Commit

Permalink
fix(events): only returning special fields to those who have rights
Browse files Browse the repository at this point in the history
  • Loading branch information
serge1peshcoff committed Dec 30, 2019
1 parent 22c6a39 commit fa142b5
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 2 deletions.
18 changes: 18 additions & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ module.exports = {
created_at: 'Created at',
updated_at: 'Updated at'
},
EVENT_PUBLIC_FIELDS: [
'id',
'name',
'url',
'image',
'description',
'application_starts',
'application_ends',
'starts',
'ends',
'fee',
'organizing_bodies',
'locations',
'type',
'questions',
'max_participants',
'application_status'
],
EVENT_TYPES: ['wu', 'es', 'nwm', 'ltc', 'rtc', 'european'],
CURRENT_USER_PREFIX: 'me'
};
10 changes: 9 additions & 1 deletion lib/events.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const errors = require('./errors');
const merge = require('./merge');
const constants = require('./constants');
const helpers = require('./helpers');
const { Event, Application } = require('../models');
const { Sequelize } = require('./sequelize');
Expand Down Expand Up @@ -152,7 +153,14 @@ exports.addEvent = async (req, res) => {
};

exports.eventDetails = async (req, res) => {
const event = req.event.toJSON();
let event = req.event.toJSON();

// Some fields shouldn't be public and only should be displayed to EQAC/CD/admins/organizers.
if (!helpers.isOrganizer(event, req.user)
&& !req.permissions.manage_event[event.type]
&& !req.permissions.approve_event[event.type]) {
event = helpers.whitelistObject(event, constants.EVENT_PUBLIC_FIELDS);
}

return res.json({
success: true,
Expand Down
13 changes: 12 additions & 1 deletion lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ exports.getDefaultQuery = (req) => {
// Default filter is empty.
const queryObj = {
where: {},
order: [['starts', 'ASC']]
order: [['starts', 'ASC']],
select: constants.EVENT_PUBLIC_FIELDS
};

// If search is set, searching for event by name or description case-insensitive.
Expand Down Expand Up @@ -115,6 +116,16 @@ exports.beautify = (value) => {
return value;
};

// A helper to whilelist object's properties.
exports.whitelistObject = (object, allowedFields) => {
const newObject = {};
for (const field of allowedFields) {
newObject[field] = object[field];
}

return newObject;
};

// A helper to get the names for application fields. Useful for exporting for getting columns headers.
exports.getApplicationFields = (event) => {
const fields = { ...constants.APPLICATION_FIELD_NAMES };
Expand Down
76 changes: 76 additions & 0 deletions test/api/events-approval.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,80 @@ describe('Events approval', () => {
const eventFromDb = await Event.findByPk(event.id);
expect(eventFromDb.status).not.toEqual('published');
});

it('should not allow changing status from draft if budget is null', async () => {
const event = await generator.createEvent({
status: 'draft',
budget: null
});

const res = await request({
uri: '/single/' + event.id + '/status',
headers: { 'X-Auth-Token': 'foobar' },
method: 'PUT',
body: { status: 'published' }
});

expect(res.statusCode).toEqual(422);
expect(res.body.success).toEqual(false);
expect(res.body).toHaveProperty('errors');
expect(res.body.errors).toHaveProperty('is_budget_set');
});

it('should not allow changing status from draft if budget is empty', async () => {
const event = await generator.createEvent({
status: 'draft',
budget: '\t\t\t \t \t'
});

const res = await request({
uri: '/single/' + event.id + '/status',
headers: { 'X-Auth-Token': 'foobar' },
method: 'PUT',
body: { status: 'published' }
});

expect(res.statusCode).toEqual(422);
expect(res.body.success).toEqual(false);
expect(res.body).toHaveProperty('errors');
expect(res.body.errors).toHaveProperty('is_budget_set');
});

it('should not allow changing status from draft if programme is null', async () => {
const event = await generator.createEvent({
status: 'draft',
programme: null
});

const res = await request({
uri: '/single/' + event.id + '/status',
headers: { 'X-Auth-Token': 'foobar' },
method: 'PUT',
body: { status: 'published' }
});

expect(res.statusCode).toEqual(422);
expect(res.body.success).toEqual(false);
expect(res.body).toHaveProperty('errors');
expect(res.body.errors).toHaveProperty('is_programme_set');
});

it('should not allow changing status from draft if programme is empty', async () => {
const event = await generator.createEvent({
status: 'draft',
programme: '\t\t\t \t \t'
});

const res = await request({
uri: '/single/' + event.id + '/status',
headers: { 'X-Auth-Token': 'foobar' },
method: 'PUT',
body: { status: 'published' }
});

expect(res.statusCode).toEqual(422);
expect(res.body.success).toEqual(false);
expect(res.body).toHaveProperty('errors');
expect(res.body.errors).toHaveProperty('is_programme_set');
});
});
21 changes: 21 additions & 0 deletions test/api/events-details.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,25 @@ describe('Events details', () => {

expect(res.statusCode).toEqual(404);
});

it('should not return special fields if the user does not have rights', async () => {
mock.mockAll({ mainPermissions: { noPermissions: true } });

const event = await generator.createEvent({
organizers: [{ user_id: 1337, first_name: 'test', last_name: 'test' }]
});
const res = await request({
uri: '/single/' + event.id,
headers: { 'X-Auth-Token': 'foobar' },
method: 'GET'
});

expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty('data');
expect(res.body.data).not.toHaveProperty('organizers');
expect(res.body.data).not.toHaveProperty('budget');
expect(res.body.data).not.toHaveProperty('programme');
expect(res.body.data).not.toHaveProperty('status');
expect(res.body.data).not.toHaveProperty('deleted');
});
});

0 comments on commit fa142b5

Please sign in to comment.