Skip to content

Commit

Permalink
feat(general): checking permissions for join requests
Browse files Browse the repository at this point in the history
  • Loading branch information
serge1peshcoff committed Mar 12, 2020
1 parent 1a2b135 commit a6af726
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 13 deletions.
10 changes: 8 additions & 2 deletions middlewares/join-requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ const helpers = require('../lib/helpers');
const { sequelize } = require('../lib/sequelize');

exports.listAllJoinRequests = async (req, res) => {
// TODO: check permissions
if (!req.permissions.hasPermission('view:join_request')) {
return errors.makeForbiddenError(res, 'Permission view:join_request is required, but not present.');
}

const result = await JoinRequest.findAndCountAll({
where: { body_id: req.currentBody.id },
...helpers.getPagination(req.query),
Expand All @@ -31,7 +34,10 @@ exports.createJoinRequest = async (req, res) => {
};

exports.changeRequestStatus = async (req, res) => {
// TODO: check permissions
if (!req.permissions.hasPermission('process:join_request')) {
return errors.makeForbiddenError(res, 'Permission process:join_request is required, but not present.');
}

if (!['accepted', 'rejected'].includes(req.body.status)) {
return errors.makeBadRequestError(res, 'The status is invalid.');
}
Expand Down
2 changes: 2 additions & 0 deletions middlewares/memberships.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ exports.listAllMemberships = async (req, res) => {
};

exports.updateMembership = async (req, res) => {
// TODO: check permissions
await req.currentBodyMembership.update({ comment: req.body.comment });
return res.json({
success: true,
Expand All @@ -30,6 +31,7 @@ exports.updateMembership = async (req, res) => {
};

exports.deleteMembership = async (req, res) => {
// TODO: check permissions
// delete all join requests if any, so a person can reapply
await JoinRequest.destroy({
where: {
Expand Down
57 changes: 54 additions & 3 deletions test/api/join-requests-listing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ describe('Join requests list', () => {
});

test('should succeed when everything is okay', async () => {
const user = await generator.createUser({ password: 'test', mail_confirmed_at: new Date() });
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();
const joinRequest = await generator.createJoinRequest(body, user);

await generator.createPermission({ scope: 'global', action: 'view', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests',
method: 'GET',
Expand All @@ -38,10 +40,12 @@ describe('Join requests list', () => {
});

test('should respect limit and offset', async () => {
const user = await generator.createUser({ password: 'test', mail_confirmed_at: new Date() });
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);
const body = await generator.createBody();

await generator.createPermission({ scope: 'global', action: 'view', object: 'join_request' });

const firstUser = await generator.createUser();
await generator.createJoinRequest(body, firstUser);

Expand Down Expand Up @@ -69,7 +73,7 @@ describe('Join requests list', () => {
});

test('should respect sorting', async () => {
const user = await generator.createUser({ password: 'test', mail_confirmed_at: new Date() });
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);
const body = await generator.createBody();

Expand All @@ -79,6 +83,8 @@ describe('Join requests list', () => {
const secondUser = await generator.createUser();
const secondJoinRequest = await generator.createJoinRequest(body, secondUser);

await generator.createPermission({ scope: 'global', action: 'view', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests?sort=id&direction=desc', // second one should be returned
method: 'GET',
Expand All @@ -95,4 +101,49 @@ describe('Join requests list', () => {
expect(res.body.data[0].id).toEqual(secondJoinRequest.id);
expect(res.body.data[1].id).toEqual(firstJoinRequest.id);
});

test('should work with local permission', async () => {
const user = await generator.createUser();
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();
const joinRequest = await generator.createJoinRequest(body, user);

const permission = await generator.createPermission({ scope: 'local', action: 'view', object: 'join_request' });
const circle = await generator.createCircle({ body_id: body.id });
await generator.createCirclePermission(circle, permission);
await generator.createCircleMembership(circle, user);

const res = await request({
uri: '/bodies/' + body.id + '/join-requests',
method: 'GET',
headers: { 'X-Auth-Token': token.value }
});

expect(res.statusCode).toEqual(200);
expect(res.body.success).toEqual(true);
expect(res.body).toHaveProperty('data');
expect(res.body).not.toHaveProperty('errors');

expect(res.body.data.length).toEqual(1);
expect(res.body.data[0].id).toEqual(joinRequest.id);
});

test('should succeed when everything is okay', async () => {
const user = await generator.createUser();
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();

const res = await request({
uri: '/bodies/' + body.id + '/join-requests',
method: 'GET',
headers: { 'X-Auth-Token': token.value }
});

expect(res.statusCode).toEqual(403);
expect(res.body.success).toEqual(false);
expect(res.body).toHaveProperty('message');
expect(res.body).not.toHaveProperty('data');
});
});
73 changes: 66 additions & 7 deletions test/api/join-requests-status.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ describe('Join request status', () => {

test('should return 400 if the request_id is invalid', async () => {
const body = await generator.createBody();
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

await generator.createPermission({ scope: 'global', action: 'process', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/lalala/status',
method: 'PUT',
Expand All @@ -36,9 +38,11 @@ describe('Join request status', () => {

test('should return 404 if the join request is not found', async () => {
const body = await generator.createBody();
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

await generator.createPermission({ scope: 'global', action: 'process', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/1337/status',
method: 'PUT',
Expand All @@ -53,12 +57,14 @@ describe('Join request status', () => {
});

test('should fail if the status is invalid', async () => {
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();
const joinRequest = await generator.createJoinRequest(body, user);

await generator.createPermission({ scope: 'global', action: 'process', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/' + joinRequest.id + '/status',
method: 'PUT',
Expand All @@ -73,9 +79,11 @@ describe('Join request status', () => {
});

test('should fail if the status is not pending', async () => {
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

await generator.createPermission({ scope: 'global', action: 'process', object: 'join_request' });

const body = await generator.createBody();
const joinRequest = await JoinRequest.create({
body_id: body.id,
Expand All @@ -97,12 +105,14 @@ describe('Join request status', () => {
});

test('should succeed if everything is okay and the status is rejected', async () => {
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();
const joinRequest = await generator.createJoinRequest(body, user);

await generator.createPermission({ scope: 'global', action: 'process', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/' + joinRequest.id + '/status',
method: 'PUT',
Expand All @@ -120,12 +130,14 @@ describe('Join request status', () => {
});

test('should succeed if everything is okay and the status is accepted', async () => {
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();
const joinRequest = await generator.createJoinRequest(body, user);

await generator.createPermission({ scope: 'global', action: 'process', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/' + joinRequest.id + '/status',
method: 'PUT',
Expand All @@ -151,13 +163,15 @@ describe('Join request status', () => {
});

test('should add the person to a shadow circle', async () => {
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

const circle = await generator.createCircle();
const body = await generator.createBody({ shadow_circle_id: circle.id });
const joinRequest = await generator.createJoinRequest(body, user);

await generator.createPermission({ scope: 'global', action: 'process', object: 'join_request' });

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/' + joinRequest.id + '/status',
method: 'PUT',
Expand All @@ -178,4 +192,49 @@ describe('Join request status', () => {
});
expect(membershipFromDb).not.toEqual(null);
});

test('should work with local permission', async () => {
const user = await generator.createUser();
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();
const joinRequest = await generator.createJoinRequest(body, user);

const circle = await generator.createCircle({ body_id: body.id });
const permission = await generator.createPermission({ scope: 'local', action: 'process', object: 'join_request' });
await generator.createCircleMembership(circle, user);
await generator.createCirclePermission(circle, permission);

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/' + joinRequest.id + '/status',
method: 'PUT',
headers: { 'X-Auth-Token': token.value },
body: { status: 'accepted' }
});

expect(res.statusCode).toEqual(200);
expect(res.body.success).toEqual(true);
expect(res.body).not.toHaveProperty('errors');
expect(res.body).toHaveProperty('message');
});

test('should fail if no permission', async () => {
const user = await generator.createUser();
const token = await generator.createAccessToken({}, user);

const body = await generator.createBody();
const joinRequest = await generator.createJoinRequest(body, user);

const res = await request({
uri: '/bodies/' + body.id + '/join-requests/' + joinRequest.id + '/status',
method: 'PUT',
headers: { 'X-Auth-Token': token.value },
body: { status: 'accepted' }
});

expect(res.statusCode).toEqual(403);
expect(res.body.success).toEqual(false);
expect(res.body).not.toHaveProperty('data');
expect(res.body).toHaveProperty('message');
});
});
2 changes: 1 addition & 1 deletion test/api/users-editing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('User editing', () => {

expect(res.statusCode).toEqual(200);
expect(res.body.success).toEqual(true);
expect(res.body).not.toHaveProperty('errrors');
expect(res.body).not.toHaveProperty('errors');
expect(res.body).toHaveProperty('data');
expect(res.body.data.email).not.toEqual('test@test.io');
});
Expand Down

0 comments on commit a6af726

Please sign in to comment.