Files
directus/api/src/utils/reduce-schema.ts
Rijk van Zanten 9335372400 Foreign Key Constraints (#5615)
* Bump knex-schema-inspector

* Fix cli role name attr

* Update relation type

* Restructure relations

* Restructure relations table

* Update api type for relation record

* Fetch relations in new structure

* Update schema-inspector

* Use new relations schema structure in api

* Update relations GETters

* Add default value to one deselect

* Add create relationship on existing field

* Add updating existing relationship

* Add delete relations

* Add relations query resolver

* Add graphql mutations for relations

* Fix reading from wrong name

* Fix wrong method name

* No idea why this flip flops every install

* Update relation type

* Accept null in use-collection composable

* Use new relations structure in translations

* Use new relations structure in new-collection

* Start updating field detail store

* Renames for new relations structure

* Silently ignore passed collection/field in relation update

* Fix setting pk field in m2o relational setup

* Small tweaks in o2m setup

* Fix m2m setup

* Tweak m2o setup

* Fix m2a setup

* Allow null for related collection (m2a)

* Fix languages code name

* Fix migration default value

* Fix relational cleanup in collections/fields

* Fix transaction problem in field delete

* Fix inserting relational o2m items

* Don't execute updateByQuery on empty item set

Fixes #5710, fixes #5070

* Show referential action input on m2o

* Finish language for m2o

* Show triggers config on o2m

* Delete items on one_deselect_item delete

* Fix naming, show relational trigger config on m2m

* Tweak language, add setup to m2a

* Fix linter warnings

* Add trigger setup for translations

* fix Edit non-schema relationship issue

* Sync existing on_delete triggers in o2m setup

* Add migration to setup foreign key constraints

* Update illegal FK values before setting constraint

* Fix MySQL unsigned vs not-unsigned in FK creation

* Use pretty names for labels in relational triggers

* Prefix auto-junction when system table

Fixes #5493

* Add system foreign key triggers

Fixes #5749

* Update docs
2021-05-19 12:29:16 -04:00

106 lines
3.1 KiB
TypeScript

import { uniq } from 'lodash';
import { PermissionsAction, SchemaOverview } from '../types';
/**
* Reduces the schema based on the included permissions. The resulting object is the schema structure, but with only
* the allowed collections/fields/relations included based on the permissions.
* @param schema The full project schema
* @param actions Array of permissions actions (crud)
* @returns Reduced schema
*/
export function reduceSchema(
schema: SchemaOverview,
actions: PermissionsAction[] = ['create', 'read', 'update', 'delete']
): SchemaOverview {
const reduced: SchemaOverview = {
collections: {},
relations: [],
permissions: schema.permissions,
};
const allowedFieldsInCollection = schema.permissions
.filter((permission) => actions.includes(permission.action))
.reduce((acc, permission) => {
if (!acc[permission.collection]) {
acc[permission.collection] = [];
}
if (permission.fields) {
acc[permission.collection] = uniq([...acc[permission.collection], ...permission.fields]);
}
return acc;
}, {} as { [collection: string]: string[] });
for (const [collectionName, collection] of Object.entries(schema.collections)) {
if (
schema.permissions.some(
(permission) => permission.collection === collectionName && actions.includes(permission.action)
)
) {
const fields: SchemaOverview['collections'][string]['fields'] = {};
for (const [fieldName, field] of Object.entries(schema.collections[collectionName].fields)) {
if (
allowedFieldsInCollection[collectionName]?.includes('*') ||
allowedFieldsInCollection[collectionName]?.includes(fieldName)
) {
fields[fieldName] = field;
}
}
reduced.collections[collectionName] = {
...collection,
fields,
};
}
}
reduced.relations = schema.relations.filter((relation) => {
let collectionsAllowed = true;
let fieldsAllowed = true;
if (Object.keys(allowedFieldsInCollection).includes(relation.collection) === false) {
collectionsAllowed = false;
}
if (
relation.related_collection &&
Object.keys(allowedFieldsInCollection).includes(relation.related_collection) === false
) {
collectionsAllowed = false;
}
if (
relation.meta?.one_allowed_collections &&
relation.meta.one_allowed_collections.every((collection) =>
Object.keys(allowedFieldsInCollection).includes(collection)
) === false
) {
collectionsAllowed = false;
}
if (
!allowedFieldsInCollection[relation.collection] ||
(allowedFieldsInCollection[relation.collection].includes('*') === false &&
allowedFieldsInCollection[relation.collection].includes(relation.field) === false)
) {
fieldsAllowed = false;
}
if (
relation.related_collection &&
relation.meta?.one_field &&
(!allowedFieldsInCollection[relation.related_collection] ||
(allowedFieldsInCollection[relation.related_collection].includes('*') === false &&
allowedFieldsInCollection[relation.related_collection].includes(relation.meta?.one_field) === false))
) {
fieldsAllowed = false;
}
return collectionsAllowed && fieldsAllowed;
});
return reduced;
}