mirror of
https://github.com/directus/directus.git
synced 2026-04-25 03:00:53 -04:00
Field permissions and relational interfaces (#13623)
* quick fix ignoring fields wrapped in $FOLLOW when checking permissions * checking related permissions for $FOLLOW filter * moved $FOLLOW logic to extractRequiredFieldPermissions * initial attempt at making e2e test for this issue * moved test to many-to-many.test.ts * added permissions for the test * created new user and role for these tests * broadened the expected matching object * only expecting name as the id field UUID was giving inconsistent uppercased results with mssql
This commit is contained in:
@@ -17,6 +17,7 @@ import { AbstractServiceOptions, AST, FieldNode, Item, NestedCollectionNode, Pri
|
||||
import { stripFunction } from '../utils/strip-function';
|
||||
import { ItemsService } from './items';
|
||||
import { PayloadService } from './payload';
|
||||
import { getRelationInfo } from '../utils/get-relation-info';
|
||||
|
||||
export class AuthorizationService {
|
||||
knex: Knex;
|
||||
@@ -229,6 +230,15 @@ export class AuthorizationService {
|
||||
// Filter value is not a filter, so we should skip it
|
||||
return result;
|
||||
}
|
||||
// virtual o2m/o2a filter in the form of `$FOLLOW(...)`
|
||||
else if (collection && filterKey.startsWith('$FOLLOW')) {
|
||||
(result[collection] || (result[collection] = new Set())).add(filterKey);
|
||||
// add virtual relation to the required permissions
|
||||
const { relation } = getRelationInfo([], collection, filterKey);
|
||||
if (relation?.collection && relation?.field) {
|
||||
(result[relation.collection] || (result[relation.collection] = new Set())).add(relation.field);
|
||||
}
|
||||
}
|
||||
// m2a filter in the form of `item:collection`
|
||||
else if (filterKey.includes(':')) {
|
||||
const [field, collectionScope] = filterKey.split(':');
|
||||
@@ -370,6 +380,7 @@ export class AuthorizationService {
|
||||
if (allowedFields.length === 0) allowedFields.push(schema.collections[collection].primary);
|
||||
|
||||
for (const field of requiredPermissions[collection]) {
|
||||
if (field.startsWith('$FOLLOW')) continue;
|
||||
if (!allowedFields.includes(field)) throw new ForbiddenException();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user