From 180491c08caef423c48ee413faed7b6bb9fbd3e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=A4fer?= Date: Mon, 4 Mar 2019 19:40:49 +0100 Subject: [PATCH] Put `isAuthor` in permissions middleware I find it dirty to access the database in a middleware, ie. I would like to put all access on the database as close to the resolver as possible. However, in this case that would mean to put the authorization check in the resolver, where nobody expects it to be. CC @appinteractive --- src/middleware/permissionsMiddleware.js | 18 ++++++++++++++++++ src/resolvers/posts.js | 24 ------------------------ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/middleware/permissionsMiddleware.js b/src/middleware/permissionsMiddleware.js index b755f3bab..c40803e00 100644 --- a/src/middleware/permissionsMiddleware.js +++ b/src/middleware/permissionsMiddleware.js @@ -25,6 +25,22 @@ const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, i return !(disabled || deleted) }) +const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => { + if (!user) return false + const session = driver.session() + const { id: postId } = args + const result = await session.run(` + MATCH (post:Post {id: $postId})<-[:WROTE]-(author) + RETURN author + `, { postId }) + const [author] = result.records.map((record) => { + return record.get('author') + }) + const { properties: { id: authorId } } = author + session.close() + return authorId === user.id +}) + // Permissions const permissions = shield({ Query: { @@ -34,6 +50,8 @@ const permissions = shield({ }, Mutation: { CreatePost: isAuthenticated, + UpdatePost: isAuthor, + DeletePost: isAuthor, report: isAuthenticated, CreateBadge: isAdmin, UpdateBadge: isAdmin, diff --git a/src/resolvers/posts.js b/src/resolvers/posts.js index f59050b5f..abf91e047 100644 --- a/src/resolvers/posts.js +++ b/src/resolvers/posts.js @@ -1,21 +1,5 @@ import { neo4jgraphql } from 'neo4j-graphql-js' -const isAuthor = async (params, { user, driver }) => { - if (!user) return false - const session = driver.session() - const { id: postId } = params - const result = await session.run(` - MATCH (post:Post {id: $postId})<-[:WROTE]-(author) - RETURN author - `, { postId }) - const [author] = result.records.map((record) => { - return record.get('author') - }) - const { properties: { id: authorId } } = author - session.close() - return authorId === user.id -} - export default { Mutation: { CreatePost: async (object, params, context, resolveInfo) => { @@ -32,14 +16,6 @@ export default { session.close() return result - }, - UpdatePost: async (object, params, context, resolveInfo) => { - if (!await isAuthor(params, context)) return Error('Not Authorised!') - return neo4jgraphql(object, params, context, resolveInfo, false) - }, - DeletePost: async (object, params, context, resolveInfo) => { - if (!await isAuthor(params, context)) return Error('Not Authorised!') - return neo4jgraphql(object, params, context, resolveInfo, false) } } }