[permissions] Fix delete and soft-delete + enable fieldPermissions in devSeeds (#13646)

In this PR
1. Fix delete and soft-delete repository methods for repositories where
permission checks are NOT bypassed: they need to have a selection of
columns to return by default. To match what we did for insert I set it
to `'*'` by default. But I feel this may be bug prone as developers will
not necessarily think to fill the right values in. Maybe we should
change the api to use selectable fields by default. @charlesBochet
2. Add field permission seeds and enable field permission feature flag
in dev
This commit is contained in:
Marie
2025-08-07 10:43:28 +02:00
committed by GitHub
parent 9cfd62f1ef
commit 05c23a1297
10 changed files with 122 additions and 6 deletions
@@ -583,6 +583,7 @@ export class WorkspaceEntityManager extends EntityManager {
targetOrEntity: EntityTarget<Entity>,
criteria: unknown,
permissionOptions?: PermissionOptions,
selectedColumns: string[] | '*' = '*',
): Promise<DeleteResult> {
if (
criteria === undefined ||
@@ -611,6 +612,7 @@ export class WorkspaceEntityManager extends EntityManager {
.delete()
.from(targetOrEntity)
.whereInIds(criteria)
.returning(selectedColumns)
.execute();
} else {
return this.createQueryBuilder(
@@ -622,6 +624,7 @@ export class WorkspaceEntityManager extends EntityManager {
.delete()
.from(targetOrEntity)
.where(criteria)
.returning(selectedColumns)
.execute();
}
}
@@ -630,6 +633,7 @@ export class WorkspaceEntityManager extends EntityManager {
targetOrEntity: EntityTarget<Entity>,
criteria: unknown,
permissionOptions?: PermissionOptions,
selectedColumns: string[] | '*' = '*',
): Promise<UpdateResult> {
// if user passed empty criteria or empty list of criterias, then throw an error
if (
@@ -659,6 +663,7 @@ export class WorkspaceEntityManager extends EntityManager {
.softDelete()
.from(targetOrEntity)
.whereInIds(criteria)
.returning(selectedColumns)
.execute();
} else {
return this.createQueryBuilder(
@@ -670,6 +675,7 @@ export class WorkspaceEntityManager extends EntityManager {
.softDelete()
.from(targetOrEntity)
.where(criteria)
.returning(selectedColumns)
.execute();
}
}
@@ -678,6 +684,7 @@ export class WorkspaceEntityManager extends EntityManager {
targetOrEntity: EntityTarget<Entity>,
criteria: unknown,
permissionOptions?: PermissionOptions,
selectedColumns: string[] | '*' = '*',
): Promise<UpdateResult> {
// if user passed empty criteria or empty list of criterias, then throw an error
if (
@@ -707,6 +714,7 @@ export class WorkspaceEntityManager extends EntityManager {
.restore()
.from(targetOrEntity)
.whereInIds(criteria)
.returning(selectedColumns)
.execute();
} else {
return this.createQueryBuilder(
@@ -718,6 +726,7 @@ export class WorkspaceEntityManager extends EntityManager {
.restore()
.from(targetOrEntity)
.where(criteria)
.returning(selectedColumns)
.execute();
}
}
@@ -1237,6 +1246,10 @@ export class WorkspaceEntityManager extends EntityManager {
objectMetadataItem: ObjectMetadataItemWithFieldMaps;
permissionOptionsFromArgs: PermissionOptions | undefined;
}): Entity[] {
if (permissionOptionsFromArgs?.shouldBypassPermissionChecks === true) {
return formattedResult;
}
const restrictedFields =
permissionOptionsFromArgs?.objectRecordsPermissions?.[
objectMetadataItem.id
@@ -248,6 +248,7 @@ describe('WorkspaceRepository', () => {
shouldBypassPermissionChecks: false,
objectRecordsPermissions: mockObjectRecordsPermissions,
},
undefined,
);
expect(result).toEqual(expectedResult);
});
@@ -332,7 +332,7 @@ const getSelectedColumnsFromExpressionMap = ({
operationType,
)
) {
if (isEmpty(expressionMap.returning)) {
if (!isDefined(expressionMap.returning)) {
throw new InternalServerError(
'Returning columns are not set for update query',
);
@@ -348,6 +348,7 @@ export class WorkspaceRepository<
| ObjectId[]
| FindOptionsWhere<T>,
entityManager?: WorkspaceEntityManager,
selectedColumns?: string[] | '*',
): Promise<DeleteResult> {
const manager = entityManager || this.manager;
@@ -360,7 +361,12 @@ export class WorkspaceRepository<
objectRecordsPermissions: this.objectRecordsPermissions,
};
return manager.delete(this.target, criteria, permissionOptions);
return manager.delete(
this.target,
criteria,
permissionOptions,
selectedColumns,
);
}
override softRemove<U extends DeepPartial<T>>(
@@ -431,6 +437,7 @@ export class WorkspaceRepository<
| ObjectId[]
| FindOptionsWhere<T>,
entityManager?: WorkspaceEntityManager,
selectedColumns?: string[],
): Promise<UpdateResult> {
const manager = entityManager || this.manager;
@@ -443,7 +450,12 @@ export class WorkspaceRepository<
objectRecordsPermissions: this.objectRecordsPermissions,
};
return manager.softDelete(this.target, criteria, permissionOptions);
return manager.softDelete(
this.target,
criteria,
permissionOptions,
selectedColumns,
);
}
/**
@@ -517,6 +529,7 @@ export class WorkspaceRepository<
| ObjectId[]
| FindOptionsWhere<T>,
entityManager?: WorkspaceEntityManager,
selectedColumns?: string[],
): Promise<UpdateResult> {
const manager = entityManager || this.manager;
@@ -529,7 +542,12 @@ export class WorkspaceRepository<
objectRecordsPermissions: this.objectRecordsPermissions,
};
return manager.restore(this.target, criteria, permissionOptions);
return manager.restore(
this.target,
criteria,
permissionOptions,
selectedColumns,
);
}
/**