diff --git a/models/user.js b/models/user.js index 67d479471..2b65bd300 100644 --- a/models/user.js +++ b/models/user.js @@ -178,6 +178,12 @@ UserSchema.method('can', function(...actions) { return false; } + // {add,remove}CommentTag - requires admin and/or moderator role + const userCanModifyTags = user => ['ADMIN', 'MODERATOR'].some(r => user.hasRoles(r)); + if (actions.some(a => ['mutation:removeCommentTag', 'mutation:addCommentTag'].includes(a)) && ! userCanModifyTags(this)) { + return false; + } + return true; }); diff --git a/test/graph/mutations/addCommentTag.js b/test/graph/mutations/addCommentTag.js index 25576a5f1..fcbb0d0e8 100644 --- a/test/graph/mutations/addCommentTag.js +++ b/test/graph/mutations/addCommentTag.js @@ -29,8 +29,8 @@ describe('graph.mutations.addCommentTag', () => { } `; - it('can add tags to comments', async () => { - const user = new UserModel({}); + it('moderators can add tags to comments', async () => { + const user = new UserModel({roles: ['MODERATOR' ]}); const context = new Context({user}); const response = await graphql(schema, query, {}, context, {id: comment.id, tag: 'BEST'}); if (response.errors && response.errors.length) { @@ -39,4 +39,24 @@ describe('graph.mutations.addCommentTag', () => { expect(response.errors).to.be.empty; expect(response.data.addCommentTag.comment.tags).to.deep.equal([{name: 'BEST'}]); }); + + describe('users who cant add tags', () => { + Object.entries({ + 'anonymous': undefined, + 'regular commenter': new UserModel({}), + 'banned moderator': new UserModel({roles: ['MODERATOR'], status: 'BANNED'}) + }).forEach(([ userDescription, user ]) => { + it(userDescription, async function () { + const context = new Context({user}); + const response = await graphql(schema, query, {}, context, {id: comment.id, tag: 'BEST'}); + if (response.errors && response.errors.length) { + console.error(response.errors); + } + expect(response.errors).to.be.empty; + expect(response.data.addCommentTag.errors).to.deep.equal([{'translation_key':'NOT_AUTHORIZED'}]); + expect(response.data.addCommentTag.comment).to.be.null; + }); + }); + }); + }); diff --git a/test/graph/mutations/removeCommentTag.js b/test/graph/mutations/removeCommentTag.js index fe60a0f4c..c10f70172 100644 --- a/test/graph/mutations/removeCommentTag.js +++ b/test/graph/mutations/removeCommentTag.js @@ -29,8 +29,8 @@ describe('graph.mutations.removeCommentTag', () => { } `; - it('can add remove tags from comments', async () => { - const user = new UserModel({}); + it('moderators can add remove tags from comments', async () => { + const user = new UserModel({roles: ['MODERATOR' ]}); const context = new Context({user}); // add a tag first @@ -40,6 +40,30 @@ describe('graph.mutations.removeCommentTag', () => { console.error(response.errors); } expect(response.errors).to.be.empty; + expect(response.data.removeCommentTag.errors).to.be.null; expect(response.data.removeCommentTag.comment.tags).to.deep.equal([]); }); + + describe('users who cant remove tags', () => { + Object.entries({ + 'anonymous': undefined, + 'regular commenter': new UserModel({}), + 'banned moderator': new UserModel({roles: ['MODERATOR'], status: 'BANNED'}) + }).forEach(([ userDescription, user ]) => { + it(userDescription, async function () { + const context = new Context({user}); + + // add a tag first + await CommentsService.addTag(comment.id, 'BEST'); + const response = await graphql(schema, query, {}, context, {id: comment.id, tag: 'BEST'}); + if (response.errors && response.errors.length) { + console.error(response.errors); + } + expect(response.errors).to.be.empty; + expect(response.data.removeCommentTag.errors).to.deep.equal([{'translation_key':'NOT_AUTHORIZED'}]); + expect(response.data.removeCommentTag.comment).to.be.null; + }); + }); + }); + });