Adapt field permissions to label identifier (#14287)
Closes https://github.com/twentyhq/core-team-issues/issues/1316 As discussed with @Bonapara, the behaviour is the following: 1 if there is a read restriction on a field that is or becomes the label identifier, this restriction is actually overriden to allow any user who has read rights on the object to also be able to read the values on the label identifier field. This restriction is overriden in the values stored in the cache but not in the db. 2 in the UI it is not possible to add a field permission to restrict read rights on the field that is the label identifier. It is still possible to update the label identifier for it to be a field that previously had a restrictive field permission on a role though, but then 1. has our back.
This commit is contained in:
+4
@@ -145,6 +145,10 @@ export const SettingsRolePermissionsObjectLevelObjectFieldPermissionTable = ({
|
||||
fieldPermissions={fieldPermissions}
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
roleId={roleId}
|
||||
isLabelIdentifier={
|
||||
objectMetadataItem.labelIdentifierFieldMetadataId ===
|
||||
fieldMetadataItem.id
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</Table>
|
||||
|
||||
+7
-2
@@ -39,6 +39,7 @@ type SettingsRolePermissionsObjectLevelObjectFieldPermissionTableRowProps = {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
fieldPermissions: FieldPermission[];
|
||||
roleId: string;
|
||||
isLabelIdentifier: boolean;
|
||||
};
|
||||
|
||||
export const SettingsRolePermissionsObjectLevelObjectFieldPermissionTableRow =
|
||||
@@ -47,6 +48,7 @@ export const SettingsRolePermissionsObjectLevelObjectFieldPermissionTableRow =
|
||||
fieldPermissions,
|
||||
objectMetadataItem,
|
||||
roleId,
|
||||
isLabelIdentifier,
|
||||
}: SettingsRolePermissionsObjectLevelObjectFieldPermissionTableRowProps) => {
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
@@ -132,7 +134,8 @@ export const SettingsRolePermissionsObjectLevelObjectFieldPermissionTableRow =
|
||||
|
||||
const isReadRestricted =
|
||||
hasRestriction &&
|
||||
fieldPermissionForThisFieldMetadataItem?.canReadFieldValue === false;
|
||||
fieldPermissionForThisFieldMetadataItem?.canReadFieldValue === false &&
|
||||
!isLabelIdentifier;
|
||||
|
||||
const isUpdateRestricted =
|
||||
hasRestriction &&
|
||||
@@ -184,7 +187,9 @@ export const SettingsRolePermissionsObjectLevelObjectFieldPermissionTableRow =
|
||||
{shouldShowSeeTableHeader && (
|
||||
<TableCell>
|
||||
<OverridableCheckbox
|
||||
disabled={fieldMetadataItem.isUIReadOnly ?? false}
|
||||
disabled={
|
||||
(fieldMetadataItem.isUIReadOnly || isLabelIdentifier) ?? false
|
||||
}
|
||||
checked={true}
|
||||
onChange={handleSeeChange}
|
||||
type={isReadRestricted ? 'override' : 'default'}
|
||||
|
||||
+10
@@ -29,6 +29,7 @@ import {
|
||||
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
|
||||
import { ObjectMetadataRelatedRecordsService } from 'src/engine/metadata-modules/object-metadata/services/object-metadata-related-records.service';
|
||||
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service';
|
||||
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@@ -38,6 +39,7 @@ export class ObjectMetadataServiceV2 {
|
||||
private readonly workspaceMetadataCacheService: WorkspaceMetadataCacheService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly objectMetadataRelatedRecordsService: ObjectMetadataRelatedRecordsService,
|
||||
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
) {}
|
||||
@@ -126,6 +128,14 @@ export class ObjectMetadataServiceV2 {
|
||||
);
|
||||
}
|
||||
|
||||
if (isDefined(updateObjectInput.update.labelIdentifierFieldMetadataId)) {
|
||||
await this.workspacePermissionsCacheService.recomputeRolesPermissionsCache(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return fromFlatObjectMetadataToObjectMetadataDto(updatedFlatObjectMetadata);
|
||||
}
|
||||
|
||||
|
||||
+13
-4
@@ -13,7 +13,6 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
import { PermissionFlagType } from 'src/engine/metadata-modules/permissions/constants/permission-flag-type.constants';
|
||||
import { RoleTargetsEntity } from 'src/engine/metadata-modules/role/role-targets.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { WorkspaceFeatureFlagsMapCacheService } from 'src/engine/metadata-modules/workspace-feature-flags-map-cache/workspace-feature-flags-map-cache.service';
|
||||
import { type UserWorkspaceRoleMap } from 'src/engine/metadata-modules/workspace-permissions-cache/types/user-workspace-role-map.type';
|
||||
import { WorkspacePermissionsCacheStorageService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache-storage.service';
|
||||
import { TwentyORMExceptionCode } from 'src/engine/twenty-orm/exceptions/twenty-orm.exception';
|
||||
@@ -45,7 +44,6 @@ export class WorkspacePermissionsCacheService {
|
||||
@InjectRepository(RoleTargetsEntity)
|
||||
private readonly roleTargetsRepository: Repository<RoleTargetsEntity>,
|
||||
private readonly workspacePermissionsCacheStorageService: WorkspacePermissionsCacheStorageService,
|
||||
private readonly workspaceFeatureFlagsMapCacheService: WorkspaceFeatureFlagsMapCacheService,
|
||||
) {}
|
||||
|
||||
async recomputeRolesPermissionsCache({
|
||||
@@ -249,12 +247,18 @@ export class WorkspacePermissionsCacheService {
|
||||
);
|
||||
|
||||
for (const fieldPermission of fieldPermissions) {
|
||||
const isFieldLabelIdentifier =
|
||||
fieldPermission.fieldMetadataId ===
|
||||
objectMetadata.labelIdentifierFieldMetadataId;
|
||||
|
||||
if (
|
||||
isDefined(fieldPermission.canReadFieldValue) ||
|
||||
isDefined(fieldPermission.canUpdateFieldValue)
|
||||
) {
|
||||
restrictedFields[fieldPermission.fieldMetadataId] = {
|
||||
canRead: fieldPermission.canReadFieldValue,
|
||||
canRead: isFieldLabelIdentifier
|
||||
? true
|
||||
: fieldPermission.canReadFieldValue,
|
||||
canUpdate: fieldPermission.canUpdateFieldValue,
|
||||
};
|
||||
}
|
||||
@@ -283,7 +287,12 @@ export class WorkspacePermissionsCacheService {
|
||||
where: {
|
||||
workspaceId,
|
||||
},
|
||||
select: ['id', 'isSystem', 'standardId'],
|
||||
select: [
|
||||
'id',
|
||||
'isSystem',
|
||||
'standardId',
|
||||
'labelIdentifierFieldMetadataId',
|
||||
],
|
||||
});
|
||||
|
||||
return workspaceObjectMetadata;
|
||||
|
||||
Reference in New Issue
Block a user