Fix couple hiccups, support *

This commit is contained in:
rijkvanzanten
2020-07-14 17:13:37 -04:00
parent 54a2b3b74d
commit dd6c7043ac
3 changed files with 28 additions and 74 deletions

View File

@@ -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]))
);

View File

@@ -108,6 +108,8 @@ export const processAST = async (role: string | null, ast: AST): Promise<AST> =>
validateFields(ast);
applyFilters(ast);
return ast;
/**
@@ -148,7 +150,10 @@ export const processAST = async (role: string | null, ast: AST): Promise<AST> =>
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<AST> =>
}
}
}
};
/*
// Swap *.* case for *,<relational-field>.*,<another-relational>.*
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;
}
*/
};

View File

@@ -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);
}