Skip to content

Commit

Permalink
feat(general): checking permissions for memberships
Browse files Browse the repository at this point in the history
  • Loading branch information
serge1peshcoff committed Mar 14, 2020
1 parent a6af726 commit 2813c1a
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 12 deletions.
16 changes: 13 additions & 3 deletions middlewares/memberships.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ const {
User
} = require('../models');
const helpers = require('../lib/helpers');
const errors = require('../lib/errors');

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

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

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

await req.currentBodyMembership.update({ comment: req.body.comment });
return res.json({
success: true,
Expand All @@ -31,7 +38,10 @@ exports.updateMembership = async (req, res) => {
};

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

// delete all join requests if any, so a person can reapply
await JoinRequest.destroy({
where: {
Expand Down
54 changes: 51 additions & 3 deletions test/api/memberships-deleting.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ describe('Memberships deleting', () => {

test('should return 404 if the membership 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: 'delete_member', object: 'body' });

const res = await request({
uri: '/bodies/' + body.id + '/members/1337',
method: 'DELETE',
Expand All @@ -35,10 +37,12 @@ describe('Memberships deleting', () => {

test('should succeed if everything is okay', async () => {
const body = await generator.createBody();
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);
const membership = await generator.createBodyMembership(body, user);

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

const res = await request({
uri: '/bodies/' + body.id + '/members/' + membership.id,
method: 'DELETE',
Expand All @@ -57,9 +61,11 @@ describe('Memberships deleting', () => {
test('should remove user from any circles in this body', async () => {
const body = await generator.createBody();
const circle = await generator.createCircle({ body_id: body.id });
const user = await generator.createUser();
const user = await generator.createUser({ superadmin: true });
const token = await generator.createAccessToken({}, user);

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

const circleMembership = await generator.createCircleMembership(circle, user);
const membership = await generator.createBodyMembership(body, user);

Expand All @@ -77,4 +83,46 @@ describe('Memberships deleting', () => {
const membershipFromDb = await CircleMembership.findByPk(circleMembership.id);
expect(membershipFromDb).toEqual(null);
});

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

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

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


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 body = await generator.createBody();
const user = await generator.createUser();
const token = await generator.createAccessToken({}, user);
const membership = await generator.createBodyMembership(body, user);

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

expect(res.statusCode).toEqual(403);
expect(res.body.success).toEqual(false);
expect(res.body).not.toHaveProperty('data');
expect(res.body).toHaveProperty('message');
});
});
57 changes: 54 additions & 3 deletions test/api/memberships-editing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ describe('Membership editing', () => {

test('should return 400 if the membership_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: 'update_member', object: 'body' });

const res = await request({
uri: '/bodies/' + body.id + '/members/lalala',
method: 'PUT',
Expand All @@ -35,9 +37,11 @@ describe('Membership editing', () => {

test('should return 404 if the membership 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: 'update_member', object: 'body' });

const res = await request({
uri: '/bodies/' + body.id + '/members/1337',
method: 'PUT',
Expand All @@ -52,12 +56,14 @@ describe('Membership editing', () => {
});

test('should succeed if everything is okay', 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 membership = await generator.createBodyMembership(body, user);

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

const res = await request({
uri: '/bodies/' + body.id + '/members/' + membership.id,
method: 'PUT',
Expand All @@ -71,4 +77,49 @@ describe('Membership editing', () => {
expect(res.body).toHaveProperty('data');
expect(res.body.data.comment).toEqual('test');
});

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

const body = await generator.createBody();
const membership = await generator.createBodyMembership(body, user);

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

const res = await request({
uri: '/bodies/' + body.id + '/members/' + membership.id,
method: 'PUT',
headers: { 'X-Auth-Token': token.value },
body: { comment: 'test' }
});

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

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

const body = await generator.createBody();
const membership = await generator.createBodyMembership(body, user);

const res = await request({
uri: '/bodies/' + body.id + '/members/' + membership.id,
method: 'PUT',
headers: { 'X-Auth-Token': token.value },
body: { comment: 'test' }
});

expect(res.statusCode).toEqual(403);
expect(res.body.success).toEqual(false);
expect(res.body).not.toHaveProperty('data');
expect(res.body).toHaveProperty('message');
});
});
55 changes: 52 additions & 3 deletions test/api/memberships-listing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ describe('Memberships 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 membership = await generator.createBodyMembership(body, user);

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

const res = await request({
uri: '/bodies/' + body.id + '/members',
method: 'GET',
Expand All @@ -38,10 +40,12 @@ describe('Memberships 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_member', object: 'body' });

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

Expand Down Expand Up @@ -69,7 +73,7 @@ describe('Memberships 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('Memberships list', () => {
const secondUser = await generator.createUser();
const secondMembership = await generator.createBodyMembership(body, secondUser);

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

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

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

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

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

const res = await request({
uri: '/bodies/' + body.id + '/members',
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');
});

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

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

const res = await request({
uri: '/bodies/' + body.id + '/members',
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');
});
});

0 comments on commit 2813c1a

Please sign in to comment.