diff --git a/apps/backend/prisma/migrations/20250325185749_rename_user_to_project_in_permission/migration.sql b/apps/backend/prisma/migrations/20250325185749_rename_user_to_project_in_permission/migration.sql new file mode 100644 index 000000000..45fc3cd3c --- /dev/null +++ b/apps/backend/prisma/migrations/20250325185749_rename_user_to_project_in_permission/migration.sql @@ -0,0 +1,19 @@ +/* + Warnings: + + - The values [USER] on the enum `PermissionScope` will be removed. If these variants are still used in the database, this will fail. + - You are about to drop the column `isDefaultUserPermission` on the `Permission` table. All the data in the column will be lost. + +*/ +-- AlterEnum +BEGIN; +CREATE TYPE "PermissionScope_new" AS ENUM ('PROJECT', 'TEAM'); +ALTER TABLE "Permission" ALTER COLUMN "scope" TYPE "PermissionScope_new" USING ("scope"::text::"PermissionScope_new"); +ALTER TYPE "PermissionScope" RENAME TO "PermissionScope_old"; +ALTER TYPE "PermissionScope_new" RENAME TO "PermissionScope"; +DROP TYPE "PermissionScope_old"; +COMMIT; + +-- AlterTable +ALTER TABLE "Permission" DROP COLUMN "isDefaultUserPermission", +ADD COLUMN "isDefaultProjectPermission" BOOLEAN NOT NULL DEFAULT false; diff --git a/apps/backend/prisma/schema.prisma b/apps/backend/prisma/schema.prisma index 8b51e1947..7b39afb02 100644 --- a/apps/backend/prisma/schema.prisma +++ b/apps/backend/prisma/schema.prisma @@ -224,14 +224,14 @@ model Permission { isDefaultTeamCreatorPermission Boolean @default(false) isDefaultTeamMemberPermission Boolean @default(false) - isDefaultUserPermission Boolean @default(false) + isDefaultProjectPermission Boolean @default(false) @@unique([projectConfigId, queryableId]) @@unique([tenancyId, teamId, queryableId]) } enum PermissionScope { - USER + PROJECT TEAM } diff --git a/apps/backend/src/app/api/latest/projects/current/crud.tsx b/apps/backend/src/app/api/latest/projects/current/crud.tsx index c8fa99ebb..eb80405fd 100644 --- a/apps/backend/src/app/api/latest/projects/current/crud.tsx +++ b/apps/backend/src/app/api/latest/projects/current/crud.tsx @@ -34,27 +34,27 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro ] as const; const teamPermissions = await listPermissionDefinitions(tx, "TEAM", auth.tenancy); - const userPermissions = await listPermissionDefinitions(tx, "USER", auth.tenancy); + const projectPermissions = await listPermissionDefinitions(tx, "PROJECT", auth.tenancy); // Handle user default permissions const userDefaultPerms = data.config?.user_default_permissions?.map((p) => p.id); if (userDefaultPerms) { - if (!userDefaultPerms.every((id) => userPermissions.some((perm) => perm.id === id))) { + if (!userDefaultPerms.every((id) => projectPermissions.some((perm) => perm.id === id))) { throw new StatusError(StatusError.BadRequest, - `Invalid user default permission ids: ${userDefaultPerms.filter(id => !userPermissions.some(perm => perm.id === id)).join(', ')}`); + `Invalid user default permission ids: ${userDefaultPerms.filter(id => !projectPermissions.some(perm => perm.id === id)).join(', ')}`); } - // Remove existing default user permissions + // Remove existing default project permissions await tx.permission.updateMany({ where: { projectConfigId: oldProject.config.id, }, data: { - isDefaultUserPermission: false, + isDefaultProjectPermission: false, }, }); - // Add new default user permissions + // Add new default project permissions await tx.permission.updateMany({ where: { projectConfigId: oldProject.config.id, @@ -63,7 +63,7 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro }, }, data: { - isDefaultUserPermission: true, + isDefaultProjectPermission: true, }, }); } diff --git a/apps/backend/src/app/api/latest/user-permission-definitions/crud.tsx b/apps/backend/src/app/api/latest/user-permission-definitions/crud.tsx index e545270cc..1fb625be2 100644 --- a/apps/backend/src/app/api/latest/user-permission-definitions/crud.tsx +++ b/apps/backend/src/app/api/latest/user-permission-definitions/crud.tsx @@ -12,7 +12,7 @@ export const userPermissionDefinitionsCrudHandlers = createLazyProxy(() => creat async onCreate({ auth, data }) { return await retryTransaction(async (tx) => { return await createPermissionDefinition(tx, { - scope: "USER", + scope: "PROJECT", tenancy: auth.tenancy, data, }); @@ -21,7 +21,7 @@ export const userPermissionDefinitionsCrudHandlers = createLazyProxy(() => creat async onUpdate({ auth, data, params }) { return await retryTransaction(async (tx) => { return await updatePermissionDefinitions(tx, { - scope: "USER", + scope: "PROJECT", tenancy: auth.tenancy, permissionId: params.permission_id, data, @@ -39,7 +39,7 @@ export const userPermissionDefinitionsCrudHandlers = createLazyProxy(() => creat async onList({ auth }) { return await retryTransaction(async (tx) => { return { - items: await listPermissionDefinitions(tx, "USER", auth.tenancy), + items: await listPermissionDefinitions(tx, "PROJECT", auth.tenancy), is_paginated: false, }; }); diff --git a/apps/backend/src/lib/permissions.tsx b/apps/backend/src/lib/permissions.tsx index b9601f2b9..9ccea130f 100644 --- a/apps/backend/src/lib/permissions.tsx +++ b/apps/backend/src/lib/permissions.tsx @@ -42,7 +42,7 @@ type ExtendedTeamPermissionDefinition = TeamPermissionDefinitionsCrud["Admin"][" __database_id: string, __is_default_team_member_permission?: boolean, __is_default_team_creator_permission?: boolean, - __is_default_user_permission?: boolean, + __is_default_project_permission?: boolean, }; export function teamPermissionDefinitionJsonFromDbType(db: Prisma.PermissionGetPayload<{ include: typeof fullPermissionInclude }>): ExtendedTeamPermissionDefinition { @@ -54,13 +54,13 @@ export function teamPermissionDefinitionJsonFromDbType(db: Prisma.PermissionGetP export function teamPermissionDefinitionJsonFromRawDbType(db: any | Prisma.PermissionGetPayload<{ include: typeof fullPermissionInclude }>): ExtendedTeamPermissionDefinition { if (!db.projectConfigId && !db.teamId) throw new StackAssertionError(`Permission DB object should have either projectConfigId or teamId`, { db }); if (db.projectConfigId && db.teamId) throw new StackAssertionError(`Permission DB object should have either projectConfigId or teamId, not both`, { db }); - if (db.scope === "USER" && db.teamId) throw new StackAssertionError(`Permission DB object should not have teamId when scope is USER`, { db }); + if (db.scope === "PROJECT" && db.teamId) throw new StackAssertionError(`Permission DB object should not have teamId when scope is PROJECT`, { db }); return { __database_id: db.dbId, __is_default_team_member_permission: db.isDefaultTeamMemberPermission, __is_default_team_creator_permission: db.isDefaultTeamCreatorPermission, - __is_default_user_permission: db.isDefaultUserPermission, + __is_default_project_permission: db.isDefaultProjectPermission, id: db.queryableId, description: db.description || undefined, contained_permission_ids: db.parentEdges?.map((edge: any) => { @@ -78,7 +78,7 @@ export function teamPermissionDefinitionJsonFromRawDbType(db: any | Prisma.Permi export function teamPermissionDefinitionJsonFromTeamSystemDbType(db: DBTeamSystemPermission, projectConfig: { teamCreateDefaultSystemPermissions: string[] | null, teamMemberDefaultSystemPermissions: string[] | null, - userDefaultPermissions?: string[] | null, + projectDefaultPermissions?: string[] | null, }): ExtendedTeamPermissionDefinition { if ((["teamMemberDefaultSystemPermissions", "teamCreateDefaultSystemPermissions"] as const).some(key => projectConfig[key] !== null && !Array.isArray(projectConfig[key]))) { throw new StackAssertionError(`Project config should have (nullable) array values for teamMemberDefaultSystemPermissions and teamCreateDefaultSystemPermissions`, { projectConfig }); @@ -88,7 +88,7 @@ export function teamPermissionDefinitionJsonFromTeamSystemDbType(db: DBTeamSyste __database_id: '$' + typedToLowercase(db), __is_default_team_member_permission: projectConfig.teamMemberDefaultSystemPermissions?.includes(db) ?? false, __is_default_team_creator_permission: projectConfig.teamCreateDefaultSystemPermissions?.includes(db) ?? false, - __is_default_user_permission: projectConfig.userDefaultPermissions?.includes(db) ?? false, + __is_default_project_permission: projectConfig.projectDefaultPermissions?.includes(db) ?? false, id: '$' + typedToLowercase(db), description: descriptionMap[db], contained_permission_ids: [] as string[], @@ -99,7 +99,7 @@ async function getParentDbIds( tx: PrismaTransaction, options: { tenancy: Tenancy, - scope: "TEAM" | "USER", + scope: "TEAM" | "PROJECT", containedPermissionIds?: string[], } ) { @@ -324,7 +324,7 @@ export async function revokeTeamPermission( export async function listPermissionDefinitions( tx: PrismaTransaction, - scope: "TEAM" | "USER", + scope: "TEAM" | "PROJECT", tenancy: Tenancy ): Promise<(TeamPermissionDefinitionsCrud["Admin"]["Read"] & { __database_id: string })[]> { const projectConfig = await tx.projectConfig.findUnique({ @@ -356,7 +356,7 @@ export async function listPermissionDefinitions( export async function createPermissionDefinition( tx: PrismaTransaction, options: { - scope: "TEAM" | "USER", + scope: "TEAM" | "PROJECT", tenancy: Tenancy, data: { id: string, @@ -402,7 +402,7 @@ export async function createPermissionDefinition( export async function updatePermissionDefinitions( tx: PrismaTransaction, options: { - scope: "TEAM" | "USER", + scope: "TEAM" | "PROJECT", tenancy: Tenancy, permissionId: string, data: { @@ -486,7 +486,7 @@ export async function listUserPermissions( recursive: boolean, } ): Promise { - const permissionDefs = await listPermissionDefinitions(tx, "USER", options.tenancy); + const permissionDefs = await listPermissionDefinitions(tx, "PROJECT", options.tenancy); const permissionsMap = new Map(permissionDefs.map(p => [p.id, p])); const results = await tx.projectUserDirectPermission.findMany({ where: { @@ -610,7 +610,7 @@ export async function revokeUserPermission( } /** - * Grants default user permissions to a user + * Grants default project permissions to a user * This function should be called when a new user is created */ export async function grantDefaultUserPermissions( @@ -623,7 +623,7 @@ export async function grantDefaultUserPermissions( const defaultPermissions = await tx.permission.findMany({ where: { projectConfigId: options.tenancy.config.id, - isDefaultUserPermission: true, + isDefaultProjectPermission: true, } }); diff --git a/apps/backend/src/lib/projects.tsx b/apps/backend/src/lib/projects.tsx index d42e96149..db8abd3ff 100644 --- a/apps/backend/src/lib/projects.tsx +++ b/apps/backend/src/lib/projects.tsx @@ -173,7 +173,7 @@ export function projectPrismaToCrud( .concat(prisma.config.teamMemberDefaultSystemPermissions.map(db => teamPermissionDefinitionJsonFromTeamSystemDbType(db, prisma.config))) .sort((a, b) => stringCompare(a.id, b.id)) .map(perm => ({ id: perm.id })), - user_default_permissions: prisma.config.permissions.filter(perm => perm.isDefaultUserPermission) + user_default_permissions: prisma.config.permissions.filter(perm => perm.isDefaultProjectPermission) .map(teamPermissionDefinitionJsonFromDbType) .sort((a, b) => stringCompare(a.id, b.id)) .map(perm => ({ id: perm.id })), @@ -464,7 +464,7 @@ export function getProjectQuery(projectId: string): RawQuery perm.__is_default_team_member_permission) .map(perm => ({ id: perm.id })), user_default_permissions: teamPermissions - .filter(perm => perm.__is_default_user_permission) + .filter(perm => perm.__is_default_project_permission) .map(perm => ({ id: perm.id })), }, };