From 852d0b67493a2b9528dab248389c9ac92a90f738 Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Thu, 22 Aug 2019 11:49:20 +0200 Subject: [PATCH 1/4] Spec Fix Spec --- spec/ParseGraphQLServer.spec.js | 132 ++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index 5a3eccbb60..c378698433 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -4906,6 +4906,138 @@ describe('ParseGraphQLServer', () => { expect(Date.parse(getResult.data.get.updatedAt)).not.toEqual(NaN); }); + it('should support ACL', async () => { + const someClass = new Parse.Object('SomeClass'); + await someClass.save(); + + const user = new Parse.User(); + user.set('username', 'username'); + user.set('password', 'password'); + await user.signUp(); + + const role = new Parse.Role(); + role.set('name', 'aRole'); + await role.save(); + + await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear(); + + const { + data: { createSomeClass }, + } = await apolloClient.mutate({ + mutation: gql` + mutation Create($fields: CreateSomeClassFieldsInput) { + createSomeClass(fields: $fields) { + objectId + ACL { + users { + userId + read + write + } + roles { + roleName + read + write + } + public { + read + write + } + } + } + } + `, + variables: { + fields: { + ACL: { + users: [{ userId: user.id, read: true, write: true }], + roles: [{ roleName: 'aRole', read: true }], + public: { read: true }, + }, + }, + }, + }); + + const expectedCreateACL = { + users: [{ userId: user.id, read: true, write: true }], + roles: [{ roleName: 'aRole', read: true, write: null }], + public: { read: true, write: null }, + }; + + const query1 = new Parse.Query('SomeClass'); + const obj1 = (await query1.get(createSomeClass.objectId, { + useMasterKey: true, + })).toJSON(); + + expect(obj1.ACL['role:aRole']).toBeDefined(); + expect(obj1.ACL['role:aRole']).toEqual({ read: true }); + expect(obj1.ACL[user.id]).toBeDefined(); + expect(obj1.ACL[user.id]).toEqual({ read: true, write: true }); + expect(obj1.ACL['*']).toBeDefined(); + expect(obj1.ACL['*']).toEqual({ read: true }); + + expect(createSomeClass.objectId).toBeDefined(); + expect(createSomeClass.ACL).toEqual(expectedCreateACL); + + const { + data: { updateSomeClass }, + } = await apolloClient.mutate({ + mutation: gql` + mutation Update( + $objectId: ID + $fields: CreateSomeClassFieldsInput + ) { + updateSomeClass(objectId: $objectId, fields: $fields) { + objectId + ACL { + users { + userId + read + write + } + roles { + roleName + read + write + } + public { + read + write + } + } + } + } + `, + variables: { + objectId: createSomeClass.objectId, + fields: { + ACL: { + roles: [{ roleName: 'aRole', read: true, write: true }], + }, + }, + }, + }); + + const expectedUpdateACL = { + users: null, + roles: [{ roleName: 'aRole', read: true, write: true }], + public: null, + }; + + const query2 = new Parse.Query('SomeClass'); + const obj2 = (await query2.get(createSomeClass.objectId, { + useMasterKey: true, + })).toJSON(); + + expect(obj2.ACL['role:aRole']).toBeDefined(); + expect(obj2.ACL['role:aRole']).toEqual({ read: true, write: true }); + expect(obj2.ACL[user.id]).toBeUndefined(); + expect(obj2.ACL['*']).toBeUndefined(); + + expect(updateSomeClass.objectId).toBeDefined(); + expect(updateSomeClass.ACL).toEqual(expectedUpdateACL); + }); + it('should support pointer on create', async () => { const company = new Parse.Object('Company'); company.set('name', 'imACompany1'); From a0616eedb645c9bc50fd698baac2da3a6902b44a Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Sat, 31 Aug 2019 14:16:39 +0200 Subject: [PATCH 2/4] Add ACL Type + Input --- spec/ParseGraphQLServer.spec.js | 107 +++++++--- src/GraphQL/ParseGraphQLServer.js | 4 + src/GraphQL/loaders/defaultGraphQLTypes.js | 220 ++++++++++++++++++++- src/GraphQL/loaders/parseClassMutations.js | 5 +- src/GraphQL/loaders/parseClassTypes.js | 17 +- src/GraphQL/transformers/mutation.js | 39 ++++ 6 files changed, 343 insertions(+), 49 deletions(-) diff --git a/spec/ParseGraphQLServer.spec.js b/spec/ParseGraphQLServer.spec.js index a337a93169..25e167d4c7 100644 --- a/spec/ParseGraphQLServer.spec.js +++ b/spec/ParseGraphQLServer.spec.js @@ -4884,10 +4884,20 @@ describe('ParseGraphQLServer', () => { user.set('password', 'password'); await user.signUp(); - const role = new Parse.Role(); - role.set('name', 'aRole'); + const user2 = new Parse.User(); + user2.set('username', 'username2'); + user2.set('password', 'password2'); + await user2.signUp(); + + const roleACL = new Parse.ACL(); + roleACL.setPublicReadAccess(true); + + const role = new Parse.Role('aRole', roleACL); await role.save(); + const role2 = new Parse.Role('aRole2', roleACL); + await role2.save(); + await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear(); const { @@ -4896,7 +4906,7 @@ describe('ParseGraphQLServer', () => { mutation: gql` mutation Create($fields: CreateSomeClassFieldsInput) { createSomeClass(fields: $fields) { - objectId + id ACL { users { userId @@ -4919,45 +4929,72 @@ describe('ParseGraphQLServer', () => { variables: { fields: { ACL: { - users: [{ userId: user.id, read: true, write: true }], - roles: [{ roleName: 'aRole', read: true }], - public: { read: true }, + users: [ + { userId: user.id, read: true, write: true }, + { userId: user2.id }, + ], + roles: [ + { roleName: 'aRole', read: true }, + { roleName: 'aRole2' }, + ], + public: { read: true, write: true }, }, }, }, }); const expectedCreateACL = { - users: [{ userId: user.id, read: true, write: true }], - roles: [{ roleName: 'aRole', read: true, write: null }], - public: { read: true, write: null }, + __typename: 'ACL', + users: [ + { + userId: user.id, + read: true, + write: true, + __typename: 'UserACL', + }, + { + userId: user2.id, + read: true, + write: true, + __typename: 'UserACL', + }, + ], + roles: [ + { + roleName: 'aRole', + read: true, + write: false, + __typename: 'RoleACL', + }, + { + roleName: 'aRole2', + read: true, + write: true, + __typename: 'RoleACL', + }, + ], + public: { read: true, write: true, __typename: 'PublicACL' }, }; const query1 = new Parse.Query('SomeClass'); - const obj1 = (await query1.get(createSomeClass.objectId, { + const obj1 = (await query1.get(createSomeClass.id, { useMasterKey: true, })).toJSON(); - expect(obj1.ACL['role:aRole']).toBeDefined(); expect(obj1.ACL['role:aRole']).toEqual({ read: true }); - expect(obj1.ACL[user.id]).toBeDefined(); + expect(obj1.ACL['role:aRole2']).toEqual({ read: true, write: true }); expect(obj1.ACL[user.id]).toEqual({ read: true, write: true }); - expect(obj1.ACL['*']).toBeDefined(); - expect(obj1.ACL['*']).toEqual({ read: true }); - - expect(createSomeClass.objectId).toBeDefined(); + expect(obj1.ACL[user2.id]).toEqual({ read: true, write: true }); + expect(obj1.ACL['*']).toEqual({ read: true, write: true }); expect(createSomeClass.ACL).toEqual(expectedCreateACL); const { data: { updateSomeClass }, } = await apolloClient.mutate({ mutation: gql` - mutation Update( - $objectId: ID - $fields: CreateSomeClassFieldsInput - ) { - updateSomeClass(objectId: $objectId, fields: $fields) { - objectId + mutation Update($id: ID!, $fields: UpdateSomeClassFieldsInput) { + updateSomeClass(id: $id, fields: $fields) { + id ACL { users { userId @@ -4978,32 +5015,38 @@ describe('ParseGraphQLServer', () => { } `, variables: { - objectId: createSomeClass.objectId, + id: createSomeClass.id, fields: { ACL: { - roles: [{ roleName: 'aRole', read: true, write: true }], + roles: [{ roleName: 'aRole', write: true }], + public: { read: true }, }, }, }, }); const expectedUpdateACL = { + __typename: 'ACL', users: null, - roles: [{ roleName: 'aRole', read: true, write: true }], - public: null, + roles: [ + { + roleName: 'aRole', + read: true, + write: true, + __typename: 'RoleACL', + }, + ], + public: { read: true, write: false, __typename: 'PublicACL' }, }; const query2 = new Parse.Query('SomeClass'); - const obj2 = (await query2.get(createSomeClass.objectId, { + const obj2 = (await query2.get(createSomeClass.id, { useMasterKey: true, })).toJSON(); - expect(obj2.ACL['role:aRole']).toBeDefined(); - expect(obj2.ACL['role:aRole']).toEqual({ read: true, write: true }); + expect(obj2.ACL['role:aRole']).toEqual({ write: true, read: true }); expect(obj2.ACL[user.id]).toBeUndefined(); - expect(obj2.ACL['*']).toBeUndefined(); - - expect(updateSomeClass.objectId).toBeDefined(); + expect(obj2.ACL['*']).toEqual({ read: true }); expect(updateSomeClass.ACL).toEqual(expectedUpdateACL); }); diff --git a/src/GraphQL/ParseGraphQLServer.js b/src/GraphQL/ParseGraphQLServer.js index 3c06699f7f..ccb80821c6 100644 --- a/src/GraphQL/ParseGraphQLServer.js +++ b/src/GraphQL/ParseGraphQLServer.js @@ -45,6 +45,10 @@ class ParseGraphQLServer { config: req.config, auth: req.auth, }, + formatError: error => { + // Allow to console.log here to debug + return error; + }, }; } catch (e) { this.log.error( diff --git a/src/GraphQL/loaders/defaultGraphQLTypes.js b/src/GraphQL/loaders/defaultGraphQLTypes.js index fb80aa7e78..29e64adadc 100644 --- a/src/GraphQL/loaders/defaultGraphQLTypes.js +++ b/src/GraphQL/loaders/defaultGraphQLTypes.js @@ -395,6 +395,200 @@ const POLYGON_INPUT = new GraphQLList(new GraphQLNonNull(GEO_POINT_INPUT)); const POLYGON = new GraphQLList(new GraphQLNonNull(GEO_POINT)); +const USER_ACL_INPUT = new GraphQLInputObjectType({ + name: 'UserACLInput', + description: + 'Allow to manage users in ACL. If read and write are not provided the user will have read and write rights.', + fields: { + userId: { + description: 'ID of the targetted User.', + type: new GraphQLNonNull(GraphQLID), + }, + read: { + description: 'Allow the user to read the current object.', + type: GraphQLBoolean, + }, + write: { + description: + 'Allow the user to write on the current object. If true, read will be set to true.', + type: GraphQLBoolean, + }, + }, +}); + +const ROLE_ACL_INPUT = new GraphQLInputObjectType({ + name: 'RoleACLInput', + description: + 'Allow to manage roles in ACL. If read and write are not provided the role will have read and write rights.', + fields: { + roleName: { + description: 'Name of the targetted Role.', + type: new GraphQLNonNull(GraphQLString), + }, + read: { + description: + 'Read is true by default. Allow users who are members of the role to read the current object.', + type: GraphQLBoolean, + }, + write: { + description: + 'Write is true by default. Allow users who are members of the role to write on the current object. If true, read will be set to true.', + type: GraphQLBoolean, + }, + }, +}); + +const PUBLIC_ACL_INPUT = new GraphQLInputObjectType({ + name: 'PublicACLInput', + description: 'Allow to manage public rights.', + fields: { + read: { + description: + 'Read is true by default. Allow anyone to read the current object.', + type: GraphQLBoolean, + }, + write: { + description: + 'Write is true by default. Allow anyone to write on the current object. If true, read will be set to true.', + type: GraphQLBoolean, + }, + }, +}); + +const ACL_INPUT = new GraphQLInputObjectType({ + name: 'ACLInput', + description: + 'Allow to manage access rights. If not provided object will be publicly readable and writable', + fields: { + users: { + description: 'Access control list for users.', + type: new GraphQLList(new GraphQLNonNull(USER_ACL_INPUT)), + }, + roles: { + description: 'Access control list for roles.', + type: new GraphQLList(new GraphQLNonNull(ROLE_ACL_INPUT)), + }, + public: { + description: 'Public access control list.', + type: PUBLIC_ACL_INPUT, + }, + }, +}); + +const USER_ACL = new GraphQLObjectType({ + name: 'UserACL', + description: + 'Allow to manage users in ACL. If read and write are null the users have read and write rights.', + fields: { + userId: { + description: 'ID of the targetted User.', + type: new GraphQLNonNull(GraphQLID), + }, + read: { + description: 'Allow the user to read the current object.', + type: GraphQLBoolean, + }, + write: { + description: 'Allow the user to write on the current object.', + type: GraphQLBoolean, + }, + }, +}); + +const ROLE_ACL = new GraphQLObjectType({ + name: 'RoleACL', + description: + 'Allow to manage roles in ACL. If read and write are null the role have read and write rights.', + fields: { + roleName: { + description: 'Name of the targetted Role.', + type: new GraphQLNonNull(GraphQLID), + }, + read: { + description: + 'Allow users who are members of the role to read the current object.', + type: GraphQLBoolean, + }, + write: { + description: + 'Allow users who are members of the role to write on the current object.', + type: GraphQLBoolean, + }, + }, +}); + +const PUBLIC_ACL = new GraphQLObjectType({ + name: 'PublicACL', + description: 'Allow to manage public rights.', + fields: { + read: { + description: 'Allow anyone to read the current object.', + type: GraphQLBoolean, + }, + write: { + description: 'Allow anyone to write on the current object.', + type: GraphQLBoolean, + }, + }, +}); + +const ACL = new GraphQLObjectType({ + name: 'ACL', + description: 'Current access control list of the current object.', + fields: { + users: { + description: 'Access control list for users.', + type: new GraphQLList(new GraphQLNonNull(USER_ACL)), + resolve(p) { + const users = []; + Object.keys(p).forEach(rule => { + if (rule !== '*' && rule.indexOf('role:') !== 0) { + users.push({ + userId: rule, + read: p[rule].read || null, + write: + p[rule].read && !p[rule].write ? false : p[rule].write || null, + }); + } + }); + return users.length ? users : null; + }, + }, + roles: { + description: 'Access control list for roles.', + type: new GraphQLList(new GraphQLNonNull(ROLE_ACL)), + resolve(p) { + const roles = []; + Object.keys(p).forEach(rule => { + if (rule.indexOf('role:') === 0) { + roles.push({ + roleName: rule.replace('role:', ''), + read: p[rule].read || null, + write: + p[rule].read && !p[rule].write ? false : p[rule].write || null, + }); + } + }); + return roles.length ? roles : null; + }, + }, + public: { + description: 'Public access control list.', + type: PUBLIC_ACL, + resolve(p) { + /* eslint-disable */ + return p['*'] + ? { + read: p['*'].read || null, + write: + p['*'].read && !p['*'].write ? false : p['*'].write || null, + } + : null; + }, + }, + }, +}); + const OBJECT_ID = new GraphQLNonNull(GraphQLID); const CLASS_NAME_ATT = { @@ -423,13 +617,10 @@ const UPDATED_AT_ATT = { type: new GraphQLNonNull(DATE), }; -const ACL_ATT = { - description: 'This is the access control list of the object.', - type: OBJECT, -}; - const INPUT_FIELDS = { - ACL: ACL_ATT, + ACL: { + type: ACL, + }, }; const CREATE_RESULT_FIELDS = { @@ -1100,6 +1291,14 @@ const load = parseGraphQLSchema => { parseGraphQLSchema.addGraphQLType(SIGN_UP_RESULT, true); parseGraphQLSchema.addGraphQLType(ELEMENT, true); parseGraphQLSchema.addGraphQLType(OBJECT_ID, true); + parseGraphQLSchema.addGraphQLType(ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(USER_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(ROLE_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(PUBLIC_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(ACL, true); + parseGraphQLSchema.addGraphQLType(USER_ACL, true); + parseGraphQLSchema.addGraphQLType(ROLE_ACL, true); + parseGraphQLSchema.addGraphQLType(PUBLIC_ACL, true); }; export { @@ -1131,7 +1330,6 @@ export { OBJECT_ID_ATT, UPDATED_AT_ATT, CREATED_AT_ATT, - ACL_ATT, INPUT_FIELDS, CREATE_RESULT_FIELDS, CREATE_RESULT, @@ -1187,6 +1385,14 @@ export { SIGN_UP_RESULT, ARRAY_RESULT, ELEMENT, + ACL_INPUT, + USER_ACL_INPUT, + ROLE_ACL_INPUT, + PUBLIC_ACL_INPUT, + ACL, + USER_ACL, + ROLE_ACL, + PUBLIC_ACL, load, loadArrayResult, }; diff --git a/src/GraphQL/loaders/parseClassMutations.js b/src/GraphQL/loaders/parseClassMutations.js index c6343501cf..1907f25f85 100644 --- a/src/GraphQL/loaders/parseClassMutations.js +++ b/src/GraphQL/loaders/parseClassMutations.js @@ -110,7 +110,7 @@ const load = function( return { ...createdObject, updatedAt: createdObject.createdAt, - ...fields, + ...parseFields, ...optimizedObject, }; } catch (e) { @@ -153,6 +153,7 @@ const load = function( auth, info ); + const selectedFields = getFieldNames(mutationInfo); const { keys, include } = extractKeysAndInclude(selectedFields); @@ -179,7 +180,7 @@ const load = function( return { id, ...updatedObject, - ...fields, + ...parseFields, ...optimizedObject, }; } catch (e) { diff --git a/src/GraphQL/loaders/parseClassTypes.js b/src/GraphQL/loaders/parseClassTypes.js index daa815de0c..5bec0baf8c 100644 --- a/src/GraphQL/loaders/parseClassTypes.js +++ b/src/GraphQL/loaders/parseClassTypes.js @@ -62,7 +62,7 @@ const mapInputType = (parseType, targetClass, parseClassTypes) => { case 'Bytes': return defaultGraphQLTypes.BYTES; case 'ACL': - return defaultGraphQLTypes.OBJECT; + return defaultGraphQLTypes.ACL_INPUT; default: return undefined; } @@ -111,7 +111,7 @@ const mapOutputType = (parseType, targetClass, parseClassTypes) => { case 'Bytes': return defaultGraphQLTypes.BYTES; case 'ACL': - return defaultGraphQLTypes.OBJECT; + return defaultGraphQLTypes.ACL; default: return undefined; } @@ -351,7 +351,7 @@ const load = ( defaultGraphQLTypes.OBJECT; const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`; - let classGraphQLCreateType = new GraphQLInputObjectType({ + const classGraphQLCreateType = new GraphQLInputObjectType({ name: classGraphQLCreateTypeName, description: `The ${classGraphQLCreateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, fields: () => @@ -375,13 +375,12 @@ const load = ( } }, { - ACL: defaultGraphQLTypes.ACL_ATT, + ACL: { + type: defaultGraphQLTypes.ACL_INPUT, + }, } ), }); - classGraphQLCreateType = parseGraphQLSchema.addGraphQLType( - classGraphQLCreateType - ); const classGraphQLUpdateTypeName = `Update${graphQLClassName}FieldsInput`; let classGraphQLUpdateType = new GraphQLInputObjectType({ @@ -408,7 +407,9 @@ const load = ( } }, { - ACL: defaultGraphQLTypes.ACL_ATT, + ACL: { + type: defaultGraphQLTypes.ACL_INPUT, + }, } ), }); diff --git a/src/GraphQL/transformers/mutation.js b/src/GraphQL/transformers/mutation.js index eec564fe59..1bfd25f440 100644 --- a/src/GraphQL/transformers/mutation.js +++ b/src/GraphQL/transformers/mutation.js @@ -60,6 +60,7 @@ const transformTypes = async ( } }); await Promise.all(promises); + if (fields.ACL) fields.ACL = transformers.ACL(fields.ACL); } return fields; }; @@ -73,6 +74,44 @@ const transformers = { ...value, __type: 'GeoPoint', }), + ACL: value => { + const parseACL = {}; + if (value.public) { + parseACL['*'] = {}; + if (value.public.read) parseACL['*'].read = value.public.read; + if (value.public.write) { + parseACL['*'] = { + read: true, + write: true, + }; + } + } + if (value.users) { + value.users.forEach(rule => { + parseACL[rule.userId] = {}; + if (rule.read) parseACL[rule.userId].read = rule.read; + if ((!rule.read && !rule.read) || rule.write) { + parseACL[rule.userId] = { + read: true, + write: true, + }; + } + }); + } + if (value.roles) { + value.roles.forEach(rule => { + parseACL[`role:${rule.roleName}`] = {}; + if (rule.read) parseACL[`role:${rule.roleName}`].read = rule.read; + if ((!rule.read && !rule.read) || rule.write) { + parseACL[`role:${rule.roleName}`] = { + read: true, + write: true, + }; + } + }); + } + return parseACL; + }, relation: async ( targetClass, field, From b3882a99b64d1b5994ff1a3ef9aa0c2ba67472a7 Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Wed, 4 Sep 2019 00:44:16 +0200 Subject: [PATCH 3/4] Improvements --- src/GraphQL/loaders/defaultGraphQLTypes.js | 32 ++++++++++------------ src/GraphQL/transformers/mutation.js | 4 +-- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/GraphQL/loaders/defaultGraphQLTypes.js b/src/GraphQL/loaders/defaultGraphQLTypes.js index 29e64adadc..cba005a63a 100644 --- a/src/GraphQL/loaders/defaultGraphQLTypes.js +++ b/src/GraphQL/loaders/defaultGraphQLTypes.js @@ -405,12 +405,13 @@ const USER_ACL_INPUT = new GraphQLInputObjectType({ type: new GraphQLNonNull(GraphQLID), }, read: { - description: 'Allow the user to read the current object.', + description: + 'Read is true by default. Allow the user to read the current object.', type: GraphQLBoolean, }, write: { description: - 'Allow the user to write on the current object. If true, read will be set to true.', + 'Write is true by default. Allow the user to write on the current object. If true, read will be set to true.', type: GraphQLBoolean, }, }, @@ -427,12 +428,12 @@ const ROLE_ACL_INPUT = new GraphQLInputObjectType({ }, read: { description: - 'Read is true by default. Allow users who are members of the role to read the current object.', + "Read is true by default. Allow users who are members of the role to read the current object. By default it's true.", type: GraphQLBoolean, }, write: { description: - 'Write is true by default. Allow users who are members of the role to write on the current object. If true, read will be set to true.', + "Write is true by default. Allow users who are members of the role to write on the current object. If true, read will be set to true. By default it's true.", type: GraphQLBoolean, }, }, @@ -486,11 +487,11 @@ const USER_ACL = new GraphQLObjectType({ }, read: { description: 'Allow the user to read the current object.', - type: GraphQLBoolean, + type: new GraphQLNonNull(GraphQLBoolean), }, write: { description: 'Allow the user to write on the current object.', - type: GraphQLBoolean, + type: new GraphQLNonNull(GraphQLBoolean), }, }, }); @@ -507,12 +508,12 @@ const ROLE_ACL = new GraphQLObjectType({ read: { description: 'Allow users who are members of the role to read the current object.', - type: GraphQLBoolean, + type: new GraphQLNonNull(GraphQLBoolean), }, write: { description: 'Allow users who are members of the role to write on the current object.', - type: GraphQLBoolean, + type: new GraphQLNonNull(GraphQLBoolean), }, }, }); @@ -545,9 +546,8 @@ const ACL = new GraphQLObjectType({ if (rule !== '*' && rule.indexOf('role:') !== 0) { users.push({ userId: rule, - read: p[rule].read || null, - write: - p[rule].read && !p[rule].write ? false : p[rule].write || null, + read: p[rule].read || p[rule].write ? true : false, + write: p[rule].write ? true : false, }); } }); @@ -563,9 +563,8 @@ const ACL = new GraphQLObjectType({ if (rule.indexOf('role:') === 0) { roles.push({ roleName: rule.replace('role:', ''), - read: p[rule].read || null, - write: - p[rule].read && !p[rule].write ? false : p[rule].write || null, + read: p[rule].read || p[rule].write ? true : false, + write: p[rule].write ? true : false, }); } }); @@ -579,9 +578,8 @@ const ACL = new GraphQLObjectType({ /* eslint-disable */ return p['*'] ? { - read: p['*'].read || null, - write: - p['*'].read && !p['*'].write ? false : p['*'].write || null, + read: p['*'].read || p['*'].write ? true : false, + write: p['*'].write ? true : false, } : null; }, diff --git a/src/GraphQL/transformers/mutation.js b/src/GraphQL/transformers/mutation.js index 1bfd25f440..d4b0335bcc 100644 --- a/src/GraphQL/transformers/mutation.js +++ b/src/GraphQL/transformers/mutation.js @@ -90,7 +90,7 @@ const transformers = { value.users.forEach(rule => { parseACL[rule.userId] = {}; if (rule.read) parseACL[rule.userId].read = rule.read; - if ((!rule.read && !rule.read) || rule.write) { + if (rule.write) { parseACL[rule.userId] = { read: true, write: true, @@ -102,7 +102,7 @@ const transformers = { value.roles.forEach(rule => { parseACL[`role:${rule.roleName}`] = {}; if (rule.read) parseACL[`role:${rule.roleName}`].read = rule.read; - if ((!rule.read && !rule.read) || rule.write) { + if (rule.write) { parseACL[`role:${rule.roleName}`] = { read: true, write: true, From 226a83c9bd99be9e6fe414631a456888a5545854 Mon Sep 17 00:00:00 2001 From: Antoine Cormouls Date: Sun, 29 Sep 2019 17:43:36 +0200 Subject: [PATCH 4/4] Fix --- src/GraphQL/loaders/defaultGraphQLTypes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GraphQL/loaders/defaultGraphQLTypes.js b/src/GraphQL/loaders/defaultGraphQLTypes.js index 010fe8df4a..912f94dcd7 100644 --- a/src/GraphQL/loaders/defaultGraphQLTypes.js +++ b/src/GraphQL/loaders/defaultGraphQLTypes.js @@ -540,7 +540,7 @@ const ACL = new GraphQLObjectType({ if (rule !== '*' && rule.indexOf('role:') !== 0) { users.push({ userId: rule, - read: p[rule].read || p[rule].write ? true : false, + read: p[rule].read ? true : false, write: p[rule].write ? true : false, }); }