[permissions] Add read field permission check layer (part 1) (#13376)
In this PR, behind a feature flag, we add a permission layer check based on the read permission. It is done by computing a map of an object's fields, where keys are the column names and values the fieldMetadata id, making them comparable to the restricted fields ids list stored in the permission cache. For mutations (create, update, delete, destroy), we need to check the read permission on the returned field, as they may differ from the updated field. The write field permission will be tackled in a different PR.
This commit is contained in:
+47
@@ -0,0 +1,47 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { InternalServerError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
|
||||
import {
|
||||
computeColumnName,
|
||||
computeCompositeColumnName,
|
||||
} from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
|
||||
import { ObjectMetadataItemWithFieldMaps } from 'src/engine/metadata-modules/types/object-metadata-item-with-field-maps';
|
||||
|
||||
export function getFieldMetadataIdForColumnNameMap(
|
||||
objectMetadataItemWithFieldMaps: ObjectMetadataItemWithFieldMaps,
|
||||
) {
|
||||
const columnNameToFieldMetadataIdMap: Record<string, string> = {};
|
||||
|
||||
for (const [fieldMetadataId, fieldMetadata] of Object.entries(
|
||||
objectMetadataItemWithFieldMaps.fieldsById,
|
||||
)) {
|
||||
if (isCompositeFieldMetadataType(fieldMetadata.type)) {
|
||||
const compositeType = compositeTypeDefinitions.get(fieldMetadata.type);
|
||||
|
||||
if (!compositeType) {
|
||||
throw new InternalServerError(
|
||||
`Composite type not found for field metadata type ${fieldMetadata.type}`,
|
||||
);
|
||||
}
|
||||
|
||||
compositeType.properties.forEach((compositeProperty) => {
|
||||
const columnName = computeCompositeColumnName(
|
||||
fieldMetadata.name,
|
||||
compositeProperty,
|
||||
);
|
||||
|
||||
columnNameToFieldMetadataIdMap[columnName] = fieldMetadataId;
|
||||
});
|
||||
} else {
|
||||
const columnName = computeColumnName(fieldMetadata, {
|
||||
isForeignKey: fieldMetadata.type === FieldMetadataType.RELATION,
|
||||
});
|
||||
|
||||
columnNameToFieldMetadataIdMap[columnName] = fieldMetadataId;
|
||||
}
|
||||
}
|
||||
|
||||
return columnNameToFieldMetadataIdMap;
|
||||
}
|
||||
Reference in New Issue
Block a user