[permissions] Update permission check layer (#13485)

Fixes https://github.com/twentyhq/core-team-issues/issues/1262

In this PR we add the update permission check layer by 
- for the graphql api: extracting columns to update from the
expressionMap
- for rest api: .save() is used so we need to add the permission layer
to .save directly. We also take advantage of this PR to filter out
non-readable fields from save response (other save returns the whole
entity) - this was planned in
https://github.com/twentyhq/core-team-issues/issues/1216

The current solution does not work with rest api depth 2 queries, but
this seem to already not work on main (for timeout reasons though, so
different). I offer to create a ticket to fix it altogether later.
This commit is contained in:
Marie
2025-07-31 18:37:01 +02:00
committed by GitHub
parent 3e9b642f7f
commit b41502a4b8
20 changed files with 1483 additions and 124 deletions
@@ -18,7 +18,7 @@ export class RestApiDeleteOneHandler extends RestApiBaseHandler {
const { objectMetadata, repository, restrictedFields } =
await this.getRepositoryAndMetadataOrFail(request);
const selectOptions = this.getSelectOptionsFromRestrictedFields({
const selectOptions = this.getAllSelectableFields({
restrictedFields,
objectMetadata,
});
@@ -23,7 +23,9 @@ export class RestApiUpdateOneHandler extends RestApiBaseHandler {
const { objectMetadata, repository, restrictedFields } =
await this.getRepositoryAndMetadataOrFail(request);
const recordToUpdate = await repository.findOneOrFail({
// assert the record exists
await repository.findOneOrFail({
select: { id: true },
where: { id: recordId },
});
@@ -33,7 +35,7 @@ export class RestApiUpdateOneHandler extends RestApiBaseHandler {
});
const updatedRecord = await repository.save({
...recordToUpdate,
id: recordId,
...overriddenBody,
});
@@ -266,7 +266,7 @@ export abstract class RestApiBaseHandler {
let selectOptions = undefined;
if (!isEmpty(restrictedFields)) {
selectOptions = this.getSelectOptionsFromRestrictedFields({
selectOptions = this.getAllSelectableFields({
restrictedFields,
objectMetadata,
});
@@ -311,7 +311,7 @@ export abstract class RestApiBaseHandler {
};
}
public getSelectOptionsFromRestrictedFields({
public getAllSelectableFields({
restrictedFields,
objectMetadata,
}: {
@@ -406,7 +406,9 @@ export abstract class RestApiBaseHandler {
const objectMetadataNameSingular =
objectMetadata.objectMetadataMapItem.nameSingular;
const qb = repository.createQueryBuilder(objectMetadataNameSingular);
const qb = repository
.createQueryBuilder(objectMetadataNameSingular)
.select('id');
const inputs = this.getVariablesFactory.create(
recordId,