From dd6c7043ac58411b8ca55198b40bd8c1a57792eb Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Tue, 14 Jul 2020 17:13:37 -0400 Subject: [PATCH] Fix couple hiccups, support * --- src/database/run-ast.ts | 6 ++- src/services/permissions.ts | 94 ++++++++------------------------- src/utils/get-ast-from-query.ts | 2 +- 3 files changed, 28 insertions(+), 74 deletions(-) diff --git a/src/database/run-ast.ts b/src/database/run-ast.ts index 7724b10f5c..957e78e6f0 100644 --- a/src/database/run-ast.ts +++ b/src/database/run-ast.ts @@ -15,7 +15,7 @@ export default async function runAST(ast: AST, query = ast.query) { for (const child of ast.children) { if (child.type === 'field') { - if (columnsInCollection.includes(child.name)) { + if (columnsInCollection.includes(child.name) || child.name === '*') { toplevelFields.push(child.name); } @@ -181,6 +181,10 @@ export default async function runAST(ast: AST, query = ast.query) { const nestedCollectionKeys = nestedCollections.map(({ fieldKey }) => fieldKey); + if (toplevelFields.includes('*')) { + return results; + } + return results.map((result) => pick(result, uniq([...nestedCollectionKeys, ...toplevelFields])) ); diff --git a/src/services/permissions.ts b/src/services/permissions.ts index 1b6c348a55..1982fd6b2f 100644 --- a/src/services/permissions.ts +++ b/src/services/permissions.ts @@ -108,6 +108,8 @@ export const processAST = async (role: string | null, ast: AST): Promise => validateFields(ast); + applyFilters(ast); + return ast; /** @@ -148,7 +150,10 @@ export const processAST = async (role: string | null, ast: AST): Promise => continue; } + if (allowedFields.includes('*')) continue; + const fieldKey = childAST.name; + if (allowedFields.includes(fieldKey) === false) { throw new ForbiddenException( `You don't have permission to access the "${fieldKey}" field.` @@ -157,83 +162,28 @@ export const processAST = async (role: string | null, ast: AST): Promise => } } } -}; -/* -// Swap *.* case for *,.*,.* -for (let index = 0; index < fields.length; index++) { - const fieldKey = fields[index]; + function applyFilters( + ast: AST | NestedCollectionAST | FieldAST + ): AST | NestedCollectionAST | FieldAST { + if (ast.type === 'collection') { + const collection = ast.name; - if (fieldKey.includes('.') === false) continue; - - const parts = fieldKey.split('.'); - - if (parts[0] === '*') { - const availableFields = await FieldsService.fieldsInCollection(parentCollection); - const allowedCollections = permissions.map(({ collection }) => collection); - - const relationalFields = availableFields.filter((field) => { - const relation = getRelation(parentCollection, field); - if (!relation) return false; - - return ( - allowedCollections.includes(relation.collection_one) && - allowedCollections.includes(relation.collection_many) + const permissions = permissionsForCollections.find( + (permission) => permission.collection === collection ); - }); - const nestedFieldKeys = relationalFields.map( - (relationalField) => `${relationalField}.${parts.slice(1).join('.')}` - ); + ast.query = { + ...ast.query, + filter: { + ...(ast.query.filter || {}), + ...permissions.permissions, + }, + }; - fields.splice(index, 1, ...nestedFieldKeys); - - fields.push('*'); - } -} - - -function convertWildcards(ast: AST | NestedCollectionAST) { - if (ast.type === 'collection') { - const permission = permissionsForCollections.find( - (permission) => permission.collection === ast.name - ); - - const wildcardIndex = ast.children.findIndex((nestedAST) => { - return nestedAST.type === 'field' && nestedAST.name === '*'; - }); - - // Replace wildcard with array of fields you're allowed to read - if (wildcardIndex !== -1) { - const allowedFields = permission?.fields; - - if (allowedFields !== '*') { - const currentFieldKeys = ast.children.map((field) => field.type === 'field' ? field.name : field.fieldKey); - console.log(currentFieldKeys); - const fields: FieldAST[] = allowedFields - .split(',') - // Make sure we don't include nested collections as columns - .filter((fieldKey) => { - console.log(currentFieldKeys, fieldKey, currentFieldKeys.includes(fieldKey)); - return currentFieldKeys.includes(fieldKey) === false; - }) - .map((fieldKey) => ({ type: 'field', name: fieldKey })); - - ast.children.splice(wildcardIndex, 1, ...fields); - } + ast.children = ast.children.map(applyFilters) as (NestedCollectionAST | FieldAST)[]; } - ast.children = ast.children - .map((childAST) => { - if (childAST.type === 'collection') { - return convertWildcards(childAST) as NestedCollectionAST | FieldAST; - } - - return childAST; - }) - .filter((c) => c); + return ast; } - - return ast; -} -*/ +}; diff --git a/src/utils/get-ast-from-query.ts b/src/utils/get-ast-from-query.ts index 4f2a856f4e..8ed61a4604 100644 --- a/src/utils/get-ast-from-query.ts +++ b/src/utils/get-ast-from-query.ts @@ -5,7 +5,6 @@ import { Relation } from '../types/relation'; import { AST, NestedCollectionAST, FieldAST, Query } from '../types'; import database, { schemaInspector } from '../database'; -import * as FieldsService from '../services/fields'; export default async function getASTFromQuery( role: string | null, @@ -49,6 +48,7 @@ export default async function getASTFromQuery( if (fieldKey.includes('*') === false) continue; if (fieldKey === '*') { + if (allowedFields.includes('*')) continue; fields.splice(index, 1, ...allowedFields); }