From 25999a6dfd98629df2807745f067bc0021420ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 3 Jun 2019 19:04:40 +0200 Subject: [PATCH 1/3] Bug fix for User can delete Comments of others Wrote a Jest test for this. --- .../src/middleware/permissionsMiddleware.js | 8 +- backend/src/resolvers/comments.spec.js | 192 ++++++++++++++---- 2 files changed, 151 insertions(+), 49 deletions(-) diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index ea4ba3dd2..bc9b4c525 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -60,14 +60,14 @@ const isAuthor = rule({ })(async (parent, args, { user, driver }) => { if (!user) return false const session = driver.session() - const { id: postId } = args + const { id: resourceId } = args const result = await session.run( ` - MATCH (post:Post {id: $postId})<-[:WROTE]-(author) + MATCH (resource {id: $resourceId})<-[:WROTE]-(author) RETURN author `, { - postId, + resourceId, }, ) const [author] = result.records.map(record => { @@ -113,7 +113,7 @@ const permissions = shield({ enable: isModerator, disable: isModerator, CreateComment: isAuthenticated, - DeleteComment: isAuthenticated, + DeleteComment: isAuthor, // CreateUser: allow, }, User: { diff --git a/backend/src/resolvers/comments.spec.js b/backend/src/resolvers/comments.spec.js index e3bf00528..0c71a2a51 100644 --- a/backend/src/resolvers/comments.spec.js +++ b/backend/src/resolvers/comments.spec.js @@ -213,14 +213,14 @@ describe('CreateComment', () => { }) describe('DeleteComment', () => { - const createCommentMutation = gql` - mutation($postId: ID, $content: String!) { - CreateComment(postId: $postId, content: $content) { - id - content - } - } - ` + // const createCommentMutation = gql` + // mutation($postId: ID, $content: String!) { + // CreateComment(postId: $postId, content: $content) { + // id + // content + // } + // } + // ` const deleteCommentMutation = gql` mutation($id: ID!) { DeleteComment(id: $id) { @@ -228,18 +228,41 @@ describe('DeleteComment', () => { } } ` - const createPostMutation = gql` - mutation($id: ID!, $title: String!, $content: String!) { - CreatePost(id: $id, title: $title, content: $content) { - id - } - } - ` + // const createPostMutation = gql` + // mutation($id: ID!, $title: String!, $content: String!) { + // CreatePost(id: $id, title: $title, content: $content) { + // id + // } + // } + // ` + + let deleteCommentVariables = { + id: 'c1', + } + + beforeEach(async () => { + const asAuthor = Factory() + await asAuthor.create('User', { + email: 'author@example.org', + password: '1234', + }) + await asAuthor.authenticateAs({ + email: 'author@example.org', + password: '1234', + }) + await asAuthor.create('Post', { + id: 'p1', + content: 'Post to be commented', + }) + await asAuthor.create('Comment', { + id: 'c1', + postId: 'p1', + content: 'Comment to be deleted', + }) + }) + describe('unauthenticated', () => { it('throws authorization error', async () => { - deleteCommentVariables = { - id: 'c1', - } client = new GraphQLClient(host) await expect(client.request(deleteCommentMutation, deleteCommentVariables)).rejects.toThrow( 'Not Authorised', @@ -247,9 +270,9 @@ describe('DeleteComment', () => { }) }) - describe('authenticated', () => { - let headers + describe('authenticated but not the author', () => { beforeEach(async () => { + let headers headers = await login({ email: 'test@example.org', password: '1234', @@ -257,38 +280,117 @@ describe('DeleteComment', () => { client = new GraphQLClient(host, { headers, }) - createCommentVariables = { - id: 'c1', - postId: 'p1', - content: "I'm authorised to comment", - } - deleteCommentVariables = { - id: 'c1', - } - createPostVariables = { - id: 'p1', - title: 'post to comment on', - content: 'please comment on me', - } - await client.request(createPostMutation, createPostVariables) }) - it('deletes the authors comment', async () => { - const { CreateComment } = await client.request(createCommentMutation, createCommentVariables) + it('throws authorization error', async () => { + await expect(client.request(deleteCommentMutation, deleteCommentVariables)).rejects.toThrow( + 'Not Authorised', + ) + }) + }) - deleteCommentVariables = { - id: CreateComment.id, - } + describe('authenticated as author', () => { + beforeEach(async () => { + let headers + headers = await login({ + email: 'author@example.org', + password: '1234', + }) + client = new GraphQLClient(host, { + headers, + }) + }) + + it('deletes the comment', async () => { const expected = { DeleteComment: { - id: CreateComment.id, + id: 'c1', }, } - await expect( - client.request(deleteCommentMutation, deleteCommentVariables), - ).resolves.toMatchObject(expected) + await expect(client.request(deleteCommentMutation, deleteCommentVariables)).resolves.toEqual( + expected, + ) }) - - it.todo('throws an error if it tries to delete a comment not from this author') }) }) + +// describe('DeleteComment', () => { +// const createCommentMutation = gql` +// mutation($postId: ID, $content: String!) { +// CreateComment(postId: $postId, content: $content) { +// id +// content +// } +// } +// ` +// const deleteCommentMutation = gql` +// mutation($id: ID!) { +// DeleteComment(id: $id) { +// id +// } +// } +// ` +// const createPostMutation = gql` +// mutation($id: ID!, $title: String!, $content: String!) { +// CreatePost(id: $id, title: $title, content: $content) { +// id +// } +// } +// ` +// describe('unauthenticated', () => { +// it('throws authorization error', async () => { +// deleteCommentVariables = { +// id: 'c1', +// } +// client = new GraphQLClient(host) +// await expect(client.request(deleteCommentMutation, deleteCommentVariables)).rejects.toThrow( +// 'Not Authorised', +// ) +// }) +// }) + +// describe('authenticated', () => { +// let headers +// beforeEach(async () => { +// headers = await login({ +// email: 'test@example.org', +// password: '1234', +// }) +// client = new GraphQLClient(host, { +// headers, +// }) +// createCommentVariables = { +// id: 'c1', +// postId: 'p1', +// content: "I'm authorised to comment", +// } +// deleteCommentVariables = { +// id: 'c1', +// } +// createPostVariables = { +// id: 'p1', +// title: 'post to comment on', +// content: 'please comment on me', +// } +// await client.request(createPostMutation, createPostVariables) +// }) + +// it('deletes the authors comment', async () => { +// const { CreateComment } = await client.request(createCommentMutation, createCommentVariables) + +// deleteCommentVariables = { +// id: CreateComment.id, +// } +// const expected = { +// DeleteComment: { +// id: CreateComment.id, +// }, +// } +// await expect( +// client.request(deleteCommentMutation, deleteCommentVariables), +// ).resolves.toMatchObject(expected) +// }) + +// it.todo('throws an error if it tries to delete a comment not from this author') +// }) +// }) From 62993cc3e901423020fcb28bbdf2b63213310a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 3 Jun 2019 19:05:59 +0200 Subject: [PATCH 2/3] Clean up --- backend/src/resolvers/comments.spec.js | 96 -------------------------- 1 file changed, 96 deletions(-) diff --git a/backend/src/resolvers/comments.spec.js b/backend/src/resolvers/comments.spec.js index 0c71a2a51..b83fdbfc9 100644 --- a/backend/src/resolvers/comments.spec.js +++ b/backend/src/resolvers/comments.spec.js @@ -213,14 +213,6 @@ describe('CreateComment', () => { }) describe('DeleteComment', () => { - // const createCommentMutation = gql` - // mutation($postId: ID, $content: String!) { - // CreateComment(postId: $postId, content: $content) { - // id - // content - // } - // } - // ` const deleteCommentMutation = gql` mutation($id: ID!) { DeleteComment(id: $id) { @@ -228,13 +220,6 @@ describe('DeleteComment', () => { } } ` - // const createPostMutation = gql` - // mutation($id: ID!, $title: String!, $content: String!) { - // CreatePost(id: $id, title: $title, content: $content) { - // id - // } - // } - // ` let deleteCommentVariables = { id: 'c1', @@ -313,84 +298,3 @@ describe('DeleteComment', () => { }) }) }) - -// describe('DeleteComment', () => { -// const createCommentMutation = gql` -// mutation($postId: ID, $content: String!) { -// CreateComment(postId: $postId, content: $content) { -// id -// content -// } -// } -// ` -// const deleteCommentMutation = gql` -// mutation($id: ID!) { -// DeleteComment(id: $id) { -// id -// } -// } -// ` -// const createPostMutation = gql` -// mutation($id: ID!, $title: String!, $content: String!) { -// CreatePost(id: $id, title: $title, content: $content) { -// id -// } -// } -// ` -// describe('unauthenticated', () => { -// it('throws authorization error', async () => { -// deleteCommentVariables = { -// id: 'c1', -// } -// client = new GraphQLClient(host) -// await expect(client.request(deleteCommentMutation, deleteCommentVariables)).rejects.toThrow( -// 'Not Authorised', -// ) -// }) -// }) - -// describe('authenticated', () => { -// let headers -// beforeEach(async () => { -// headers = await login({ -// email: 'test@example.org', -// password: '1234', -// }) -// client = new GraphQLClient(host, { -// headers, -// }) -// createCommentVariables = { -// id: 'c1', -// postId: 'p1', -// content: "I'm authorised to comment", -// } -// deleteCommentVariables = { -// id: 'c1', -// } -// createPostVariables = { -// id: 'p1', -// title: 'post to comment on', -// content: 'please comment on me', -// } -// await client.request(createPostMutation, createPostVariables) -// }) - -// it('deletes the authors comment', async () => { -// const { CreateComment } = await client.request(createCommentMutation, createCommentVariables) - -// deleteCommentVariables = { -// id: CreateComment.id, -// } -// const expected = { -// DeleteComment: { -// id: CreateComment.id, -// }, -// } -// await expect( -// client.request(deleteCommentMutation, deleteCommentVariables), -// ).resolves.toMatchObject(expected) -// }) - -// it.todo('throws an error if it tries to delete a comment not from this author') -// }) -// }) From cc774b03b8f094f792b26b06895a4af51003218b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 3 Jun 2019 19:48:36 +0200 Subject: [PATCH 3/3] Lint Fix in Backend --- backend/src/resolvers/comments.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/resolvers/comments.spec.js b/backend/src/resolvers/comments.spec.js index b83fdbfc9..c0b65ee63 100644 --- a/backend/src/resolvers/comments.spec.js +++ b/backend/src/resolvers/comments.spec.js @@ -6,7 +6,6 @@ import { host, login } from '../jest/helpers' const factory = Factory() let client let createCommentVariables -let deleteCommentVariables let createPostVariables let createCommentVariablesSansPostId let createCommentVariablesWithNonExistentPost