[permissions V2] Remove feature flag (#12790)
This commit is contained in:
@ -691,7 +691,6 @@ export enum FeatureFlagKey {
|
||||
IS_AIRTABLE_INTEGRATION_ENABLED = 'IS_AIRTABLE_INTEGRATION_ENABLED',
|
||||
IS_AI_ENABLED = 'IS_AI_ENABLED',
|
||||
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
|
||||
IS_PERMISSIONS_V2_ENABLED = 'IS_PERMISSIONS_V2_ENABLED',
|
||||
IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
|
||||
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
|
||||
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED'
|
||||
|
||||
@ -647,7 +647,6 @@ export enum FeatureFlagKey {
|
||||
IS_AIRTABLE_INTEGRATION_ENABLED = 'IS_AIRTABLE_INTEGRATION_ENABLED',
|
||||
IS_AI_ENABLED = 'IS_AI_ENABLED',
|
||||
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
|
||||
IS_PERMISSIONS_V2_ENABLED = 'IS_PERMISSIONS_V2_ENABLED',
|
||||
IS_POSTGRESQL_INTEGRATION_ENABLED = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
|
||||
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
|
||||
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED'
|
||||
|
||||
@ -7,12 +7,10 @@ import { SettingsRolesTableRow } from '@/settings/roles/components/SettingsRoles
|
||||
import { settingsAllRolesSelector } from '@/settings/roles/states/settingsAllRolesSelector';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { H2Title, IconPlus } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { sortByAscString } from '~/utils/array/sortByAscString';
|
||||
|
||||
@ -35,9 +33,6 @@ const StyledNoRoles = styled(TableCell)`
|
||||
|
||||
export const SettingsRolesList = () => {
|
||||
const navigateSettings = useNavigateSettings();
|
||||
const isPermissionsV2Enabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
);
|
||||
|
||||
const settingsAllRoles = useRecoilValue(settingsAllRolesSelector);
|
||||
|
||||
@ -69,8 +64,6 @@ export const SettingsRolesList = () => {
|
||||
title={t`Create Role`}
|
||||
variant="secondary"
|
||||
size="small"
|
||||
soon={!isPermissionsV2Enabled}
|
||||
disabled={!isPermissionsV2Enabled}
|
||||
onClick={() => navigateSettings(SettingsPath.RoleCreate)}
|
||||
/>
|
||||
</StyledCreateRoleSection>
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { SettingsRolePermissionsObjectLevelSection } from '@/settings/roles/role-permissions/object-level-permissions/components/SettingsRolePermissionsObjectLevelSection';
|
||||
import { SettingsRolePermissionsObjectsSection } from '@/settings/roles/role-permissions/objects-permissions/components/SettingsRolePermissionsObjectsSection';
|
||||
import { SettingsRolePermissionsSettingsSection } from '@/settings/roles/role-permissions/settings-permissions/components/SettingsRolePermissionsSettingsSection';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import styled from '@emotion/styled';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledRolePermissionsContainer = styled.div`
|
||||
display: flex;
|
||||
@ -22,17 +20,13 @@ export const SettingsRolePermissions = ({
|
||||
isEditable,
|
||||
isCreateMode,
|
||||
}: SettingsRolePermissionsProps) => {
|
||||
const isPermissionsV2Enabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledRolePermissionsContainer>
|
||||
<SettingsRolePermissionsObjectsSection
|
||||
roleId={roleId}
|
||||
isEditable={isEditable}
|
||||
/>
|
||||
{isPermissionsV2Enabled && !isCreateMode && (
|
||||
{!isCreateMode && (
|
||||
<SettingsRolePermissionsObjectLevelSection
|
||||
roleId={roleId}
|
||||
isEditable={isEditable}
|
||||
|
||||
@ -3,7 +3,6 @@ import { SettingsRolePermissionsSettingsTableHeader } from '@/settings/roles/rol
|
||||
import { SettingsRolePermissionsSettingsTableRow } from '@/settings/roles/role-permissions/settings-permissions/components/SettingsRolePermissionsSettingsTableRow';
|
||||
import { SettingsRolePermissionsSettingPermission } from '@/settings/roles/role-permissions/settings-permissions/types/SettingsRolePermissionsSettingPermission';
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import styled from '@emotion/styled';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
@ -18,10 +17,7 @@ import {
|
||||
IconUsers,
|
||||
} from 'twenty-ui/display';
|
||||
import { AnimatedExpandableContainer, Card, Section } from 'twenty-ui/layout';
|
||||
import {
|
||||
FeatureFlagKey,
|
||||
SettingPermissionType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { SettingPermissionType } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledTable = styled.div`
|
||||
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
@ -45,10 +41,6 @@ export const SettingsRolePermissionsSettingsSection = ({
|
||||
roleId,
|
||||
isEditable,
|
||||
}: SettingsRolePermissionsSettingsSectionProps) => {
|
||||
const isPermissionsV2Enabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
);
|
||||
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
);
|
||||
@ -102,23 +94,21 @@ export const SettingsRolePermissionsSettingsSection = ({
|
||||
return (
|
||||
<Section>
|
||||
<H2Title title={t`Settings`} description={t`Settings permissions`} />
|
||||
{isPermissionsV2Enabled && (
|
||||
<StyledCard rounded>
|
||||
<SettingsOptionCardContentToggle
|
||||
Icon={IconSettings}
|
||||
title={t`Settings All Access`}
|
||||
description={t`Ability to edit all settings`}
|
||||
checked={settingsDraftRole.canUpdateAllSettings}
|
||||
disabled={!isEditable}
|
||||
onChange={() => {
|
||||
setSettingsDraftRole({
|
||||
...settingsDraftRole,
|
||||
canUpdateAllSettings: !settingsDraftRole.canUpdateAllSettings,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</StyledCard>
|
||||
)}
|
||||
<StyledCard rounded>
|
||||
<SettingsOptionCardContentToggle
|
||||
Icon={IconSettings}
|
||||
title={t`Settings All Access`}
|
||||
description={t`Ability to edit all settings`}
|
||||
checked={settingsDraftRole.canUpdateAllSettings}
|
||||
disabled={!isEditable}
|
||||
onChange={() => {
|
||||
setSettingsDraftRole({
|
||||
...settingsDraftRole,
|
||||
canUpdateAllSettings: !settingsDraftRole.canUpdateAllSettings,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</StyledCard>
|
||||
<AnimatedExpandableContainer
|
||||
isExpanded={!settingsDraftRole.canUpdateAllSettings}
|
||||
dimension="height"
|
||||
|
||||
@ -2,13 +2,11 @@ import { SettingsRolePermissionsSettingPermission } from '@/settings/roles/role-
|
||||
import { settingsDraftRoleFamilyState } from '@/settings/roles/states/settingsDraftRoleFamilyState';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { Checkbox } from 'twenty-ui/input';
|
||||
import { v4 } from 'uuid';
|
||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledTableRow = styled(TableRow)<{ isDisabled: boolean }>`
|
||||
cursor: ${({ isDisabled }) => (isDisabled ? 'default' : 'pointer')};
|
||||
@ -57,9 +55,6 @@ export const SettingsRolePermissionsSettingsTableRow = ({
|
||||
const [settingsDraftRole, setSettingsDraftRole] = useRecoilState(
|
||||
settingsDraftRoleFamilyState(roleId),
|
||||
);
|
||||
const isPermissionsV2Enabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
);
|
||||
const canUpdateAllSettings = settingsDraftRole.canUpdateAllSettings;
|
||||
|
||||
const isSettingPermissionEnabled =
|
||||
@ -68,8 +63,7 @@ export const SettingsRolePermissionsSettingsTableRow = ({
|
||||
) ?? false;
|
||||
|
||||
const isChecked = isSettingPermissionEnabled || canUpdateAllSettings;
|
||||
const isDisabled =
|
||||
!isEditable || canUpdateAllSettings || !isPermissionsV2Enabled;
|
||||
const isDisabled = !isEditable || canUpdateAllSettings;
|
||||
|
||||
const handleChange = (value: boolean) => {
|
||||
const currentPermissions = settingsDraftRole.settingPermissions ?? [];
|
||||
|
||||
@ -18,7 +18,6 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBa
|
||||
import { TabList } from '@/ui/layout/tab-list/components/TabList';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
@ -26,7 +25,6 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconLockOpen, IconSettings, IconUserPlus } from 'twenty-ui/display';
|
||||
import { v4 } from 'uuid';
|
||||
import {
|
||||
FeatureFlagKey,
|
||||
Role,
|
||||
useCreateOneRoleMutation,
|
||||
useUpdateOneRoleMutation,
|
||||
@ -60,10 +58,6 @@ export const SettingsRole = ({ roleId, isCreateMode }: SettingsRoleProps) => {
|
||||
SETTINGS_ROLE_DETAIL_TABS.COMPONENT_INSTANCE_ID + '-' + roleId,
|
||||
);
|
||||
|
||||
const isPermissionsV2Enabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
);
|
||||
|
||||
const navigateSettings = useNavigateSettings();
|
||||
|
||||
const [createRole] = useCreateOneRoleMutation();
|
||||
@ -91,7 +85,7 @@ export const SettingsRole = ({ roleId, isCreateMode }: SettingsRoleProps) => {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const isRoleEditable = isPermissionsV2Enabled && settingsDraftRole.isEditable;
|
||||
const isRoleEditable = settingsDraftRole.isEditable;
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
|
||||
@ -26,6 +26,7 @@ import { workspaceQueryRunnerGraphqlApiExceptionHandler } from 'src/engine/api/g
|
||||
import { WorkspaceQueryHookService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.service';
|
||||
import { RESOLVER_METHOD_NAMES } from 'src/engine/api/graphql/workspace-resolver-builder/constants/resolver-method-names';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
|
||||
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
||||
import {
|
||||
PermissionsException,
|
||||
@ -37,7 +38,6 @@ import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role
|
||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
|
||||
|
||||
export type GraphqlQueryResolverExecutionArgs<Input extends ResolverArgs> = {
|
||||
args: Input;
|
||||
@ -98,18 +98,8 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
|
||||
const featureFlagsMap = workspaceDataSource.featureFlagMap;
|
||||
|
||||
const isPermissionsV2Enabled =
|
||||
featureFlagsMap[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED];
|
||||
|
||||
if (objectMetadataItemWithFieldMaps.isSystem === true) {
|
||||
await this.validateSettingsPermissionsOnObjectOrThrow(options);
|
||||
} else {
|
||||
if (!isPermissionsV2Enabled)
|
||||
await this.validateObjectRecordPermissionsOrThrow({
|
||||
objectMetadataId: objectMetadataItemWithFieldMaps.id,
|
||||
operationName,
|
||||
options,
|
||||
});
|
||||
}
|
||||
|
||||
const hookedArgs =
|
||||
@ -228,39 +218,6 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
}
|
||||
}
|
||||
|
||||
private async validateObjectRecordPermissionsOrThrow({
|
||||
objectMetadataId,
|
||||
operationName,
|
||||
options,
|
||||
}: {
|
||||
objectMetadataId: string;
|
||||
operationName: WorkspaceResolverBuilderMethodNames;
|
||||
options: WorkspaceQueryRunnerOptions;
|
||||
}) {
|
||||
const requiredPermission =
|
||||
this.getRequiredPermissionForMethod(operationName);
|
||||
|
||||
const workspace = options.authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
const userHasPermission =
|
||||
await this.permissionsService.userHasObjectRecordsPermission({
|
||||
userWorkspaceId: options.authContext.userWorkspaceId,
|
||||
requiredPermission,
|
||||
workspaceId: workspace.id,
|
||||
isExecutedByApiKey: isDefined(options.authContext.apiKey),
|
||||
objectMetadataId,
|
||||
});
|
||||
|
||||
if (!userHasPermission) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.PERMISSION_DENIED,
|
||||
PermissionsExceptionCode.PERMISSION_DENIED,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private getRequiredPermissionForMethod(
|
||||
operationName: WorkspaceResolverBuilderMethodNames,
|
||||
) {
|
||||
|
||||
@ -4,6 +4,5 @@ export enum FeatureFlagKey {
|
||||
IS_STRIPE_INTEGRATION_ENABLED = 'IS_STRIPE_INTEGRATION_ENABLED',
|
||||
IS_UNIQUE_INDEXES_ENABLED = 'IS_UNIQUE_INDEXES_ENABLED',
|
||||
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
|
||||
IS_PERMISSIONS_V2_ENABLED = 'IS_PERMISSIONS_V2_ENABLED',
|
||||
IS_AI_ENABLED = 'IS_AI_ENABLED',
|
||||
}
|
||||
|
||||
@ -73,12 +73,6 @@ export class FeatureFlagService {
|
||||
},
|
||||
);
|
||||
|
||||
if (keys.includes(FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED)) {
|
||||
await this.workspacePermissionsCacheService.recomputeRolesPermissionsCache(
|
||||
{ workspaceId, ignoreLock: true },
|
||||
);
|
||||
}
|
||||
|
||||
await this.workspaceFeatureFlagsMapCacheService.recomputeFeatureFlagsMapCache(
|
||||
{
|
||||
workspaceId,
|
||||
@ -144,12 +138,6 @@ export class FeatureFlagService {
|
||||
},
|
||||
);
|
||||
|
||||
if (featureFlag === FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED) {
|
||||
await this.workspacePermissionsCacheService.recomputeRolesPermissionsCache(
|
||||
{ workspaceId, ignoreLock: true },
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
@ -12,7 +11,6 @@ import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/wor
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([RoleEntity, UserWorkspaceRoleEntity], 'core'),
|
||||
FeatureFlagModule,
|
||||
TypeOrmModule.forFeature([UserWorkspace], 'core'),
|
||||
UserRoleModule,
|
||||
WorkspacePermissionsCacheModule,
|
||||
|
||||
@ -7,8 +7,6 @@ import {
|
||||
AuthException,
|
||||
AuthExceptionCode,
|
||||
} from 'src/engine/core-modules/auth/auth.exception';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
||||
import {
|
||||
PermissionsException,
|
||||
@ -24,7 +22,6 @@ export class PermissionsService {
|
||||
constructor(
|
||||
private readonly userRoleService: UserRoleService,
|
||||
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {}
|
||||
|
||||
public async getUserWorkspacePermissions({
|
||||
@ -157,108 +154,10 @@ export class PermissionsService {
|
||||
return true;
|
||||
}
|
||||
|
||||
const isPermissionsV2Enabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
workspaceId,
|
||||
);
|
||||
const settingPermissions = roleOfUserWorkspace.settingPermissions ?? [];
|
||||
|
||||
if (isPermissionsV2Enabled) {
|
||||
const settingPermissions = roleOfUserWorkspace.settingPermissions ?? [];
|
||||
|
||||
return settingPermissions.some(
|
||||
(settingPermission) => settingPermission.setting === setting,
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async userHasObjectRecordsPermission({
|
||||
userWorkspaceId,
|
||||
workspaceId,
|
||||
requiredPermission,
|
||||
isExecutedByApiKey,
|
||||
objectMetadataId,
|
||||
}: {
|
||||
userWorkspaceId?: string;
|
||||
workspaceId: string;
|
||||
requiredPermission: PermissionsOnAllObjectRecords;
|
||||
isExecutedByApiKey: boolean;
|
||||
objectMetadataId: string;
|
||||
}): Promise<boolean> {
|
||||
const isPermissionsV2Enabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
if (isPermissionsV2Enabled) {
|
||||
throw new Error(
|
||||
'This should not be called once Permissions V2 is enabled',
|
||||
);
|
||||
}
|
||||
|
||||
if (isExecutedByApiKey) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isDefined(userWorkspaceId)) {
|
||||
throw new AuthException(
|
||||
'Missing userWorkspaceId or apiKey in authContext',
|
||||
AuthExceptionCode.USER_WORKSPACE_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const roleIdOfUserWorkspace =
|
||||
await this.userRoleService.getRoleIdForUserWorkspace({
|
||||
userWorkspaceId,
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
if (!isDefined(roleIdOfUserWorkspace)) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.NO_ROLE_FOUND_FOR_USER_WORKSPACE,
|
||||
PermissionsExceptionCode.NO_ROLE_FOUND_FOR_USER_WORKSPACE,
|
||||
);
|
||||
}
|
||||
|
||||
const { data: rolesPermissions } =
|
||||
await this.workspacePermissionsCacheService.getRolesPermissionsFromCache({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const rolePermissionsForUserWorkspaceRole =
|
||||
rolesPermissions[roleIdOfUserWorkspace];
|
||||
|
||||
const objectPermissionKey =
|
||||
this.getObjectPermissionKeyForRequiredPermission(requiredPermission);
|
||||
|
||||
const objectPermissionValue =
|
||||
rolePermissionsForUserWorkspaceRole[objectMetadataId]?.[
|
||||
objectPermissionKey
|
||||
];
|
||||
|
||||
return objectPermissionValue === true;
|
||||
}
|
||||
|
||||
private getObjectPermissionKeyForRequiredPermission(
|
||||
requiredPermission: PermissionsOnAllObjectRecords,
|
||||
) {
|
||||
switch (requiredPermission) {
|
||||
case PermissionsOnAllObjectRecords.READ_ALL_OBJECT_RECORDS:
|
||||
return 'canRead';
|
||||
case PermissionsOnAllObjectRecords.UPDATE_ALL_OBJECT_RECORDS:
|
||||
return 'canUpdate';
|
||||
case PermissionsOnAllObjectRecords.SOFT_DELETE_ALL_OBJECT_RECORDS:
|
||||
return 'canSoftDelete';
|
||||
case PermissionsOnAllObjectRecords.DESTROY_ALL_OBJECT_RECORDS:
|
||||
return 'canDestroy';
|
||||
default:
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.UNKNOWN_REQUIRED_PERMISSION,
|
||||
PermissionsExceptionCode.UNKNOWN_REQUIRED_PERMISSION,
|
||||
);
|
||||
}
|
||||
return settingPermissions.some(
|
||||
(settingPermission) => settingPermission.setting === setting,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { FileModule } from 'src/engine/core-modules/file/file.module';
|
||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module';
|
||||
@ -11,19 +10,17 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RoleResolver } from 'src/engine/metadata-modules/role/role.resolver';
|
||||
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
|
||||
import { UserWorkspaceRoleEntity } from 'src/engine/metadata-modules/role/user-workspace-role.entity';
|
||||
import { SettingPermissionModule } from 'src/engine/metadata-modules/setting-permission/setting-permission.module';
|
||||
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
|
||||
import { WorkspacePermissionsCacheModule } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([RoleEntity, UserWorkspaceRoleEntity], 'core'),
|
||||
TypeOrmModule.forFeature([RoleEntity], 'core'),
|
||||
TypeOrmModule.forFeature([UserWorkspace, Workspace], 'core'),
|
||||
UserRoleModule,
|
||||
PermissionsModule,
|
||||
UserWorkspaceModule,
|
||||
FeatureFlagModule,
|
||||
ObjectPermissionModule,
|
||||
SettingPermissionModule,
|
||||
WorkspacePermissionsCacheModule,
|
||||
|
||||
@ -8,9 +8,6 @@ import {
|
||||
Resolver,
|
||||
} from '@nestjs/graphql';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { FileService } from 'src/engine/core-modules/file/services/file.service';
|
||||
import { PreventNestToAutoLogGraphqlErrorsFilter } from 'src/engine/core-modules/graphql/filters/prevent-nest-to-auto-log-graphql-errors.filter';
|
||||
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
|
||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||
@ -56,10 +53,8 @@ export class RoleResolver {
|
||||
private readonly userRoleService: UserRoleService,
|
||||
private readonly roleService: RoleService,
|
||||
private readonly userWorkspaceService: UserWorkspaceService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
private readonly objectPermissionService: ObjectPermissionService,
|
||||
private readonly settingPermissionService: SettingPermissionService,
|
||||
private readonly fileService: FileService,
|
||||
) {}
|
||||
|
||||
@Query(() => [RoleDTO])
|
||||
@ -123,8 +118,6 @@ export class RoleResolver {
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args('createRoleInput') createRoleInput: CreateRoleInput,
|
||||
): Promise<RoleDTO> {
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
|
||||
return await this.roleService.createRole({
|
||||
workspaceId: workspace.id,
|
||||
input: createRoleInput,
|
||||
@ -136,8 +129,6 @@ export class RoleResolver {
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args('updateRoleInput') updateRoleInput: UpdateRoleInput,
|
||||
): Promise<RoleDTO> {
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
|
||||
const role = await this.roleService.updateRole({
|
||||
input: updateRoleInput,
|
||||
workspaceId: workspace.id,
|
||||
@ -151,8 +142,6 @@ export class RoleResolver {
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
@Args('roleId') roleId: string,
|
||||
): Promise<string> {
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
|
||||
const deletedRoleId = await this.roleService.deleteRole(
|
||||
roleId,
|
||||
workspace.id,
|
||||
@ -167,8 +156,6 @@ export class RoleResolver {
|
||||
@Args('upsertObjectPermissionsInput')
|
||||
upsertObjectPermissionsInput: UpsertObjectPermissionsInput,
|
||||
): Promise<ObjectPermissionDTO[]> {
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
|
||||
return this.objectPermissionService.upsertObjectPermissions({
|
||||
workspaceId: workspace.id,
|
||||
input: upsertObjectPermissionsInput,
|
||||
@ -181,8 +168,6 @@ export class RoleResolver {
|
||||
@Args('upsertSettingPermissionsInput')
|
||||
upsertSettingPermissionsInput: UpsertSettingPermissionsInput,
|
||||
): Promise<SettingPermissionDTO[]> {
|
||||
await this.validatePermissionsV2EnabledOrThrow(workspace);
|
||||
|
||||
return this.settingPermissionService.upsertSettingPermissions({
|
||||
workspaceId: workspace.id,
|
||||
input: upsertSettingPermissionsInput,
|
||||
@ -202,19 +187,4 @@ export class RoleResolver {
|
||||
|
||||
return workspaceMembers;
|
||||
}
|
||||
|
||||
private async validatePermissionsV2EnabledOrThrow(workspace: Workspace) {
|
||||
const isPermissionsV2Enabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
workspace.id,
|
||||
);
|
||||
|
||||
if (!isPermissionsV2Enabled) {
|
||||
throw new PermissionsException(
|
||||
PermissionsExceptionMessage.PERMISSIONS_V2_NOT_ENABLED,
|
||||
PermissionsExceptionCode.PERMISSIONS_V2_NOT_ENABLED,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ import {
|
||||
UpdateRolePayload,
|
||||
} from 'src/engine/metadata-modules/role/dtos/update-role-input.dto';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { UserWorkspaceRoleEntity } from 'src/engine/metadata-modules/role/user-workspace-role.entity';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { isArgDefinedIfProvidedOrThrow } from 'src/engine/metadata-modules/utils/is-arg-defined-if-provided-or-throw.util';
|
||||
import { WorkspacePermissionsCacheService } from 'src/engine/metadata-modules/workspace-permissions-cache/workspace-permissions-cache.service';
|
||||
@ -28,8 +27,6 @@ export class RoleService {
|
||||
private readonly workspaceRepository: Repository<Workspace>,
|
||||
@InjectRepository(RoleEntity, 'core')
|
||||
private readonly roleRepository: Repository<RoleEntity>,
|
||||
@InjectRepository(UserWorkspaceRoleEntity, 'core')
|
||||
private readonly userWorkspaceRoleRepository: Repository<UserWorkspaceRoleEntity>,
|
||||
private readonly userRoleService: UserRoleService,
|
||||
private readonly workspacePermissionsCacheService: WorkspacePermissionsCacheService,
|
||||
) {}
|
||||
|
||||
@ -8,7 +8,6 @@ import {
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { In, Repository } from 'typeorm';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
@ -85,18 +84,9 @@ export class WorkspacePermissionsCacheService {
|
||||
);
|
||||
}
|
||||
|
||||
const workspaceFeatureFlagsMap =
|
||||
await this.workspaceFeatureFlagsMapCacheService.getWorkspaceFeatureFlagsMap(
|
||||
{ workspaceId },
|
||||
);
|
||||
|
||||
const isPermissionsV2Enabled =
|
||||
!!workspaceFeatureFlagsMap[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED];
|
||||
|
||||
const recomputedRolesPermissions =
|
||||
await this.getObjectRecordPermissionsForRoles({
|
||||
workspaceId,
|
||||
isPermissionsV2Enabled,
|
||||
roleIds,
|
||||
});
|
||||
|
||||
@ -232,11 +222,9 @@ export class WorkspacePermissionsCacheService {
|
||||
|
||||
private async getObjectRecordPermissionsForRoles({
|
||||
workspaceId,
|
||||
isPermissionsV2Enabled,
|
||||
roleIds,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
isPermissionsV2Enabled: boolean;
|
||||
roleIds?: string[];
|
||||
}): Promise<ObjectRecordsPermissionsByRoleId> {
|
||||
let roles: RoleEntity[] = [];
|
||||
@ -265,49 +253,47 @@ export class WorkspacePermissionsCacheService {
|
||||
let canSoftDelete = role.canSoftDeleteAllObjectRecords;
|
||||
let canDestroy = role.canDestroyAllObjectRecords;
|
||||
|
||||
if (isPermissionsV2Enabled) {
|
||||
if (
|
||||
standardId &&
|
||||
[
|
||||
STANDARD_OBJECT_IDS.workflow,
|
||||
STANDARD_OBJECT_IDS.workflowRun,
|
||||
STANDARD_OBJECT_IDS.workflowVersion,
|
||||
].includes(standardId)
|
||||
) {
|
||||
const hasWorkflowsPermissions = this.hasWorkflowsPermissions(role);
|
||||
if (
|
||||
standardId &&
|
||||
[
|
||||
STANDARD_OBJECT_IDS.workflow,
|
||||
STANDARD_OBJECT_IDS.workflowRun,
|
||||
STANDARD_OBJECT_IDS.workflowVersion,
|
||||
].includes(standardId)
|
||||
) {
|
||||
const hasWorkflowsPermissions = this.hasWorkflowsPermissions(role);
|
||||
|
||||
canRead = hasWorkflowsPermissions;
|
||||
canUpdate = hasWorkflowsPermissions;
|
||||
canSoftDelete = hasWorkflowsPermissions;
|
||||
canDestroy = hasWorkflowsPermissions;
|
||||
} else {
|
||||
const objectRecordPermissionsOverride = role.objectPermissions.find(
|
||||
(objectPermission) =>
|
||||
objectPermission.objectMetadataId === objectMetadataId,
|
||||
);
|
||||
canRead = hasWorkflowsPermissions;
|
||||
canUpdate = hasWorkflowsPermissions;
|
||||
canSoftDelete = hasWorkflowsPermissions;
|
||||
canDestroy = hasWorkflowsPermissions;
|
||||
} else {
|
||||
const objectRecordPermissionsOverride = role.objectPermissions.find(
|
||||
(objectPermission) =>
|
||||
objectPermission.objectMetadataId === objectMetadataId,
|
||||
);
|
||||
|
||||
const getPermissionValue = (
|
||||
overrideValue: boolean | undefined,
|
||||
defaultValue: boolean,
|
||||
) => (isSystem ? true : (overrideValue ?? defaultValue));
|
||||
const getPermissionValue = (
|
||||
overrideValue: boolean | undefined,
|
||||
defaultValue: boolean,
|
||||
) => (isSystem ? true : (overrideValue ?? defaultValue));
|
||||
|
||||
canRead = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canReadObjectRecords,
|
||||
canRead,
|
||||
);
|
||||
canUpdate = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canUpdateObjectRecords,
|
||||
canUpdate,
|
||||
);
|
||||
canSoftDelete = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canSoftDeleteObjectRecords,
|
||||
canSoftDelete,
|
||||
);
|
||||
canDestroy = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canDestroyObjectRecords,
|
||||
canDestroy,
|
||||
);
|
||||
}
|
||||
canRead = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canReadObjectRecords,
|
||||
canRead,
|
||||
);
|
||||
canUpdate = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canUpdateObjectRecords,
|
||||
canUpdate,
|
||||
);
|
||||
canSoftDelete = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canSoftDeleteObjectRecords,
|
||||
canSoftDelete,
|
||||
);
|
||||
canDestroy = getPermissionValue(
|
||||
objectRecordPermissionsOverride?.canDestroyObjectRecords,
|
||||
canDestroy,
|
||||
);
|
||||
}
|
||||
|
||||
objectRecordsPermissions[objectMetadataId] = {
|
||||
|
||||
@ -15,7 +15,6 @@ import { EntityManagerFactory } from 'typeorm/entity-manager/EntityManagerFactor
|
||||
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
|
||||
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
@ -168,28 +167,22 @@ export class WorkspaceDataSource extends DataSource {
|
||||
): SelectQueryBuilder<any> {
|
||||
let calledByWorkspaceEntityManager;
|
||||
|
||||
const isPermissionsV2Enabled =
|
||||
this.featureFlagMap[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED];
|
||||
|
||||
const isCalledWithEntityTarget =
|
||||
isDefined(aliasOrOptions) && typeof aliasOrOptions === 'string';
|
||||
|
||||
if (isPermissionsV2Enabled) {
|
||||
if (isCalledWithEntityTarget) {
|
||||
calledByWorkspaceEntityManager =
|
||||
options?.calledByWorkspaceEntityManager;
|
||||
} else {
|
||||
calledByWorkspaceEntityManager = (
|
||||
aliasOrOptions as CreateQueryBuilderOptions
|
||||
)?.calledByWorkspaceEntityManager;
|
||||
}
|
||||
if (isCalledWithEntityTarget) {
|
||||
calledByWorkspaceEntityManager = options?.calledByWorkspaceEntityManager;
|
||||
} else {
|
||||
calledByWorkspaceEntityManager = (
|
||||
aliasOrOptions as CreateQueryBuilderOptions
|
||||
)?.calledByWorkspaceEntityManager;
|
||||
}
|
||||
|
||||
if (!(calledByWorkspaceEntityManager === true)) {
|
||||
throw new PermissionsException(
|
||||
'Method not allowed because permissions are not implemented at datasource level.',
|
||||
PermissionsExceptionCode.METHOD_NOT_ALLOWED,
|
||||
);
|
||||
}
|
||||
if (!(calledByWorkspaceEntityManager === true)) {
|
||||
throw new PermissionsException(
|
||||
'Method not allowed because permissions are not implemented at datasource level.',
|
||||
PermissionsExceptionCode.METHOD_NOT_ALLOWED,
|
||||
);
|
||||
}
|
||||
|
||||
if (isCalledWithEntityTarget) {
|
||||
|
||||
@ -5,7 +5,6 @@ import { PlainObjectToDatabaseEntityTransformer } from 'typeorm/query-builder/tr
|
||||
|
||||
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
||||
import { validateOperationIsPermittedOrThrow } from 'src/engine/twenty-orm/repository/permissions.utils';
|
||||
|
||||
@ -58,15 +57,10 @@ describe('WorkspaceEntityManager', () => {
|
||||
objectMetadataMaps: {
|
||||
idByNameSingular: {},
|
||||
},
|
||||
featureFlagsMap: {
|
||||
[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED]: true,
|
||||
},
|
||||
} as WorkspaceInternalContext;
|
||||
|
||||
mockDataSource = {
|
||||
featureFlagMap: {
|
||||
[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED]: true,
|
||||
},
|
||||
featureFlagMap: {},
|
||||
permissionsPerRoleId: {},
|
||||
} as WorkspaceDataSource;
|
||||
|
||||
@ -141,11 +135,6 @@ describe('WorkspaceEntityManager', () => {
|
||||
return entityName;
|
||||
});
|
||||
|
||||
// Mock getFeatureFlagMap
|
||||
jest.spyOn(entityManager as any, 'getFeatureFlagMap').mockReturnValue({
|
||||
[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED]: true,
|
||||
});
|
||||
|
||||
// Mock typeORM's EntityManager methods
|
||||
jest
|
||||
.spyOn(EntityManager.prototype, 'save')
|
||||
|
||||
@ -32,7 +32,6 @@ import { InstanceChecker } from 'typeorm/util/InstanceChecker';
|
||||
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
|
||||
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
@ -94,25 +93,18 @@ export class WorkspaceEntityManager extends EntityManager {
|
||||
|
||||
let objectPermissions = {};
|
||||
|
||||
const featureFlagMap = this.getFeatureFlagMap();
|
||||
|
||||
const isPermissionsV2Enabled =
|
||||
featureFlagMap[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED];
|
||||
|
||||
if (permissionOptions?.roleId) {
|
||||
const objectPermissionsByRoleId = dataSource.permissionsPerRoleId;
|
||||
|
||||
if (!isDefined(objectPermissionsByRoleId?.[permissionOptions.roleId])) {
|
||||
if (isPermissionsV2Enabled) {
|
||||
throw new PermissionsException(
|
||||
`No permissions found for role in datasource (missing ${
|
||||
!isDefined(objectPermissionsByRoleId)
|
||||
? 'objectPermissionsByRoleId object'
|
||||
: `roleId in objectPermissionsByRoleId object (${permissionOptions.roleId})`
|
||||
})`,
|
||||
PermissionsExceptionCode.NO_PERMISSIONS_FOUND_IN_DATASOURCE,
|
||||
);
|
||||
}
|
||||
throw new PermissionsException(
|
||||
`No permissions found for role in datasource (missing ${
|
||||
!isDefined(objectPermissionsByRoleId)
|
||||
? 'objectPermissionsByRoleId object'
|
||||
: `roleId in objectPermissionsByRoleId object (${permissionOptions.roleId})`
|
||||
})`,
|
||||
PermissionsExceptionCode.NO_PERMISSIONS_FOUND_IN_DATASOURCE,
|
||||
);
|
||||
} else {
|
||||
objectPermissions = objectPermissionsByRoleId[permissionOptions.roleId];
|
||||
}
|
||||
@ -165,21 +157,12 @@ export class WorkspaceEntityManager extends EntityManager {
|
||||
);
|
||||
}
|
||||
|
||||
const featureFlagMap = this.getFeatureFlagMap();
|
||||
|
||||
const isPermissionsV2Enabled =
|
||||
featureFlagMap[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED];
|
||||
|
||||
if (!isPermissionsV2Enabled) {
|
||||
return queryBuilder;
|
||||
} else {
|
||||
return new WorkspaceSelectQueryBuilder(
|
||||
queryBuilder,
|
||||
options?.objectRecordsPermissions ?? {},
|
||||
this.internalContext,
|
||||
options?.shouldBypassPermissionChecks ?? false,
|
||||
);
|
||||
}
|
||||
return new WorkspaceSelectQueryBuilder(
|
||||
queryBuilder,
|
||||
options?.objectRecordsPermissions ?? {},
|
||||
this.internalContext,
|
||||
options?.shouldBypassPermissionChecks ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
override insert<Entity extends ObjectLiteral>(
|
||||
@ -391,15 +374,6 @@ export class WorkspaceEntityManager extends EntityManager {
|
||||
objectRecordsPermissions?: ObjectRecordsPermissions;
|
||||
},
|
||||
): void {
|
||||
const featureFlagMap = this.getFeatureFlagMap();
|
||||
|
||||
const isPermissionsV2Enabled =
|
||||
featureFlagMap[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED];
|
||||
|
||||
if (!isPermissionsV2Enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (permissionOptions?.shouldBypassPermissionChecks === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -23,7 +23,6 @@ import { UpsertOptions } from 'typeorm/repository/UpsertOptions';
|
||||
import { FeatureFlagMap } from 'src/engine/core-modules/feature-flag/interfaces/feature-flag-map.interface';
|
||||
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import {
|
||||
PermissionsException,
|
||||
PermissionsExceptionCode,
|
||||
@ -70,23 +69,17 @@ export class WorkspaceRepository<
|
||||
alias,
|
||||
queryRunner,
|
||||
) as unknown as WorkspaceSelectQueryBuilder<U>;
|
||||
const isPermissionsV2Enabled =
|
||||
this.featureFlagMap[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED];
|
||||
|
||||
if (!isPermissionsV2Enabled) {
|
||||
return queryBuilder;
|
||||
} else {
|
||||
if (!this.objectRecordsPermissions) {
|
||||
throw new Error('Object records permissions are required');
|
||||
}
|
||||
|
||||
return new WorkspaceSelectQueryBuilder(
|
||||
queryBuilder,
|
||||
this.objectRecordsPermissions,
|
||||
this.internalContext,
|
||||
this.shouldBypassPermissionChecks,
|
||||
);
|
||||
if (!this.objectRecordsPermissions) {
|
||||
throw new Error('Object records permissions are required');
|
||||
}
|
||||
|
||||
return new WorkspaceSelectQueryBuilder(
|
||||
queryBuilder,
|
||||
this.objectRecordsPermissions,
|
||||
this.internalContext,
|
||||
this.shouldBypassPermissionChecks,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -40,11 +40,6 @@ export const seedFeatureFlags = async (
|
||||
workspaceId: workspaceId,
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
key: FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED,
|
||||
workspaceId: workspaceId,
|
||||
value: true,
|
||||
},
|
||||
])
|
||||
.execute();
|
||||
};
|
||||
|
||||
@ -3,7 +3,6 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@ -194,10 +193,5 @@ export class WorkspaceManagerService {
|
||||
await this.workspaceRepository.update(workspaceId, {
|
||||
defaultRoleId: memberRole.id,
|
||||
});
|
||||
|
||||
await this.featureFlagService.enableFeatureFlags(
|
||||
[FeatureFlagKey.IS_PERMISSIONS_V2_ENABLED],
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user