[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
@@ -7,6 +7,7 @@ import { Repository } from 'typeorm';
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { FieldPermissionService } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.service';
import { ObjectPermissionService } from 'src/engine/metadata-modules/object-permission/object-permission.service';
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
@@ -30,6 +31,7 @@ export class DevSeederPermissionsService {
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
private readonly typeORMService: TypeORMService,
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
private readonly fieldPermissionService: FieldPermissionService,
) {}
public async initPermissions(workspaceId: string) {
@@ -175,6 +177,28 @@ export class DevSeederPermissionsService {
},
});
const personObjectMetadata =
await this.objectMetadataRepository.findOneOrFail({
where: {
nameSingular: 'person',
workspaceId,
},
relations: {
fields: true,
},
});
const companyObjectMetadata =
await this.objectMetadataRepository.findOneOrFail({
where: {
nameSingular: 'company',
workspaceId,
},
relations: {
fields: true,
},
});
await this.objectPermissionService.upsertObjectPermissions({
workspaceId,
input: {
@@ -198,6 +222,47 @@ export class DevSeederPermissionsService {
},
});
const personCityFieldMetadata = personObjectMetadata.fields.find(
(field) => field.name === 'city',
);
if (!personCityFieldMetadata) {
throw new Error('Person city field metadata not found');
}
const companyLinkedinLinkFieldMetadata = companyObjectMetadata.fields.find(
(field) => field.name === 'linkedinLink',
);
if (!companyLinkedinLinkFieldMetadata) {
throw new Error('Company linkedin link field metadata not found');
}
const readOnlyOnPersonCityFieldPermission = {
objectMetadataId: personObjectMetadata.id,
fieldMetadataId: personCityFieldMetadata.id,
canReadFieldValue: null,
canUpdateFieldValue: false,
};
const noReadOnCompanyLinkedinLinkFieldPermission = {
objectMetadataId: companyObjectMetadata.id,
fieldMetadataId: companyLinkedinLinkFieldMetadata.id,
canReadFieldValue: false,
canUpdateFieldValue: false,
};
await this.fieldPermissionService.upsertFieldPermissions({
workspaceId,
input: {
roleId: customRole.id,
fieldPermissions: [
readOnlyOnPersonCityFieldPermission,
noReadOnCompanyLinkedinLinkFieldPermission,
],
},
});
return customRole;
}
}
@@ -75,6 +75,11 @@ export const seedFeatureFlags = async (
workspaceId: workspaceId,
value: true,
},
{
key: FeatureFlagKey.IS_FIELDS_PERMISSIONS_ENABLED,
workspaceId: workspaceId,
value: true,
},
])
.execute();
};