From 0e6b6b45e03da9b1403e32b19e30d32a6e293089 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Tue, 22 Nov 2022 17:52:20 +0530 Subject: [PATCH 1/3] Directive Resolvers Designed --- api/schema/helpers/projectIdFetcher.js | 15 ++++++++ api/schema/index.js | 6 ++-- api/schema/resolvers/DirectiveResolvers.js | 40 ++++++++++++++++++++++ api/schema/types/AllocationType.js | 5 +-- api/schema/types/ClientType.js | 13 +++---- api/schema/types/ProjectType.js | 3 +- api/schema/types/RateType.js | 1 + server.js | 10 +++--- 8 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 api/schema/helpers/projectIdFetcher.js create mode 100644 api/schema/resolvers/DirectiveResolvers.js diff --git a/api/schema/helpers/projectIdFetcher.js b/api/schema/helpers/projectIdFetcher.js new file mode 100644 index 00000000..73e958b7 --- /dev/null +++ b/api/schema/helpers/projectIdFetcher.js @@ -0,0 +1,15 @@ +const db = require('../../models') + +module.exports = (fieldName, id) => { + return { + getAllocationById: (id) => db.models.Allocation.findByPk(id).dataValues.project_id, + updateAllocationById: (id) => db.models.Allocation.findByPk(id).dataValues.project_id, + deleteAllocationById: (id) => db.models.Allocation.findByPk(id).dataValues.project_id, + getClientById: (id) => db.models.Client.findByPk(id).dataValues.project_id, + updateClientById: (id) => db.models.Client.findByPk(id).dataValues.project_id, + deleteClientById: (id) => db.models.Client.findByPk(id).dataValues.project_id, + getPaymentById: (id) => db.models.Payment.findByPk(id).dataValues.project_id, + updatePaymentById: (id) => db.models.Payment.findByPk(id).dataValues.project_id, + deletePaymentById: (id) => db.models.Payment.findByPk(id).dataValues.project_id, + } +} diff --git a/api/schema/index.js b/api/schema/index.js index 3bb2ee64..6be74a76 100644 --- a/api/schema/index.js +++ b/api/schema/index.js @@ -7,6 +7,7 @@ const ClientResolver = require('./resolvers/ClientResolver') const ContributionResolver = require('./resolvers/ContributionResolver') const ConfigResolver = require('./resolvers/ConfigResolver') const ContributorResolver = require('./resolvers/ContributorResolver') +const directiveResolvers = require('./resolvers/DirectiveResolvers') const IssueResolver = require('./resolvers/IssueResolver') const PaymentResolver = require('./resolvers/PaymentResolver') const PermissionResolver = require('./resolvers/PermissionResolver') @@ -25,7 +26,7 @@ const PaymentType = require('./types/PaymentType') const PermissionType = require('./types/PermissionType') const ProjectType = require('./types/ProjectType') const RateType = require('./types/RateType') -const TimeEntry = require('./types/TimeEntryType') +const TimeEntry = require('./types/TimeEntryType'); //merge types const typeDefs = mergeTypeDefs([ @@ -60,5 +61,6 @@ const resolvers = mergeResolvers([ // Export generated schema module.exports = makeExecutableSchema({ typeDefs, - resolvers + resolvers, + directiveResolvers }); diff --git a/api/schema/resolvers/DirectiveResolvers.js b/api/schema/resolvers/DirectiveResolvers.js new file mode 100644 index 00000000..1836bca8 --- /dev/null +++ b/api/schema/resolvers/DirectiveResolvers.js @@ -0,0 +1,40 @@ +const { AuthenticationError } = require('apollo-server'); +const Contribution = require('../../models/Contribution'); +const projectId = require('../helpers/projectIdFetcher') + +module.exports = { + authorizedContributor: async (next, src, args, { models, cookies }, operation ) => { + if (!cookies.userSession) { + return new Error('User not logged in') + } + return next('abc'); + }, + authorizedProjectContributor: async (next, src, args, { models, cookies }, operation) => { + //You get the contributor id of the contributor who needs access to that specific project. They are going to + const contributor_id = cookies.userSession + console.log(contributor_id) + const { project_id } = (operation.variableValues) + console.log(project_id) + const permission = await models.Permission.findOne({ where: { project_id: project_id, contributor_id: contributor_id } }) + if (!permission) { + return new Error('Contributor not authorized') + } + return next(); + }, + authorizedProjectAdmin: async (next, src, args, { models, cookies }, operation) => { + + const contributor_id = cookies.userSession + console.log(contributor_id) + const fieldName = operation.fieldName + console.log(fieldName) + const project_id = operation.fieldNodes[0].arguments[0].value.value + // const project_id = operation.fieldNodes[0].arguments[0].value.value + const permission = await models.Permission.findOne({ where: { project_id: project_id, contributor_id: contributor_id } }) + if (!permission) { + return new Error('Contributor not authorized') + } else if ( permission.dataValues.type != 'owner' ) { + return new Error('Only Project Admin is authorized') + } + return next(); + }, +} diff --git a/api/schema/types/AllocationType.js b/api/schema/types/AllocationType.js index 8a18aaef..db2dd257 100644 --- a/api/schema/types/AllocationType.js +++ b/api/schema/types/AllocationType.js @@ -1,6 +1,7 @@ const { gql } = require('apollo-server') //TODO: Change this when rates table added module.exports = gql` + directive @authorizedProjectAdmin on FIELD_DEFINITION type Allocation { id: Int! @@ -45,8 +46,8 @@ module.exports = gql` } type Query { - getAllocationById(id: Int!): Allocation - getAllocations(contributorId: Int, projectId: Int): [Allocation] + getAllocationById(id: Int!): Allocation + getAllocations(contributorId: Int, projectId: Int): [Allocation] } type Mutation { diff --git a/api/schema/types/ClientType.js b/api/schema/types/ClientType.js index 34c0771f..7acf9056 100644 --- a/api/schema/types/ClientType.js +++ b/api/schema/types/ClientType.js @@ -1,6 +1,7 @@ const { gql } = require('apollo-server') module.exports = gql` + directive @authorizedContributor on FIELD_DEFINITION type Client { id: Int! @@ -34,12 +35,12 @@ module.exports = gql` } type Query { - getClientById(id: Int!): Client - getClients: [Client] - getActiveClients: [Client] - getInactiveClients: [Client] - getActiveClientsCount: Int! - getInactiveClientsCount: Int! + getClientById(id: Int!): Client @authorizedContributor + getClients: [Client] @authorizedContributor + getActiveClients: [Client] @authorizedProjectContributor + getInactiveClients: [Client] @authorizedContributor + getActiveClientsCount: Int! @authorizedContributor + getInactiveClientsCount: Int! @authorizedContributor } type Mutation { diff --git a/api/schema/types/ProjectType.js b/api/schema/types/ProjectType.js index 9ff22a0a..b6d81624 100644 --- a/api/schema/types/ProjectType.js +++ b/api/schema/types/ProjectType.js @@ -1,6 +1,7 @@ const { gql } = require('apollo-server') module.exports = gql` + directive @authorizedProjectContributor on FIELD_DEFINITION type Project { id: Int! @@ -121,7 +122,7 @@ module.exports = gql` } type Query { - getProjectById(id: Int!): Project + getProjectById(id: Int!): Project @authorizedProjectAdmin @authorizedContributor getProjects: [Project] getActiveProjects: [Project] getActiveProjectsCount(clientId: Int): Int! diff --git a/api/schema/types/RateType.js b/api/schema/types/RateType.js index 9eda961c..38c10763 100644 --- a/api/schema/types/RateType.js +++ b/api/schema/types/RateType.js @@ -1,6 +1,7 @@ const { gql } = require('apollo-server') module.exports = gql` + type Rate { id: Int! active: Boolean! diff --git a/server.js b/server.js index 43f9f5bf..28a84e26 100644 --- a/server.js +++ b/server.js @@ -235,10 +235,12 @@ app.post('/api/webhooks/customer/delete', async (req, res) => { const server = new ApolloServer({ schema, - context: ({ req }) => ({ - ...db, - cookies: req.session - }), + context: ({ req }) => { + return { + ...db, + cookies: req.session + } + }, introspection: true, playground: { settings: { From db40522892249866007cb2493902cd8519c5943c Mon Sep 17 00:00:00 2001 From: Rishabh Date: Wed, 30 Nov 2022 19:56:02 +0530 Subject: [PATCH 2/3] `project_id` fetching added --- api/models/Allocation.js | 6 ++++-- api/schema/helpers/projectIdFetcher.js | 24 ++++++++++++---------- api/schema/resolvers/DirectiveResolvers.js | 17 ++++++++------- api/schema/types/AllocationType.js | 2 +- api/schema/types/ClientType.js | 12 +++++------ api/schema/types/ProjectType.js | 2 +- 6 files changed, 33 insertions(+), 30 deletions(-) diff --git a/api/models/Allocation.js b/api/models/Allocation.js index 2d163abb..e9f4df16 100644 --- a/api/models/Allocation.js +++ b/api/models/Allocation.js @@ -66,12 +66,14 @@ module.exports = (sequelize) => { } }, status: { + defaultValue: 'active', type: DataTypes.STRING, - allowNull: false + allowNull: true }, proposed_by_contributor_id: { + defaultValue: 1, type: DataTypes.INTEGER, - allowNull: false, + allowNull: true, references: { model: 'Contributors', key: 'id', diff --git a/api/schema/helpers/projectIdFetcher.js b/api/schema/helpers/projectIdFetcher.js index 73e958b7..76692b70 100644 --- a/api/schema/helpers/projectIdFetcher.js +++ b/api/schema/helpers/projectIdFetcher.js @@ -1,15 +1,17 @@ const db = require('../../models') -module.exports = (fieldName, id) => { - return { - getAllocationById: (id) => db.models.Allocation.findByPk(id).dataValues.project_id, - updateAllocationById: (id) => db.models.Allocation.findByPk(id).dataValues.project_id, - deleteAllocationById: (id) => db.models.Allocation.findByPk(id).dataValues.project_id, - getClientById: (id) => db.models.Client.findByPk(id).dataValues.project_id, - updateClientById: (id) => db.models.Client.findByPk(id).dataValues.project_id, - deleteClientById: (id) => db.models.Client.findByPk(id).dataValues.project_id, - getPaymentById: (id) => db.models.Payment.findByPk(id).dataValues.project_id, - updatePaymentById: (id) => db.models.Payment.findByPk(id).dataValues.project_id, - deletePaymentById: (id) => db.models.Payment.findByPk(id).dataValues.project_id, +module.exports = async (fieldName, fieldId, operation) => { + if (fieldName == 'getProjectById') { + return fieldId + } + if (fieldName == 'getAllocationById' || fieldName == 'updateAllocationById' || fieldName == 'deleteAllocationByI') { + console.log(await db.models.Allocation.findByPk(fieldId).dataValues.project_id) + return db.models.Allocation.findByPk(fieldId).dataValues.project_id + } + if (fieldName == 'getClientById' || fieldName == 'updateClientById' || fieldName == 'deleteClientByI') { + return db.models.Client.findByPk(fieldId).dataValues.project_id + } + if (fieldName == 'getPaymentById' || fieldName == 'updatePaymentById' || fieldName == 'deletePaymentById') { + return db.models.Payment.findByPk(fieldId).dataValues.project_id } } diff --git a/api/schema/resolvers/DirectiveResolvers.js b/api/schema/resolvers/DirectiveResolvers.js index 1836bca8..63bcfc74 100644 --- a/api/schema/resolvers/DirectiveResolvers.js +++ b/api/schema/resolvers/DirectiveResolvers.js @@ -1,19 +1,17 @@ -const { AuthenticationError } = require('apollo-server'); -const Contribution = require('../../models/Contribution'); -const projectId = require('../helpers/projectIdFetcher') +const fetchProjectId = require('../helpers/projectIdFetcher') module.exports = { authorizedContributor: async (next, src, args, { models, cookies }, operation ) => { if (!cookies.userSession) { return new Error('User not logged in') } - return next('abc'); + return next(); }, authorizedProjectContributor: async (next, src, args, { models, cookies }, operation) => { - //You get the contributor id of the contributor who needs access to that specific project. They are going to + //You get the contributor id of the contributor who needs access to that specific project const contributor_id = cookies.userSession + const project_id = operation.fieldNodes[0].arguments[0].value.value console.log(contributor_id) - const { project_id } = (operation.variableValues) console.log(project_id) const permission = await models.Permission.findOne({ where: { project_id: project_id, contributor_id: contributor_id } }) if (!permission) { @@ -24,11 +22,12 @@ module.exports = { authorizedProjectAdmin: async (next, src, args, { models, cookies }, operation) => { const contributor_id = cookies.userSession - console.log(contributor_id) + console.log(operation.variableValues.id) const fieldName = operation.fieldName + const fieldId = operation.variableValues.id + // const fieldId = operation.fieldNodes[0].arguments[0].value.value + const project_id = fetchProjectId(fieldName, fieldId, operation) console.log(fieldName) - const project_id = operation.fieldNodes[0].arguments[0].value.value - // const project_id = operation.fieldNodes[0].arguments[0].value.value const permission = await models.Permission.findOne({ where: { project_id: project_id, contributor_id: contributor_id } }) if (!permission) { return new Error('Contributor not authorized') diff --git a/api/schema/types/AllocationType.js b/api/schema/types/AllocationType.js index db2dd257..7e62a5af 100644 --- a/api/schema/types/AllocationType.js +++ b/api/schema/types/AllocationType.js @@ -46,7 +46,7 @@ module.exports = gql` } type Query { - getAllocationById(id: Int!): Allocation + getAllocationById(id: Int!): Allocation @authorizedProjectAdmin getAllocations(contributorId: Int, projectId: Int): [Allocation] } diff --git a/api/schema/types/ClientType.js b/api/schema/types/ClientType.js index 7acf9056..9931a1b5 100644 --- a/api/schema/types/ClientType.js +++ b/api/schema/types/ClientType.js @@ -35,12 +35,12 @@ module.exports = gql` } type Query { - getClientById(id: Int!): Client @authorizedContributor - getClients: [Client] @authorizedContributor - getActiveClients: [Client] @authorizedProjectContributor - getInactiveClients: [Client] @authorizedContributor - getActiveClientsCount: Int! @authorizedContributor - getInactiveClientsCount: Int! @authorizedContributor + getClientById(id: Int!): Client + getClients: [Client] + getActiveClients: [Client] + getInactiveClients: [Client] + getActiveClientsCount: Int! + getInactiveClientsCount: Int! } type Mutation { diff --git a/api/schema/types/ProjectType.js b/api/schema/types/ProjectType.js index b6d81624..ad1dac98 100644 --- a/api/schema/types/ProjectType.js +++ b/api/schema/types/ProjectType.js @@ -122,7 +122,7 @@ module.exports = gql` } type Query { - getProjectById(id: Int!): Project @authorizedProjectAdmin @authorizedContributor + getProjectById(id: Int!): Project @authorizedProjectAdmin getProjects: [Project] getActiveProjects: [Project] getActiveProjectsCount(clientId: Int): Int! From bcb9062e697ff34d87260d5c2182f0ee46b28895 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Wed, 30 Nov 2022 20:25:32 +0530 Subject: [PATCH 3/3] Async removed from projectFetching --- api/schema/helpers/projectIdFetcher.js | 4 ++-- api/schema/resolvers/DirectiveResolvers.js | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/api/schema/helpers/projectIdFetcher.js b/api/schema/helpers/projectIdFetcher.js index 76692b70..953231d3 100644 --- a/api/schema/helpers/projectIdFetcher.js +++ b/api/schema/helpers/projectIdFetcher.js @@ -1,11 +1,11 @@ const db = require('../../models') -module.exports = async (fieldName, fieldId, operation) => { +module.exports = (fieldName, fieldId, operation) => { if (fieldName == 'getProjectById') { return fieldId } if (fieldName == 'getAllocationById' || fieldName == 'updateAllocationById' || fieldName == 'deleteAllocationByI') { - console.log(await db.models.Allocation.findByPk(fieldId).dataValues.project_id) + console.log( db.models.Allocation.findByPk(fieldId).dataValues.project_id) return db.models.Allocation.findByPk(fieldId).dataValues.project_id } if (fieldName == 'getClientById' || fieldName == 'updateClientById' || fieldName == 'deleteClientByI') { diff --git a/api/schema/resolvers/DirectiveResolvers.js b/api/schema/resolvers/DirectiveResolvers.js index 63bcfc74..320dbed1 100644 --- a/api/schema/resolvers/DirectiveResolvers.js +++ b/api/schema/resolvers/DirectiveResolvers.js @@ -22,12 +22,13 @@ module.exports = { authorizedProjectAdmin: async (next, src, args, { models, cookies }, operation) => { const contributor_id = cookies.userSession - console.log(operation.variableValues.id) const fieldName = operation.fieldName const fieldId = operation.variableValues.id // const fieldId = operation.fieldNodes[0].arguments[0].value.value const project_id = fetchProjectId(fieldName, fieldId, operation) console.log(fieldName) + console.log(project_id) + console.log(contributor_id) const permission = await models.Permission.findOne({ where: { project_id: project_id, contributor_id: contributor_id } }) if (!permission) { return new Error('Contributor not authorized')