[field-level permissions] Upsert fieldPermission + use fieldPermission to compute permissions (#13050)

In this PR

- introduction of fieldPermission entity
- addition of upsertFieldPermission in role resolver
- computing of permissions taking fieldPermission into account. In order
to limit what is stored in Redis we only store fields restrictions. For
instance for objectMetadata with id XXX with a restriction on field with
id YYY we store:
`"XXX":{"canRead":true,"canUpdate":false,"canSoftDelete":false,"canDestroy":false,"restrictedFields":{"YYY":{"canRead":false,"canUpdate":null}}}`

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
Marie
2025-07-09 08:47:59 +00:00
committed by GitHub
co-authored by Charles Bochet
parent 6ba6860e1c
commit 1cb60f943e
49 changed files with 1343 additions and 47 deletions
@@ -0,0 +1,22 @@
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType('FieldPermission')
export class FieldPermissionDTO {
@Field({ nullable: false })
id: string;
@Field({ nullable: false })
objectMetadataId: string;
@Field({ nullable: false })
fieldMetadataId: string;
@Field({ nullable: false })
roleId: string;
@Field(() => Boolean, { nullable: true })
canReadFieldValue?: boolean | null;
@Field(() => Boolean, { nullable: true })
canUpdateFieldValue?: boolean | null;
}
@@ -0,0 +1,47 @@
import { Field, InputType } from '@nestjs/graphql';
import {
ArrayMinSize,
IsArray,
IsBoolean,
IsNotEmpty,
IsOptional,
IsUUID,
} from 'class-validator';
@InputType()
export class UpsertFieldPermissionsInput {
@IsUUID()
@IsNotEmpty()
@Field()
roleId: string;
@IsArray()
@ArrayMinSize(1)
@IsNotEmpty()
@Field(() => [FieldPermissionInput])
fieldPermissions: FieldPermissionInput[];
}
@InputType()
export class FieldPermissionInput {
@IsUUID()
@IsNotEmpty()
@Field()
objectMetadataId: string;
@IsUUID()
@IsNotEmpty()
@Field()
fieldMetadataId: string;
@IsBoolean()
@IsOptional()
@Field(() => Boolean, { nullable: true })
canReadFieldValue?: boolean | null;
@IsBoolean()
@IsOptional()
@Field(() => Boolean, { nullable: true })
canUpdateFieldValue?: boolean | null;
}