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:
Brainslug
2022-05-31 16:05:40 +02:00
committed by GitHub
parent 6a4a82f971
commit 6f2d22704e
5 changed files with 70 additions and 0 deletions

View File

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