mirror of
https://github.com/directus/directus.git
synced 2026-01-30 00:37:55 -05:00
Add limit permissions
This commit is contained in:
@@ -39,6 +39,10 @@ export default async function runAST(ast: AST, query = ast.query) {
|
||||
|
||||
let dbQuery = database.select([...toplevelFields, ...tempFields]).from(ast.name);
|
||||
|
||||
// Query defaults
|
||||
query.limit = query.limit || 100;
|
||||
query.sort = query.sort || [{ column: primaryKeyField, order: 'asc' }];
|
||||
|
||||
if (query.filter) {
|
||||
applyFilter(dbQuery, query.filter);
|
||||
}
|
||||
@@ -88,6 +92,7 @@ export default async function runAST(ast: AST, query = ast.query) {
|
||||
|
||||
let batchQuery: Query = {};
|
||||
let tempField: string = null;
|
||||
let tempLimit: number = null;
|
||||
|
||||
if (m2o) {
|
||||
// Make sure we always fetch the nested items primary key field to ensure we have the key to match the item by
|
||||
@@ -131,6 +136,17 @@ export default async function runAST(ast: AST, query = ast.query) {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* The nested queries are done with a WHERE m2o IN (pk, pk, pk) query. We have to remove
|
||||
* LIMIT from that equation to ensure we limit `n` items _per parent record_ instead of
|
||||
* `n` items in total. This limit will then be re-applied in the stitching process
|
||||
* down below
|
||||
*/
|
||||
if (batchQuery.limit) {
|
||||
tempLimit = batchQuery.limit;
|
||||
delete batchQuery.limit;
|
||||
}
|
||||
}
|
||||
|
||||
const nestedResults = await runAST(batch, batchQuery);
|
||||
@@ -157,26 +173,32 @@ export default async function runAST(ast: AST, query = ast.query) {
|
||||
}
|
||||
|
||||
// o2m
|
||||
let resultsForCurrentRecord = nestedResults
|
||||
.filter((nestedRecord) => {
|
||||
return (
|
||||
nestedRecord[batch.relation.field_many] ===
|
||||
record[batch.relation.primary_one] ||
|
||||
// In case of nested object:
|
||||
nestedRecord[batch.relation.field_many]?.[batch.relation.primary_many] ===
|
||||
record[batch.relation.primary_one]
|
||||
);
|
||||
})
|
||||
.map((nestedRecord) => {
|
||||
if (tempField) {
|
||||
delete nestedRecord[tempField];
|
||||
}
|
||||
|
||||
return nestedRecord;
|
||||
});
|
||||
|
||||
// Reapply LIMIT query on a per-record basis
|
||||
if (tempLimit) {
|
||||
resultsForCurrentRecord = resultsForCurrentRecord.slice(0, tempLimit);
|
||||
}
|
||||
|
||||
const newRecord = {
|
||||
...record,
|
||||
[batch.fieldKey]: nestedResults
|
||||
.filter((nestedRecord) => {
|
||||
/**
|
||||
* @todo
|
||||
* pull the name ID from somewhere real
|
||||
*/
|
||||
return (
|
||||
nestedRecord[batch.relation.field_many] === record.id ||
|
||||
nestedRecord[batch.relation.field_many]?.id === record.id
|
||||
);
|
||||
})
|
||||
.map((nestedRecord) => {
|
||||
if (tempField) {
|
||||
delete nestedRecord[tempField];
|
||||
}
|
||||
|
||||
return nestedRecord;
|
||||
}),
|
||||
[batch.fieldKey]: resultsForCurrentRecord,
|
||||
};
|
||||
|
||||
return newRecord;
|
||||
|
||||
@@ -13,9 +13,12 @@ const sanitizeQuery: RequestHandler = (req, res, next) => {
|
||||
|
||||
const query: Query = {
|
||||
fields: sanitizeFields(req.query.fields) || ['*'],
|
||||
limit: sanitizeLimit(req.query.limit) || 100,
|
||||
};
|
||||
|
||||
if (req.query.limit) {
|
||||
query.limit = sanitizeLimit(req.query.limit);
|
||||
}
|
||||
|
||||
if (req.query.sort) {
|
||||
query.sort = sanitizeSort(req.query.sort);
|
||||
}
|
||||
|
||||
@@ -148,6 +148,17 @@ export const processAST = async (ast: AST, role: string | null): Promise<AST> =>
|
||||
},
|
||||
};
|
||||
|
||||
if (permissions.limit && ast.query.limit > permissions.limit) {
|
||||
throw new ForbiddenException(
|
||||
`You can't read more than ${permissions.limit} items at a time.`
|
||||
);
|
||||
}
|
||||
|
||||
// Default to the permissions limit if limit hasn't been set
|
||||
if (permissions.limit && !ast.query.limit) {
|
||||
ast.query.limit = permissions.limit;
|
||||
}
|
||||
|
||||
ast.children = ast.children.map(applyFilters) as (NestedCollectionAST | FieldAST)[];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user